Android中ListView(下拉刷新、上拉载入更多)的示例-XListView控件实现

该示例使用的github上的一个开源控件XListView,作者:Maxwin-z,源码地址:https://github.com/Maxwin-z/XListView-Android

测试activity:XListViewActivity

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. package me.maxwin;  
  2.   
  3. import java.util.ArrayList;  
  4.   
  5. import me.maxwin.view.XListView;  
  6. import me.maxwin.view.XListView.IXListViewListener;  
  7. import android.app.Activity;  
  8. import android.os.Bundle;  
  9. import android.os.Handler;  
  10. import android.widget.ArrayAdapter;  
  11.   
  12. public class XListViewActivity extends Activity implements IXListViewListener {  
  13.     private XListView mListView;  
  14.     private ArrayAdapter<String> mAdapter;  
  15.     private ArrayList<String> items = new ArrayList<String>();  
  16.     private Handler mHandler;  
  17.     private int start = 0;  
  18.     private static int refreshCnt = 0;  
  19.   
  20.     @Override  
  21.     public void onCreate(Bundle savedInstanceState) {  
  22.         super.onCreate(savedInstanceState);  
  23.         setContentView(R.layout.main);  
  24.         geneItems();  
  25.         mListView = (XListView) findViewById(R.id.xListView);  
  26.         mListView.setPullLoadEnable(true);  
  27.         mAdapter = new ArrayAdapter<String>(this, R.layout.list_item, items);  
  28.         mListView.setAdapter(mAdapter);  
  29.         // mListView.setPullLoadEnable(false);  
  30.         // mListView.setPullRefreshEnable(false);  
  31.         mListView.setXListViewListener(this);  
  32.         mHandler = new Handler();  
  33.     }  
  34.   
  35.     private void geneItems() {  
  36.         for (int i = 0; i != 5; ++i) {  
  37.             items.add("refresh cnt " + (++start));  
  38.         }  
  39.     }  
  40.   
  41.     private void onLoad() {  
  42.         mListView.stopRefresh();  
  43.         mListView.stopLoadMore();  
  44.         mListView.setRefreshTime("刚刚");  
  45.     }  
  46.   
  47.     @Override  
  48.     public void onRefresh() {  
  49.         mHandler.postDelayed(new Runnable() {  
  50.             @Override  
  51.             public void run() {  
  52.                 start = ++refreshCnt;  
  53.                 items.clear();  
  54.                 geneItems();  
  55.                 // mAdapter.notifyDataSetChanged();  
  56.                 mAdapter = new ArrayAdapter<String>(XListViewActivity.this,  
  57.                         R.layout.list_item, items);  
  58.                 mListView.setAdapter(mAdapter);  
  59.                 onLoad();  
  60.             }  
  61.         }, 2000);  
  62.     }  
  63.   
  64.     @Override  
  65.     public void onLoadMore() {  
  66.         mHandler.postDelayed(new Runnable() {  
  67.             @Override  
  68.             public void run() {  
  69.                 geneItems();  
  70.                 mAdapter.notifyDataSetChanged();  
  71.                 onLoad();  
  72.             }  
  73.         }, 2000);  
  74.     }  
  75.   
  76. }  

