Maxwin-z/XListView-Android (pull and refresh) source code parsing (2)

Source: Internet
Author: User

Maxwin-z/XListView-Android (pull and refresh) source code parsing (2)

 

This article mainly posts the xlistview source code and a use instance, without too much explanation

Use instance, MainActivity

 

public class MainActivity extends Activity {private LinkedList
 
     listItems = null;    private XListView     listView  = null;    private ArrayAdapter
  
    adapter;     private String[]             mStrings  = { Aaaaaa, Bbbbbb, Cccccc, Dddddd, Eeeeee,            Ffffff, Gggggg, Hhhhhh, Iiiiii, Jjjjjj, Kkkkkk, Llllll, Mmmmmm,            Nnnnnn,                     };     @Override    public void onCreate(Bundle savedInstanceState) {    super.onCreate(savedInstanceState);    setContentView(R.layout.activity_main);                      listView = (XListView)findViewById(R.id.mlist);        listView.setXListViewListener(new IXListViewListener() {@Overridepublic void onRefresh() {new GetDataTask(true).execute();}@Overridepublic void onLoadMore() {new GetDataTask(false).execute();}});               listItems = new LinkedList
   
    ();        listItems.addAll(Arrays.asList(mStrings));        adapter = new ArrayAdapter
    
     (this, android.R.layout.simple_list_item_1, listItems);        listView.setAdapter(adapter);        listView.setPullLoadEnable(true);    }     private class GetDataTask extends AsyncTask
     
       {         private boolean isDropDown;         public GetDataTask(boolean isDropDown){            this.isDropDown = isDropDown;        }         @Override        protected String[] doInBackground(Void... params) {            try {                Thread.sleep(1000);            } catch (InterruptedException e) {                ;            }            return mStrings;        }         @Override        protected void onPostExecute(String[] result) {             if (isDropDown) {                listItems.addFirst(Added after drop down);                adapter.notifyDataSetChanged();                                                    listView.stopRefresh();            } else {                listItems.add(Added after on bottom);                adapter.notifyDataSetChanged();                listView.stopLoadMore();                          }             super.onPostExecute(result);        }    }}
     
    
   
  
 

XListView

 

 

