Android-custom controls implement ListView pull-down refresh and androidlistview

Source: Internet
Author: User

Android-custom controls implement ListView pull-down refresh and androidlistview

This blog introduces you to a common feature of android-ListView pull-down refresh (refer to the blog of another user who forgot the website, read his code and understand the comments, hoping to help you ):

First, the mobile phone displays the following interface when the drop-down fails:

The following code is a custom Sample Control:

Package com. dhsr. smartID. view; import android. content. context; import android. util. attributeSet; import android. view. gravity; import android. view. layoutInflater; import android. view. view; import android. view. animation. animation; import android. view. animation. rotateAnimation; import android. widget. imageView; import android. widget. linearLayout; import android. widget. progressBar; import android. widget. textView; I Mport com. example. sirelinkscanapp. R;/*** custom control. When the drop-down is completed, the ListView displays "the icon and prompt is refreshing ......" * @ Author cyf **/public class XListViewHeader extends LinearLayout {private LinearLayout mContainer; // picture private ImageView mArrowImageView; // circular progress bar private ProgressBar mProgressBar; private TextView mHintTextView; // State private int mState = STATE_NORMAL; // Animation private Animation mRotateUpAnim; private Animation mRotateDownAnim; private final int ROTATE_ANIM_DURATION = 180; // normal public final static int STATE_NORMAL = 0; // prepare to refresh public final static int STATE_READY = 1; // public final static int STATE_REFRESHING = 2; public XListViewHeader (Context context) {super (context ); initView (context);}/*** @ param context * @ param attrs */public XListViewHeader (Context context, AttributeSet attrs) {super (context, attrs ); initView (context);}/*** "release to refresh ...... Refreshing ......" ** @ Param context */private void initView (Context context) {// in the Initial State, set the drop-down refresh view height to 0LinearLayout. layoutParams lp = new LinearLayout. layoutParams (LayoutParams. MATCH_PARENT, 0); mContainer = (LinearLayout) LayoutInflater. from (context ). inflate (R. layout. xlistview_header, null); // load the view addView (mContainer, lp); // setGravity (Gravity. BOTTOM); // initialization control mArrowImageView = (ImageView) findViewById (R. id. xlis Tview_header_arrow); mHintTextView = (TextView) findViewById (R. id. xlistview_header_hint_textview); mProgressBar = (ProgressBar) findViewById (R. id. xlistview_header_progressbar); // set the Animation mRotateUpAnim = new RotateAnimation (0.0f,-180.0f, Animation. RELATIVE_TO_SELF, 0.5f, Animation. RELATIVE_TO_SELF, 0.5f); mRotateUpAnim. setDuration (ROTATE_ANIM_DURATION); mRotateUpAnim. setFillAfter (true); mRotateDownAnim = new RotateAnimation (-180.0f, 0.0f, Animation. RELATIVE_TO_SELF, 0.5f, Animation. RELATIVE_TO_SELF, 0.5f); mRotateDownAnim. setDuration (ROTATE_ANIM_DURATION); mRotateDownAnim. setFillAfter (true);}/*** execute the corresponding function based on the drop-down status to start and stop the corresponding animation ** @ param state */public void setState (int state) {if (state = mState) return; if (state = STATE_REFRESHING) {// display progress mArrowImageView. clearAnimation (); mArrowImageView. setVisibility (Vi Ew. 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) {// start the animation mArrowImageView. startAnimation (mRotateDownAnim);} // refresh if (mState = STATE_REFRESHING) {// clear the animation mArrowImageView. clearAnimation ();} mHintTextView. setText (R. string. xlistview_h Eader_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;} public void setVisiableHeight (int height) {if (height <0) height = 0; LinearLayout. layoutParams lp = (LinearLayout. layoutParams) mContainer. getLayoutParams (); lp. height = height; mContainer. setLayoutParams (lp);} public int getVisiableHeight () {return mContainer. getHeight ();}}

Next, you need to customize your own ListView to inherit from the android ListView, so that you can easily add new methods.

Package com. dhsr. smartID. view; import android. content. context; import android. util. attributeSet; import android. view. motionEvent; import android. view. view; import android. view. viewTreeObserver. onGlobalLayoutListener; import android. view. animation. decelerateInterpolator; import android. widget. absListView; import android. widget. absListView. onScrollListener; import android. widget. listAdapter; import android. wid Get. listView; import android. widget. relativeLayout; import android. widget. scroller; import android. widget. textView; import com. example. sirelinkscanapp. r;/*** custom ListView ** @ author cyf **/public class XListView extends ListView implements OnScrollListener {private final String TAG = "XListView "; private float mLastY =-1; private Scroller mscroler; // sliding private OnScrollListener mScrollListener; // outside Create a listener private IXListViewListener mListViewListener; // The custom control private XListViewHeader mHeaderView; private RelativeLayout mHeaderViewContent; private TextView mHeaderTimeView; private int mHeaderViewHeight; // header view's heightprivate boolean mEnablePullRefresh = true; private boolean mPullRefreshing = false; // is refreashing. private boolean mEnablePullLoad; private boolean mPullLoading; private boo Lean 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; private final static int SCROLLBACK_HEADER = 0; private final static int SCROLLBACK_FOOTER = 1; private final static int SCROLL_DURATION = 400; // scroll back durationprivate final static int PULL_LOAD_MOR E_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); initWithContext (context);} public XListView (Context context, AttributeS Et attrs, int defStyle) {super (context, attrs, defStyle); initWithContext (context );} /*** initialize the control ** @ param context */private void initWithContext (Context context) {mScroller = new Scroller (context, new DecelerateInterpolator (); super. setOnScrollListener (this); mHeaderView = new XListViewHeader (context); mHeaderViewContent = (RelativeLayout) mHeaderView. findViewById (R. id. xlistview_header_content); mHea DerTimeView = (TextView) mHeaderView. findViewById (R. id. xlistview_header_time); addHeaderView (mHeaderView, null, false); mHeaderView. getViewTreeObserver (). addOnGlobalLayoutListener (new OnGlobalLayoutListener () {@ Overridepublic void onGlobalLayout () {mHeaderViewHeight = mHeaderViewContent. getHeight (); getViewTreeObserver (). removeGlobalOnLayoutListener (this) ;}}) ;}@ Overridepublic void setAdapter (ListAdap Ter adapter) {// make sure XListViewFooter is the last footer view, and only add once. if (mIsFooterReady = false) {if (mEnablePullLoad) {mIsFooterReady = true; // addFooterView (mFooterView);} super. setAdapter (adapter);} public void setPullRefreshEnable (boolean enable) {mEnablePullRefresh = enable; if (! MEnablePullRefresh) {// disable, hide the contentmHeaderViewContent. setVisibility (View. INVISIBLE);} else {mHeaderViewContent. setVisibility (View. VISIBLE) ;}/ *** stop refreshing */public void stopRefresh () {if (mPullRefreshing = true) {mPullRefreshing = false; resetHeaderHeight ();}} // when you enter the Activity, execute a drop-down refresh public void startRefresh () {if (mPullRefreshing = false) {mPullRefreshing = true; mHeaderView. setState (XLi StViewHeader. STATE_REFRESHING); mHeaderView. setVisiableHeight (90); if (mListViewListener! = Null) {mListViewListener. onRefresh () ;}}/ *** stop load more, reset footer view. */public void stopLoadMore () {if (mPullLoading = true) {mPullLoading = false ;}} /*** set last refresh time *** @ param time */public void setRefreshTime (String time) {mHeaderTimeView. setText (time);} private void invokeOnScrolling () {if (mScrollListener instanceof OnXScrollListener) {OnXScrollListener l = (OnXScrollLis Tener) mScrollListener; l. onXScrolling (this) ;}} 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);} if (mPullLoading) {// disable, hide the contentmHeaderViewContent. setVisibility (View. INVISIBLE);} else {mHeaderViewContent. setVisibility (View. VISIBLE) ;}} setSelection (0); // scroll to top each time }/ * ** Reset header view's height. */private void resetHeaderHeight () {int height = mHeaderView. getVisiableHeight (); if (height = 0) // not visible. return; // refreshing and header isn' t shown fully. do nothing. if (mPullRefreshing & height <= mHeaderViewHeight) {return;} int finalHeight = 0; // default: scroll back to dismiss header. // is refreshing, just scroll back to show all the header. if (mPullR Efreshing & height> mHeaderViewHeight) {finalHeight = mHeaderViewHeight;} mScrollBack = SCROLLBACK_HEADER; mScroller. startScroll (0, height, 0, finalHeight-height, SCROLL_DURATION); // trigger computeScrollinvalidate ();}/*** touch screen listener */@ Overridepublic boolean onTouchEvent (MotionEvent ev) {if (mLastY =-1) {mLastY = ev. getRawY ();} switch (ev. getAction () {case MotionEvent. ACTION_DOWN: mLastY = ev. getRaw Y (); break; case MotionEvent. ACTION_MOVE: final float deltaY = ev. getRawY ()-mLastY; // DLog. I (TAG, "deltaY is" + deltaY); mLastY = ev. getRawY (); if (getFirstVisiblePosition () = 0 & (mHeaderView. getVisiableHeight ()> 0 | deltaY> 0) {// the first item is showing, header has shown or pull down. updateHeaderHeight (deltaY/OFFSET_RADIO); invokeOnScrolling ();} else if (getLastVisiblePosition () = mTotal ItemCount-1) {// last item, already pulled up or want to pull up .} break; default: mLastY =-1; // resetif (getFirstVisiblePosition () = 0) {// invoke refreshif (! MPullRefreshing & mEnablePullRefresh &&! MPullLoading & mHeaderView. getVisiableHeight ()> mHeaderViewHeight) {mPullRefreshing = true; mHeaderView. setState (XListViewHeader. STATE_REFRESHING); // DLog. I (TAG, "invoke refresh"); if (mListViewListener! = Null) {// execute the new method mListViewListener. onRefresh () ;}} resetHeaderHeight ();} else if (getLastVisiblePosition () = mTotalItemCount-1) {// invoke load more. if (! MPullLoading & mEnablePullLoad &&! MPullRefreshing) {// DLog. I (TAG, "invoke load more") ;}} break;} return super. onTouchEvent (ev) ;}@ Overridepublic void computeScroll () {if (mScroller. computescroloffset () {if (mScrollBack = SCROLLBACK_HEADER) {mHeaderView. setVisiableHeight (mScroller. getCurrY ();} else {} postInvalidate (); invokeOnScrolling ();} super. computeScroll () ;}@ Overridepublic void setOnScrollListener (OnScrollListener l) {mScrollLi Stener = l;}/*** calls back when rolling. The callback is 2-3 times. If you don't leave your finger blank, the callback is 2 times. If scrollState is 2, the callback is not performed for 1st times: scrollState = * SCROLL_STATE_TOUCH_SCROLL (1) rolling 2nd times: scrollState = * SCROLL_STATE_FLING (2) the finger throws (slide hard before leaving the screen) for 3rd Times: scrollState = * SCROLL_STATE_IDLE (0) Stop rolling */@ Overridepublic void onScrollStateChanged (AbsListView view, int scrollState) {if (mScrollListener! = Null) {mScrollListener. onScrollStateChanged (view, scrollState);} // load more automatically when sliding to the bottom. You can also disable this logic if (getLastVisiblePosition () = mTotalItemCount-1 & scrollState = SCROLL_STATE_IDLE) {if (! MPullLoading & mEnablePullLoad &&! MPullRefreshing) {// DLog. I (TAG, "invoke load more") ;}}/*** calls back when rolling is in progress, and stops the callback only when the rolling is stopped, call back once when you click */@ Overridepublic void onScroll (AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {// send to user's quota = totalItemCount; if (rollmsclistener! = Null) {mScrollListener. onScroll (view, firstVisibleItem, visibleItemCount, totalItemCount) ;}} public void setXListViewListener (IXListViewListener l) {mListViewListener = l ;} /*** listen to the ListView sliding event ** @ author cyf **/public interface OnXScrollListener extends OnScrollListener {public void onXScrolling (View view );} /*** custom interface */public interface IXListViewListener {// The method of public void onRefresh () executed during the pull-down refresh (); // public void onLoadMore ();}}

In the xml file of MainActivity, do not use the android ListView instead. Use the custom ListView above (with the package name)

Package com. test. andy; import java. util. arrayList; import com. test. andy. view. XListView; import com. test. andy. view. XListView. IXListViewListener; import com. test. andy. r; import android. app. activity; import android. OS. bundle; import android. OS. handler; import android. widget. arrayAdapter;/*** XListViewActivity * implements the IXListViewListener interface to implement the drop-down and refresh methods. * @ author cyf **/public class XListViewActivity extends Act Ivity implements IXListViewListener {// custom ListViewprivate XListView mListView; private ArrayAdapter <String> mAdapter; private ArrayList <String> items = new ArrayList <String> (); private Handler mHandler; private int start = 0; private int refreshCnt = 0;/** Called when the activity is first created. * // @ Overridepublic void onCreate (Bundle savedInstanceState) {super. onCreate (savedInstanceState); setConten TView (R. layout. main); // load 20 pieces of data during initialization (geneItems (); mListView = (XListView) findViewById (R. id. xListView); mListView. setPullLoadEnable (true); mAdapter = new ArrayAdapter <String> (this, R. layout. list_item, items); mListView. setAdapter (mAdapter); // mListView. setPullRefreshEnable (false); mListView. setXListViewListener (this); mHandler = new Handler (); mListView. startRefresh ();} private void geneItems () {for (int I = 0; I! = 20; ++ I) {items. add ("refresh cnt" + (++ start) ;}} private void onLoad () {mListView. stopRefresh (); mListView. stopLoadMore (); mListView. setRefreshTime ("just") ;}@ Overridepublic void onRefresh () {mHandler. postDelayed (new Runnable () {@ Overridepublic void run () {start = ++ refreshCnt; items. clear (); geneItems (); // mAdapter. notifyDataSetChanged (); mAdapter = new ArrayAdapter <String> (XListViewActivity. this, R. layout. list_item, items); mListView. setAdapter (mAdapter); onLoad () ;}, 2000) ;}@ Overridepublic void onLoadMore () {mHandler. postDelayed (new Runnable () {@ Overridepublic void run () {geneItems (); mAdapter. notifyDataSetChanged (); onLoad () ;}, 2000 );}}

The important code is summarized here. I hope to help you. Thank you.

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.