控件:XListView

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. /** 
  2.  * @file XListView.java 
  3.  * @package me.maxwin.view 
  4.  * @create Mar 18, 2012 6:28:41 PM 
  5.  * @author Maxwin 
  6.  * @description An ListView support (a) Pull down to refresh, (b) Pull up to load more. 
  7.  *      Implement IXListViewListener, and see stopRefresh() / stopLoadMore(). 
  8.  */  
  9. package me.maxwin.view;  
  10.   
  11. import me.maxwin.R;  
  12. import android.content.Context;  
  13. import android.util.AttributeSet;  
  14. import android.view.MotionEvent;  
  15. import android.view.View;  
  16. import android.view.ViewTreeObserver.OnGlobalLayoutListener;  
  17. import android.view.animation.DecelerateInterpolator;  
  18. import android.widget.AbsListView;  
  19. import android.widget.AbsListView.OnScrollListener;  
  20. import android.widget.ListAdapter;  
  21. import android.widget.ListView;  
  22. import android.widget.RelativeLayout;  
  23. import android.widget.Scroller;  
  24. import android.widget.TextView;  
  25.   
  26. public class XListView extends ListView implements OnScrollListener {  
  27.   
  28.     private float mLastY = -1// save event y  
  29.     private Scroller mScroller; // used for scroll back  
  30.     private OnScrollListener mScrollListener; // user's scroll listener  
  31.   
  32.     // the interface to trigger refresh and load more.  
  33.     private IXListViewListener mListViewListener;  
  34.   
  35.     // -- header view  
  36.     private XListViewHeader mHeaderView;  
  37.     // header view content, use it to calculate the Header's height. And hide it  
  38.     // when disable pull refresh.  
  39.     private RelativeLayout mHeaderViewContent;  
  40.     private TextView mHeaderTimeView;  
  41.     private int mHeaderViewHeight; // header view's height  
  42.     private boolean mEnablePullRefresh = true;  
  43.     private boolean mPullRefreshing = false// is refreashing.  
  44.   
  45.     // -- footer view  
  46.     private XListViewFooter mFooterView;  
  47.     private boolean mEnablePullLoad;  
  48.     private boolean mPullLoading;  
  49.     private boolean mIsFooterReady = false;  
  50.   
  51.     // total list items, used to detect is at the bottom of listview.  
  52.     private int mTotalItemCount;  
  53.   
  54.     // for mScroller, scroll back from header or footer.  
  55.     private int mScrollBack;  
  56.     private final static int SCROLLBACK_HEADER = 0;  
  57.     private final static int SCROLLBACK_FOOTER = 1;  
  58.   
  59.     private final static int SCROLL_DURATION = 400// scroll back duration  
  60.     private final static int PULL_LOAD_MORE_DELTA = 50// when pull up >= 50px  
  61.                                                         // at bottom, trigger  
  62.                                                         // load more.  
  63.     private final static float OFFSET_RADIO = 1.8f; // support iOS like pull  
  64.                                                     // feature.  
  65.   
  66.     /** 
  67.      * @param context 
  68.      */  
  69.     public XListView(Context context) {  
  70.         super(context);  
  71.         initWithContext(context);  
  72.     }  
  73.   
  74.     public XListView(Context context, AttributeSet attrs) {  
  75.         super(context, attrs);  
  76.         initWithContext(context);  
  77.     }  
  78.   
  79.     public XListView(Context context, AttributeSet attrs, int defStyle) {  
  80.         super(context, attrs, defStyle);  
  81.         initWithContext(context);  
  82.     }  
  83.   
  84.     private void initWithContext(Context context) {  
  85.         mScroller = new Scroller(context, new DecelerateInterpolator());  
  86.         // XListView need the scroll event, and it will dispatch the event to  
  87.         // user's listener (as a proxy).  
  88.         super.setOnScrollListener(this);  
  89.   
  90.         // init header view  
  91.         mHeaderView = new XListViewHeader(context);  
  92.         mHeaderViewContent = (RelativeLayout) mHeaderView  
  93.                 .findViewById(R.id.xlistview_header_content);  
  94.         mHeaderTimeView = (TextView) mHeaderView  
  95.                 .findViewById(R.id.xlistview_header_time);  
  96.         addHeaderView(mHeaderView);  
  97.   
  98.         // init footer view  
  99.         mFooterView = new XListViewFooter(context);  
  100.   
  101.         // init header height  
  102.         mHeaderView.getViewTreeObserver().addOnGlobalLayoutListener(  
  103.                 new OnGlobalLayoutListener() {  
  104.                     @Override  
  105.                     public void onGlobalLayout() {  
  106.                         mHeaderViewHeight = mHeaderViewContent.getHeight();  
  107.                         getViewTreeObserver()  
  108.                                 .removeGlobalOnLayoutListener(this);  
  109.                     }  
  110.                 });  
  111.     }  
  112.   
  113.     @Override  
  114.     public void setAdapter(ListAdapter adapter) {  
  115.         // make sure XListViewFooter is the last footer view, and only add once.  
  116.         if (mIsFooterReady == false) {  
  117.             mIsFooterReady = true;  
  118.             addFooterView(mFooterView);  
  119.         }  
  120.         super.setAdapter(adapter);  
  121.     }  
  122.   
  123.     /** 
  124.      * enable or disable pull down refresh feature. 
  125.      *  
  126.      * @param enable 
  127.      */  
  128.     public void setPullRefreshEnable(boolean enable) {  
  129.         mEnablePullRefresh = enable;  
  130.         if (!mEnablePullRefresh) { // disable, hide the content  
  131.             mHeaderViewContent.setVisibility(View.INVISIBLE);  
  132.         } else {  
  133.             mHeaderViewContent.setVisibility(View.VISIBLE);  
  134.         }  
  135.     }  
  136.   
  137.     /** 
  138.      * enable or disable pull up load more feature. 
  139.      *  
  140.      * @param enable 
  141.      */  
  142.     public void setPullLoadEnable(boolean enable) {  
  143.         mEnablePullLoad = enable;  
  144.         if (!mEnablePullLoad) {  
  145.             mFooterView.hide();  
  146.             mFooterView.setOnClickListener(null);  
  147.         } else {  
  148.             mPullLoading = false;  
  149.             mFooterView.show();  
  150.             mFooterView.setState(XListViewFooter.STATE_NORMAL);  
  151.             // both "pull up" and "click" will invoke load more.  
  152.             mFooterView.setOnClickListener(new OnClickListener() {  
  153.                 @Override  
  154.                 public void onClick(View v) {  
  155.                     startLoadMore();  
  156.                 }  
  157.             });  
  158.         }  
  159.     }  
  160.   
  161.     /** 
  162.      * stop refresh, reset header view. 
  163.      */  
  164.     public void stopRefresh() {  
  165.         if (mPullRefreshing == true) {  
  166.             mPullRefreshing = false;  
  167.             resetHeaderHeight();  
  168.         }  
  169.     }  
  170.   
  171.     /** 
  172.      * stop load more, reset footer view. 
  173.      */  
  174.     public void stopLoadMore() {  
  175.         if (mPullLoading == true) {  
  176.             mPullLoading = false;  
  177.             mFooterView.setState(XListViewFooter.STATE_NORMAL);  
  178.         }  
  179.     }  
  180.   
  181.     /** 
  182.      * set last refresh time 
  183.      *  
  184.      * @param time 
  185.      */  
  186.     public void setRefreshTime(String time) {  
  187.         mHeaderTimeView.setText(time);  
  188.     }  
  189.   
  190.     private void invokeOnScrolling() {  
  191.         if (mScrollListener instanceof OnXScrollListener) {  
  192.             OnXScrollListener l = (OnXScrollListener) mScrollListener;  
  193.             l.onXScrolling(this);  
  194.         }  
  195.     }  
  196.   
  197.     private void updateHeaderHeight(float delta) {  
  198.         mHeaderView.setVisiableHeight((int) delta  
  199.                 + mHeaderView.getVisiableHeight());  
  200.         if (mEnablePullRefresh && !mPullRefreshing) { // 未处于刷新状态,更新箭头  
  201.             if (mHeaderView.getVisiableHeight() > mHeaderViewHeight) {  
  202.                 mHeaderView.setState(XListViewHeader.STATE_READY);  
  203.             } else {  
  204.                 mHeaderView.setState(XListViewHeader.STATE_NORMAL);  
  205.             }  
  206.         }  
  207.         setSelection(0); // scroll to top each time  
  208.     }  
  209.   
  210.     /** 
  211.      * reset header view's height. 
  212.      */  
  213.     private void resetHeaderHeight() {  
  214.         int height = mHeaderView.getVisiableHeight();  
  215.         if (height == 0// not visible.  
  216.             return;  
  217.         // refreshing and header isn't shown fully. do nothing.  
  218.         if (mPullRefreshing && height <= mHeaderViewHeight) {  
  219.             return;  
  220.         }  
  221.         int finalHeight = 0// default: scroll back to dismiss header.  
  222.         // is refreshing, just scroll back to show all the header.  
  223.         if (mPullRefreshing && height > mHeaderViewHeight) {  
  224.             finalHeight = mHeaderViewHeight;  
  225.         }  
  226.         mScrollBack = SCROLLBACK_HEADER;  
  227.         mScroller.startScroll(0, height, 0, finalHeight - height,  
  228.                 SCROLL_DURATION);  
  229.         // trigger computeScroll  
  230.         invalidate();  
  231.     }  
  232.   
  233.     private void updateFooterHeight(float delta) {  
  234.         int height = mFooterView.getBottomMargin() + (int) delta;  
  235.         if (mEnablePullLoad && !mPullLoading) {  
  236.             if (height > PULL_LOAD_MORE_DELTA) { // height enough to invoke load  
  237.                                                     // more.  
  238.                 mFooterView.setState(XListViewFooter.STATE_READY);  
  239.             } else {  
  240.                 mFooterView.setState(XListViewFooter.STATE_NORMAL);  
  241.             }  
  242.         }  
  243.         mFooterView.setBottomMargin(height);  
  244.   
  245.         // setSelection(mTotalItemCount - 1); // scroll to bottom  
  246.     }  
  247.   
  248.     private void resetFooterHeight() {  
  249.         int bottomMargin = mFooterView.getBottomMargin();  
  250.         if (bottomMargin > 0) {  
  251.             mScrollBack = SCROLLBACK_FOOTER;  
  252.             mScroller.startScroll(0, bottomMargin, 0, -bottomMargin,  
  253.                     SCROLL_DURATION);  
  254.             invalidate();  
  255.         }  
  256.     }  
  257.   
  258.     private void startLoadMore() {  
  259.         mPullLoading = true;  
  260.         mFooterView.setState(XListViewFooter.STATE_LOADING);  
  261.         if (mListViewListener != null) {  
  262.             mListViewListener.onLoadMore();  
  263.         }  
  264.     }  
  265.   
  266.     @Override  
  267.     public boolean onTouchEvent(MotionEvent ev) {  
  268.         if (mLastY == -1) {  
  269.             mLastY = ev.getRawY();  
  270.         }  
  271.   
  272.         switch (ev.getAction()) {  
  273.         case MotionEvent.ACTION_DOWN:  
  274.             mLastY = ev.getRawY();  
  275.             break;  
  276.         case MotionEvent.ACTION_MOVE:  
  277.             final float deltaY = ev.getRawY() - mLastY;  
  278.             mLastY = ev.getRawY();  
  279.             System.out.println("数据监测:" + getFirstVisiblePosition() + "---->"  
  280.                     + getLastVisiblePosition());  
  281.             if (getFirstVisiblePosition() == 0  
  282.                     && (mHeaderView.getVisiableHeight() > 0 || deltaY > 0)) {  
  283.                 // the first item is showing, header has shown or pull down.  
  284.                 updateHeaderHeight(deltaY / OFFSET_RADIO);  
  285.                 invokeOnScrolling();  
  286.             } else if (getLastVisiblePosition() == mTotalItemCount - 1  
  287.                     && (mFooterView.getBottomMargin() > 0 || deltaY < 0)) {  
  288.                 // last item, already pulled up or want to pull up.  
  289.                 updateFooterHeight(-deltaY / OFFSET_RADIO);  
  290.             }  
  291.             break;  
  292.         default:  
  293.             mLastY = -1// reset  
  294.             if (getFirstVisiblePosition() == 0) {  
  295.                 // invoke refresh  
  296.                 if (mEnablePullRefresh  
  297.                         && mHeaderView.getVisiableHeight() > mHeaderViewHeight) {  
  298.                     mPullRefreshing = true;  
  299.                     mHeaderView.setState(XListViewHeader.STATE_REFRESHING);  
  300.                     if (mListViewListener != null) {  
  301.                         mListViewListener.onRefresh();  
  302.                     }  
  303.                 }  
  304.                 resetHeaderHeight();  
  305.             }  
  306.             if (getLastVisiblePosition() == mTotalItemCount - 1) {  
  307.                 // invoke load more.  
  308.                 if (mEnablePullLoad  
  309.                         && mFooterView.getBottomMargin() > PULL_LOAD_MORE_DELTA) {  
  310.                     startLoadMore();  
  311.                 }  
  312.                 resetFooterHeight();  
  313.             }  
  314.             break;  
  315.         }  
  316.         return super.onTouchEvent(ev);  
  317.     }  
  318.   
  319.     @Override  
  320.     public void computeScroll() {  
  321.         if (mScroller.computeScrollOffset()) {  
  322.             if (mScrollBack == SCROLLBACK_HEADER) {  
  323.                 mHeaderView.setVisiableHeight(mScroller.getCurrY());  
  324.             } else {  
  325.                 mFooterView.setBottomMargin(mScroller.getCurrY());  
  326.             }  
  327.             postInvalidate();  
  328.             invokeOnScrolling();  
  329.         }  
  330.         super.computeScroll();  
  331.     }  
  332.   
  333.     @Override  
  334.     public void setOnScrollListener(OnScrollListener l) {  
  335.         mScrollListener = l;  
  336.     }  
  337.   
  338.     @Override  
  339.     public void onScrollStateChanged(AbsListView view, int scrollState) {  
  340.         if (mScrollListener != null) {  
  341.             mScrollListener.onScrollStateChanged(view, scrollState);  
  342.         }  
  343.     }  
  344.   
  345.     @Override  
  346.     public void onScroll(AbsListView view, int firstVisibleItem,  
  347.             int visibleItemCount, int totalItemCount) {  
  348.         // send to user's listener  
  349.         mTotalItemCount = totalItemCount;  
  350.         if (mScrollListener != null) {  
  351.             mScrollListener.onScroll(view, firstVisibleItem, visibleItemCount,  
  352.                     totalItemCount);  
  353.         }  
  354.     }  
  355.   
  356.     public void setXListViewListener(IXListViewListener l) {  
  357.         mListViewListener = l;  
  358.     }  
  359.   
  360.     /** 
  361.      * you can listen ListView.OnScrollListener or this one. it will invoke 
  362.      * onXScrolling when header/footer scroll back. 
  363.      */  
  364.     public interface OnXScrollListener extends OnScrollListener {  
  365.         public void onXScrolling(View view);  
  366.     }  
  367.   
  368.     /** 
  369.      * implements this interface to get refresh/load more event. 
  370.      */  
  371.     public interface IXListViewListener {  
  372.         public void onRefresh();  
  373.   
  374.         public void onLoadMore();  
  375.     }  
  376. }  

XListView顶部:XListViewHeader

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. /** 
  2.  * @file XListViewHeader.java 
  3.  * @create Apr 18, 2012 5:22:27 PM 
  4.  * @author Maxwin 
  5.  * @description XListView's header 
  6.  */  
  7. package me.maxwin.view;  
  8.   
  9. import me.maxwin.R;  
  10. import android.content.Context;  
  11. import android.util.AttributeSet;  
  12. import android.view.Gravity;  
  13. import android.view.LayoutInflater;  
  14. import android.view.View;  
  15. import android.view.animation.Animation;  
  16. import android.view.animation.RotateAnimation;  
  17. import android.widget.ImageView;  
  18. import android.widget.LinearLayout;  
  19. import android.widget.ProgressBar;  
  20. import android.widget.TextView;  
  21.   
  22. public class XListViewHeader extends LinearLayout {  
  23.     private LinearLayout mContainer;  
  24.     private ImageView mArrowImageView;  
  25.     private ProgressBar mProgressBar;  
  26.     private TextView mHintTextView;  
  27.     private int mState = STATE_NORMAL;  
  28.   
  29.     private Animation mRotateUpAnim;  
  30.     private Animation mRotateDownAnim;  
  31.   
  32.     private final int ROTATE_ANIM_DURATION = 180;  
  33.   
  34.     public final static int STATE_NORMAL = 0;  
  35.     public final static int STATE_READY = 1;  
  36.     public final static int STATE_REFRESHING = 2;  
  37.   
  38.     public XListViewHeader(Context context) {  
  39.         super(context);  
  40.         initView(context);  
  41.     }  
  42.   
  43.     /** 
  44.      * @param context 
  45.      * @param attrs 
  46.      */  
  47.     public XListViewHeader(Context context, AttributeSet attrs) {  
  48.         super(context, attrs);  
  49.         initView(context);  
  50.     }  
  51.   
  52.     private void initView(Context context) {  
  53.         // 初始情况,设置下拉刷新view高度为0  
  54.         LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(  
  55.                 LayoutParams.MATCH_PARENT, 0);  
  56.         mContainer = (LinearLayout) LayoutInflater.from(context).inflate(  
  57.                 R.layout.xlistview_header, null);  
  58.         addView(mContainer, lp);  
  59.         setGravity(Gravity.BOTTOM);  
  60.   
  61.         mArrowImageView = (ImageView) findViewById(R.id.xlistview_header_arrow);  
  62.         mHintTextView = (TextView) findViewById(R.id.xlistview_header_hint_textview);  
  63.         mProgressBar = (ProgressBar) findViewById(R.id.xlistview_header_progressbar);  
  64.   
  65.         mRotateUpAnim = new RotateAnimation(0.0f, -180.0f,  
  66.                 Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,  
  67.                 0.5f);  
  68.         mRotateUpAnim.setDuration(ROTATE_ANIM_DURATION);  
  69.         mRotateUpAnim.setFillAfter(true);  
  70.         mRotateDownAnim = new RotateAnimation(-180.0f, 0.0f,  
  71.                 Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,  
  72.                 0.5f);  
  73.         mRotateDownAnim.setDuration(ROTATE_ANIM_DURATION);  
  74.         mRotateDownAnim.setFillAfter(true);  
  75.     }  
  76.   
  77.     public void setState(int state) {  
  78.         if (state == mState)  
  79.             return;  
  80.   
  81.         if (state == STATE_REFRESHING) { // 显示进度  
  82.             mArrowImageView.clearAnimation();  
  83.             mArrowImageView.setVisibility(View.INVISIBLE);  
  84.             mProgressBar.setVisibility(View.VISIBLE);  
  85.         } else { // 显示箭头图片  
  86.             mArrowImageView.setVisibility(View.VISIBLE);  
  87.             mProgressBar.setVisibility(View.INVISIBLE);  
  88.         }  
  89.   
  90.         switch (state) {  
  91.         case STATE_NORMAL:  
  92.             if (mState == STATE_READY) {  
  93.                 mArrowImageView.startAnimation(mRotateDownAnim);  
  94.             }  
  95.             if (mState == STATE_REFRESHING) {  
  96.                 mArrowImageView.clearAnimation();  
  97.             }  
  98.             mHintTextView.setText(R.string.xlistview_header_hint_normal);  
  99.             break;  
  100.         case STATE_READY:  
  101.             if (mState != STATE_READY) {  
  102.                 mArrowImageView.clearAnimation();  
  103.                 mArrowImageView.startAnimation(mRotateUpAnim);  
  104.                 mHintTextView.setText(R.string.xlistview_header_hint_ready);  
  105.             }  
  106.             break;  
  107.         case STATE_REFRESHING:  
  108.             mHintTextView.setText(R.string.xlistview_header_hint_loading);  
  109.             break;  
  110.         default:  
  111.         }  
  112.   
  113.         mState = state;  
  114.     }  
  115.   
  116.     public void setVisiableHeight(int height) {  
  117.         if (height < 0)  
  118.             height = 0;  
  119.         LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) mContainer  
  120.                 .getLayoutParams();  
  121.         lp.height = height;  
  122.         mContainer.setLayoutParams(lp);  
  123.     }  
  124.   
  125.     public int getVisiableHeight() {  
  126.         return mContainer.getHeight();  
  127.     }  
  128.   
  129. }  