Public class XListView extends ListView implements OnScrollListener {private float mLastY =-1; // save event y/*** is used for the drop-down, slide and return */private Scroller; // used for scroll backprivate OnScrollListener mScrollListener; // user's scroll listener // the interface to trigger refresh and load more. private IXListViewListener mListViewListener;/*** drop-down header */private XListViewHeader mHeaderView;/*** drop-down Header Body, used to calculate the height of the header * hidden */private RelativeLayout mHeaderViewContent when refreshing is not allowed;/*** drop-down arrow */private TextView mHeaderTimeView; /*** height of the drop-down header */private int mHeaderViewHeight;/*** whether to pull down and refresh */private boolean mEnablePullRefresh = true;/*** whether to refresh, false indicates refreshing */private boolean mPullRefreshing = false; // is refreashing. // -- footer viewprivate XListViewFooter mFooterView; private boolean mEnablePullLoad; private bo Olean mPullLoading; private boolean mIsFooterReady = false; // total list items, used to detect is at the bottom of listview. private int mTotalItemCount; // for mScroller, scroll back from header or footer. private int mScrollBack;/*** returns the head slide */private final static int SCROLLBACK_HEADER = 0;/*** returns the footer slide */private final static int SCROLLBACK_FOOTER = 1; private final static int SCROLL_DURATION = 40 0; // scroll back durationprivate final static int PULL_LOAD_MORE_DELTA = 50; // when pull up> = 50px // at bottom, trigger // load more. private final static float OFFSET_RADIO = 1.8f; // support iOS like pull // feature. /*** @ param context */public XListView (Context context) {super (context); initWithContext (context);} public XListView (Context context, AttributeSet attrs) {super (context, attrs); initWi ThContext (context);} public XListView (Context context, AttributeSet attrs, int defStyle) {super (context, attrs, defStyle); initWithContext (context );} private void initWithContext (Context context) {mScroller = new Scroller (context, new DecelerateInterpolator (); // XListView need the scroll event, and it will dispatch the event to // user's listener (as a proxy ). super. setOnScrollListener (this); // initialize the drop-down header m HeaderView = new XListViewHeader (context); mHeaderViewContent = (RelativeLayout) mHeaderView. findViewById (R. id. xlistview_header_content); mHeaderTimeView = (TextView) mHeaderView. findViewById (R. id. xlistview_header_time); addHeaderView (mHeaderView); // initialize the mFooterView at the bottom = new XListViewFooter (context); // initialize the mHeaderView at the bottom. getViewTreeObserver (). addOnGlobalLayoutListener (new OnGlobalLayoutListener () {@ Over Ridepublic void onGlobalLayout () {mHeaderViewHeight = mHeaderViewContent. getHeight (); // get the height of the drop-down header getViewTreeObserver (). removeGlobalOnLayoutListener (this) ;}}) ;}@ Overridepublic void setAdapter (ListAdapter adapter) {/** add more footer to the bottom of the listview by pulling it up and adding it only once */if (mIsFooterReady = false) {mIsFooterReady = true; addFooterView (mFooterView ); // listview native method} super. setAdapter (adapter);}/*** set whether the pull-down refresh function is enabled *@ Param enable */public void setPullRefreshEnable (boolean enable) {mEnablePullRefresh = enable; if (! MEnablePullRefresh) {// disable this function to hide the header mHeaderViewContent. setVisibility (View. INVISIBLE);} else {mHeaderViewContent. setVisibility (View. VISIBLE);}/*** set whether to enable the pull-on function. * If You Want To enable the function, you must actively call this function * @ param enable */public void setPullLoadEnable (boolean enable) {mEnablePullLoad = enable; if (! MEnablePullLoad) {// If mFooterView is not enabled. hide (); // hide footermFooterView. setOnClickListener (null ); // cancel listening // make sure pull up don't show a line in bottom when listview with one page // ensure that the split line between items in listview disappears (the last one) setFooterDividersEnabled (false); // listview native method} else {mPullLoading = false; mFooterView. show (); mFooterView. setState (XListViewFooter. STATE_NORMAL); // make sure pull up don't show a line in bottom when Listview with one page setFooterDividersEnabled (true); // both pull up and click will invoke load more. mFooterView. setOnClickListener (new OnClickListener () {@ Overridepublic void onClick (View v) {startLoadMore () ;}}}/ *** stop refresh, reset header view. * stop refreshing, reset the header */public void stopRefresh () {if (mPullRefreshing = true) {mPullRefreshing = false; resetHeaderHeight () ;}/ *** stop load more, reset Footer view. * Stop loading more. Reset footer */public void stopLoadMore () {if (mPullLoading = true) {mPullLoading = false; mFooterView. setState (XListViewFooter. STATE_NORMAL) ;}}/*** set last refresh time * sets the last refresh time * @ param time */public void setRefreshTime (String time) {mHeaderTimeView. setText (time);} private void invokeOnScrolling () {if (mScrollListener instanceof OnXScrollListener) {OnXScrollListener l = (OnXScrollListener) mScrollListener; l. onXScrolling (this) ;}/ *** update the header height * this function is used to record the number of dropped entries * @ param delta */private void updateHeaderHeight (float delta) {mHeaderView. setVisiableHeight (int) delta + mHeaderView. getVisiableHeight (); if (mEnablePullRefresh &&! MPullRefreshing) {// not refreshed, update the arrow if (mHeaderView. getVisiableHeight ()> mHeaderViewHeight) {mHeaderView. setState (XListViewHeader. STATE_READY);} else {mHeaderView. setState (XListViewHeader. STATE_NORMAL) ;}/// slip to the header setSelection (0); // scroll to top each time}/*** reset header view's height. * reset the header height */private void resetHeaderHeight () {int height = mHeaderView. getVisiableHeight (); if (height = 0) // not v Isible. return; // refreshing and header isn' t shown fully. do nothing. // if (mPullRefreshing & height <= mHeaderViewHeight) {return ;} int finalHeight = 0; // The default final height is returned, that is to say, the header should be removed // is refreshing, just scroll back to show all the header. // refreshing. if (mPullRefreshing & height> mHeaderViewHeight) {finalHeight = mHeaderViewHeight;} mScrollBack = SCROLLBACK_HEADER; // from the current position, returns to the hidden m in the header. Scroller. startScroll (0, height, 0, finalHeight-height, SCROLL_DURATION); // trigger computeScrollinvalidate ();} /*** update the distance between footer and the bottom * @ param delta */private void updateFooterHeight (float delta) {int height = mFooterView. getBottomMargin () + (int) delta; if (mEnablePullLoad &&! MPullLoading) {if (height> PULL_LOAD_MORE_DELTA) {// height enough to invoke load. mFooterView. setState (XListViewFooter. STATE_READY);} else {mFooterView. setState (XListViewFooter. STATE_NORMAL) ;}} mFooterView. setBottomMargin (height); // setSelection (mTotalItemCount-1); // scroll to bottom}/*** reset footer position */private void resetFooterHeight () {int bottomMargin = mFooterView. getBottomMarg In (); if (bottomMargin> 0) {mScrollBack = SCROLLBACK_FOOTER; mScroller. startScroll (0, bottomMargin, 0,-bottomMargin, SCROLL_DURATION); invalidate () ;}} private void startLoadMore () {mPullLoading = true; mFooterView. setState (XListViewFooter. STATE_LOADING); if (mListViewListener! = Null) {mListViewListener. onLoadMore () ;}@ Overridepublic boolean onTouchEvent (MotionEvent ev) {if (mLastY =-1) {// obtain the y coordinate of the touch, mLastY = ev. getRawY ();} switch (ev. getAction () {case MotionEvent. ACTION_DOWN: mLastY = ev. getRawY (); break; case MotionEvent. ACTION_MOVE: final float deltaY = ev. getRawY ()-mLastY; // pull down or pull up the number of offsetmLastY = ev. getRawY (); if (getFirstVisiblePosition () = 0 & (mHeaderView. getVisiab LeHeight ()> 0 | deltaY> 0) {// The first item is visible and displayed in the header or in the drop-down menu, the first item is showing, header has shown or pull down. updateHeaderHeight (deltaY/OFFSET_RADIO); invokeOnScrolling ();} else if (getLastVisiblePosition () = mTotalItemCount-1 & (mFooterView. getBottomMargin ()> 0 | deltaY <0) {// The last item is visible and footer is displayed or pulled up, indicates that the instance is in the uppull refresh status // last item, already pulled up or want to pull up. up DateFooterHeight (-deltaY/OFFSET_RADIO);} break; default: // action_upmLastY =-1; // resetif (getFirstVisiblePosition () = 0) {// invoke refreshif (mEnablePullRefresh & mHeaderView. getVisiableHeight ()> mHeaderViewHeight) {mPullRefreshing = true; mHeaderView. setState (XListViewHeader. STATE_REFRESHING); if (mListViewListener! = Null) {mListViewListener. onRefresh () ;}} resetHeaderHeight ();} else if (getLastVisiblePosition () = mTotalItemCount-1) {// invoke load more. if (mEnablePullLoad & mFooterView. getBottomMargin ()> PULL_LOAD_MORE_DELTA &&! MPullLoading) {startLoadMore ();} resetFooterHeight ();} break;} return super. onTouchEvent (ev) ;}@ Overridepublic void computeScroll () {if (mScroller. computescroloffset () {if (mScrollBack = SCROLLBACK_HEADER) {mHeaderView. setVisiableHeight (mScroller. getCurrY ();} else {mFooterView. setBottomMargin (mScroller. getCurrY ();} postInvalidate (); invokeOnScrolling ();} super. computeScroll () ;}@ Overridepublic void se TOnScrollListener (OnScrollListener l) {mScrollListener = l ;}@ Overridepublic void onScrollStateChanged (AbsListView view, int scrollState) {if (mScrollListener! = Null) {mScrollListener. onScrollStateChanged (view, scrollState) ;}@ Overridepublic void onScroll (AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {// send to user's quota = totalItemCount; if (mScrollListener! = Null) {mScrollListener. onScroll (view, firstVisibleItem, visibleItemCount, totalItemCount) ;}} public void setXListViewListener (IXListViewListener l) {mListViewListener = l;}/*** you can listen ListView. onScrollListener or this one. it will invoke * onXScrolling when header/footer scroll back. */public interface OnXScrollListener extends OnScrollListener {public void onXScrolling (View view);}/*** implements this interface to get refresh/load more event. * drop-down and pull-up listeners */public interface IXListViewListener {public void onRefresh (); public void onLoadMore ();}}

XListViewHeader

 

 

Public class XListViewHeader extends LinearLayout {/*** drop-down layout subject */private LinearLayout mContainer;/*** drop-down arrow */private ImageView mArrowImageView; /*** ring progress bar */private ProgressBar mProgressBar;/*** text */private TextView mHintTextView; private int mState = STATE_NORMAL; private Animation mRotateUpAnim; private Animation mRotateDownAnim; /*** animation time */private final int ROTATE_ANIM_DURATION = 180; public Final static int STATE_NORMAL = 0; // public final static int STATE_READY = 1; // You can refresh public final static int STATE_REFRESHING = 2 from the drop-down list; // loading public XListViewHeader (Context context) {super (context); initView (context );} /*** @ param context * @ param attrs */public XListViewHeader (Context context, AttributeSet attrs) {super (context, attrs); initView (context );} private void initView (Context context) {// initial information Set the height of the drop-down refresh view to 0LinearLayout. layoutParams lp = new LinearLayout. layoutParams (LayoutParams. FILL_PARENT, 0); mContainer = (LinearLayout) LayoutInflater. from (context ). inflate (R. layout. xlistview_header, null); addView (mContainer, lp); setGravity (Gravity. BOTTOM); mArrowImageView = (ImageView) findViewById (R. id. xlistview_header_arrow); mHintTextView = (TextView) findViewById (R. id. xlistview_header_hint_textview ); MProgressBar = (ProgressBar) findViewById (R. id. xlistview_header_progressbar); // rotate the Animation mRotateUpAnim = new RotateAnimation (0.0f,-180.0f, Animation. RELATIVE_TO_SELF, 0.5f, Animation. RELATIVE_TO_SELF, 0.5f); // sets the animation time to mRotateUpAnim. setDuration (ROTATE_ANIM_DURATION); // when the animation ends, it stays at the last frame, that is, retaining the state of mRotateUpAnim after the animation. setFillAfter (true); // rotation Animation mRotateDownAnim = new RotateAnimation (-180.0f, 0.0f, Animation. RELATIVE_TO_SEL F, 0.5f, Animation. RELATIVE_TO_SELF, 0.5f); mRotateDownAnim. setDuration (ROTATE_ANIM_DURATION); mRotateDownAnim. setFillAfter (true);} public void setState (int state) {if (state = mState) return; if (state = STATE_REFRESHING) {// display progress mArrowImageView. clearAnimation (); mArrowImageView. setVisibility (View. INVISIBLE); mProgressBar. setVisibility (View. VISIBLE);} else {// display the arrow picture mArrowImageView. setVisibility (View. VISIBLE); mProgressBar. setVisibility (View. INVISIBLE);} switch (state) {case STATE_NORMAL: if (mState = STATE_READY) {mArrowImageView. startAnimation (mRotateDownAnim);} if (mState = STATE_REFRESHING) {mArrowImageView. clearAnimation ();} mHintTextView. setText (R. string. xlistview_header_hint_normal); break; case STATE_READY: if (mState! = STATE_READY) {mArrowImageView. clearAnimation (); mArrowImageView. startAnimation (mRotateUpAnim); mHintTextView. setText (R. string. xlistview_header_hint_ready);} break; case STATE_REFRESHING: mHintTextView. setText (R. string. xlistview_header_hint_loading); break; default:} mState = state;}/*** sets the effective height of the drop-down header * @ param height */public void setVisiableHeight (int height) {if (height <0) height = 0; LinearLayout. layoutParams lp = (LinearLayout. layoutParams) mContainer. getLayoutParams (); lp. height = height; mContainer. setLayoutParams (lp);}/*** get the effective height of the drop-down header * @ return */public int getVisiableHeight () {return mContainer. getLayoutParams (). height ;}}

XListViewFooter
Public class XListViewFooter extends LinearLayout {public final static int STATE_NORMAL = 0; // public final static int STATE_READY = 1; // You can refresh public final static int STATE_LOADING = 2; // loading private Context mContext; private View mContentView; private View mProgressBar; private TextView mHintView; public XListViewFooter (Context context) {super (context); initView (context );} public XListViewFooter (Context context, AttributeSet attrs) {super (context, attrs); initView (context );} /*** set status ** @ param state */public void setState (int state) {mHintView. setVisibility (View. INVISIBLE); mProgressBar. setVisibility (View. INVISIBLE); mHintView. setVisibility (View. INVISIBLE); if (state = STATE_READY) {mHintView. setVisibility (View. VISIBLE); mHintView. setText (R. string. xlistview_footer_hint_ready);} else if (state = STATE_LOADING) {mProgressBar. setVisibility (View. VISIBLE);} else {mHintView. setVisibility (View. VISIBLE); mHintView. setText (R. string. xlistview_footer_hint_normal) ;}}/*** set the bottom height of footer * @ param height */public void setBottomMargin (int height) {if (height <0) return; LinearLayout. layoutParams lp = (LinearLayout. layoutParams) mContentView. getLayoutParams (); lp. bottomMargin = height; mContentView. setLayoutParams (lp);}/*** get the bottom height of footer * @ return */public int getBottomMargin () {LinearLayout. layoutParams lp = (LinearLayout. layoutParams) mContentView. getLayoutParams (); return lp. bottomMargin;}/*** normal status */public void normal () {mHintView. setVisibility (View. VISIBLE); mProgressBar. setVisibility (View. GONE);}/*** loading status */public void loading () {mHintView. setVisibility (View. GONE); mProgressBar. setVisibility (View. VISIBLE);}/*** hide footer when disable pull load more */public void hide () {LinearLayout. layoutParams lp = (LinearLayout. layoutParams) mContentView. getLayoutParams (); lp. height = 0; mContentView. setLayoutParams (lp);}/*** show footer */public void show () {LinearLayout. layoutParams lp = (LinearLayout. layoutParams) mContentView. getLayoutParams (); lp. height = LayoutParams. WRAP_CONTENT; mContentView. setLayoutParams (lp);}/*** initialize Layout * @ param context */private void initView (Context context) {mContext = context; LinearLayout moreView = (LinearLayout) LayoutInflater. from (mContext ). inflate (R. layout. xlistview_footer, null); addView (moreView); moreView. setLayoutParams (new LinearLayout. layoutParams (LayoutParams. FILL_PARENT, LayoutParams. WRAP_CONTENT); mContentView = moreView. findViewById (R. id. xlistview_footer_content); mProgressBar = moreView. findViewById (R. id. xlistview_footer_progressbar); mHintView = (TextView) moreView. findViewById (R. id. xlistview_footer_hint_textview );}}

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.