XListView底部:XListViewFooter

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. /** 
  2.  * @file XFooterView.java 
  3.  * @create Mar 31, 2012 9:33:43 PM 
  4.  * @author Maxwin 
  5.  * @description XListView's footer 
  6.  */  
  7. package me.maxwin.view;  
  8.   
  9. import me.maxwin.R;  
  10. import android.content.Context;  
  11. import android.util.AttributeSet;  
  12. import android.view.LayoutInflater;  
  13. import android.view.View;  
  14. import android.widget.LinearLayout;  
  15. import android.widget.TextView;  
  16.   
  17. public class XListViewFooter extends LinearLayout {  
  18.     public final static int STATE_NORMAL = 0;  
  19.     public final static int STATE_READY = 1;  
  20.     public final static int STATE_LOADING = 2;  
  21.   
  22.     private Context mContext;  
  23.   
  24.     private View mContentView;  
  25.     private View mProgressBar;  
  26.     private TextView mHintView;  
  27.   
  28.     public XListViewFooter(Context context) {  
  29.         super(context);  
  30.         initView(context);  
  31.     }  
  32.   
  33.     public XListViewFooter(Context context, AttributeSet attrs) {  
  34.         super(context, attrs);  
  35.         initView(context);  
  36.     }  
  37.   
  38.     public void setState(int state) {  
  39.         mHintView.setVisibility(View.INVISIBLE);  
  40.         mProgressBar.setVisibility(View.INVISIBLE);  
  41.         mHintView.setVisibility(View.INVISIBLE);  
  42.         if (state == STATE_READY) {  
  43.             mHintView.setVisibility(View.VISIBLE);  
  44.             mHintView.setText(R.string.xlistview_footer_hint_ready);  
  45.         } else if (state == STATE_LOADING) {  
  46.             mProgressBar.setVisibility(View.VISIBLE);  
  47.         } else {  
  48.             mHintView.setVisibility(View.VISIBLE);  
  49.             mHintView.setText(R.string.xlistview_footer_hint_normal);  
  50.         }  
  51.     }  
  52.   
  53.     public void setBottomMargin(int height) {  
  54.         if (height < 0)  
  55.             return;  
  56.         LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) mContentView  
  57.                 .getLayoutParams();  
  58.         lp.bottomMargin = height;  
  59.         mContentView.setLayoutParams(lp);  
  60.     }  
  61.   
  62.     public int getBottomMargin() {  
  63.         LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) mContentView  
  64.                 .getLayoutParams();  
  65.         return lp.bottomMargin;  
  66.     }  
  67.   
  68.     /** 
  69.      * normal status 
  70.      */  
  71.     public void normal() {  
  72.         mHintView.setVisibility(View.VISIBLE);  
  73.         mProgressBar.setVisibility(View.GONE);  
  74.     }  
  75.   
  76.     /** 
  77.      * loading status 
  78.      */  
  79.     public void loading() {  
  80.         mHintView.setVisibility(View.GONE);  
  81.         mProgressBar.setVisibility(View.VISIBLE);  
  82.     }  
  83.   
  84.     /** 
  85.      * hide footer when disable pull load more 
  86.      */  
  87.     public void hide() {  
  88.         LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) mContentView  
  89.                 .getLayoutParams();  
  90.         lp.height = 0;  
  91.         mContentView.setLayoutParams(lp);  
  92.     }  
  93.   
  94.     /** 
  95.      * show footer 
  96.      */  
  97.     public void show() {  
  98.         LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) mContentView  
  99.                 .getLayoutParams();  
  100.         lp.height = LayoutParams.WRAP_CONTENT;  
  101.         mContentView.setLayoutParams(lp);  
  102.     }  
  103.   
  104.     private void initView(Context context) {  
  105.         mContext = context;  
  106.         LinearLayout moreView = (LinearLayout) LayoutInflater.from(mContext)  
  107.                 .inflate(R.layout.xlistview_footer, null);  
  108.         addView(moreView);  
  109.         moreView.setLayoutParams(new LinearLayout.LayoutParams(  
  110.                 LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));  
  111.   
  112.         mContentView = moreView.findViewById(R.id.xlistview_footer_content);  
  113.         mProgressBar = moreView.findViewById(R.id.xlistview_footer_progressbar);  
  114.         mHintView = (TextView) moreView  
  115.                 .findViewById(R.id.xlistview_footer_hint_textview);  
  116.     }  
  117.   
  118. }  


布局xml文件:

测试activity布局main:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="fill_parent"  
  4.     android:layout_height="fill_parent"  
  5.     android:background="#f0f0f0"  
  6.     android:orientation="vertical" >  
  7.   
  8.     <TextView  
  9.         android:layout_width="fill_parent"  
  10.         android:layout_height="wrap_content"  
  11.         android:text="@string/hello" />  
  12.   
  13.     <me.maxwin.view.XListView  
  14.         android:id="@+id/xListView"  
  15.         android:layout_width="fill_parent"  
  16.         android:layout_height="fill_parent"  
  17.         android:cacheColorHint="#00000000" >  
  18.     </me.maxwin.view.XListView>  
  19.   
  20. </LinearLayout>  

ListView每一行的布局list_item:

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <TextView xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:id="@+id/list_item_textview"  
  4.     android:layout_width="fill_parent"  
  5.     android:layout_height="fill_parent"  
  6.     android:padding="5dp"  
  7.     android:textColor="#000"  
  8.     android:textSize="16sp" >  
  9. </TextView>  

xlistview_footer.xml:

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="fill_parent"  
  4.     android:layout_height="wrap_content" >  
  5.   
  6.     <RelativeLayout  
  7.         android:id="@+id/xlistview_footer_content"  
  8.         android:layout_width="fill_parent"  
  9.         android:layout_height="wrap_content"  
  10.         android:padding="10dp" >  
  11.   
  12.         <ProgressBar  
  13.             android:id="@+id/xlistview_footer_progressbar"  
  14.             android:layout_width="wrap_content"  
  15.             android:layout_height="wrap_content"  
  16.             android:layout_centerInParent="true"  
  17.             android:visibility="invisible" />  
  18.   
  19.         <TextView  
  20.             android:id="@+id/xlistview_footer_hint_textview"  
  21.             android:layout_width="wrap_content"  
  22.             android:layout_height="wrap_content"  
  23.             android:layout_centerInParent="true"  
  24.             android:text="@string/xlistview_footer_hint_normal" />  
  25.     </RelativeLayout>  
  26.   
  27. </LinearLayout>  

xlistview_header.xml:

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="fill_parent"  
  4.     android:layout_height="wrap_content"  
  5.     android:gravity="bottom" >  
  6.   
  7.     <RelativeLayout  
  8.         android:id="@+id/xlistview_header_content"  
  9.         android:layout_width="fill_parent"  
  10.         android:layout_height="60dp" >  
  11.   
  12.         <LinearLayout  
  13.             android:id="@+id/xlistview_header_text"  
  14.             android:layout_width="wrap_content"  
  15.             android:layout_height="wrap_content"  
  16.             android:layout_centerInParent="true"  
  17.             android:gravity="center"  
  18.             android:orientation="vertical" >  
  19.   
  20.             <TextView  
  21.                 android:id="@+id/xlistview_header_hint_textview"  
  22.                 android:layout_width="wrap_content"  
  23.                 android:layout_height="wrap_content"  
  24.                 android:text="@string/xlistview_header_hint_normal" />  
  25.   
  26.             <LinearLayout  
  27.                 android:layout_width="wrap_content"  
  28.                 android:layout_height="wrap_content"  
  29.                 android:layout_marginTop="3dp" >  
  30.   
  31.                 <TextView  
  32.                     android:layout_width="wrap_content"  
  33.                     android:layout_height="wrap_content"  
  34.                     android:text="@string/xlistview_header_last_time"  
  35.                     android:textSize="12sp" />  
  36.   
  37.                 <TextView  
  38.                     android:id="@+id/xlistview_header_time"  
  39.                     android:layout_width="wrap_content"  
  40.                     android:layout_height="wrap_content"  
  41.                     android:textSize="12sp" />  
  42.             </LinearLayout>  
  43.         </LinearLayout>  
  44.   
  45.         <ImageView  
  46.             android:id="@+id/xlistview_header_arrow"  
  47.             android:layout_width="wrap_content"  
  48.             android:layout_height="wrap_content"  
  49.             android:layout_alignLeft="@id/xlistview_header_text"  
  50.             android:layout_centerVertical="true"  
  51.             android:layout_marginLeft="-35dp"  
  52.             android:src="@drawable/xlistview_arrow" />  
  53.   
  54.         <ProgressBar  
  55.             android:id="@+id/xlistview_header_progressbar"  
  56.             android:layout_width="30dp"  
  57.             android:layout_height="30dp"  
  58.             android:layout_alignLeft="@id/xlistview_header_text"  
  59.             android:layout_centerVertical="true"  
  60.             android:layout_marginLeft="-40dp"  
  61.             android:visibility="invisible" />  
  62.     </RelativeLayout>  
  63.   
  64. </LinearLayout>  

strings.xml:

[html]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <resources>  
  3.   
  4.     <string name="hello">Hello World, XListViewActivity!</string>  
  5.     <string name="app_name">XListView</string>  
  6.     <string name="xlistview_header_hint_normal">下拉刷新</string>  
  7.     <string name="xlistview_header_hint_ready">松开刷新数据</string>  
  8.     <string name="xlistview_header_hint_loading">正在加载...</string>  
  9.     <string name="xlistview_header_last_time">上次更新时间:</string>  
  10.     <string name="xlistview_footer_hint_normal">查看更多</string>  
  11.     <string name="xlistview_footer_hint_ready">松开载入更多</string>  
  12.   
  13. </resources>  


图片资源:





 





 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值