在前几天的开发项目中需要实现上拉刷新,下拉加载更多的功能,当然这些功能主要还是与网络请求分不开的。看到很多码友说xListView效果也不错,所以自己本身也进行了简单的研究,在网络请求方面使用了OKHttp,并且将两者封装用到项目中。
一:xListView
1:导入xListView
网上有很多的关于xListView的源码,可以去下载!总的来说都分为XListView(自定义的ListView,主体),XListViewHeader(头),XListViewFooter(脚)三个自定义的布局文件,XListViewHeader和XListViewFooter分别在XListView以addView的方式添加到listView中的。下面边贴代码,边解释:
加载头部:
public XListView(Context context) { super(context); 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); // init header view mHeaderView = new XListViewHeader(context); mHeaderViewContent = (RelativeLayout) mHeaderView .findViewById(R.id.xlistview_header_content); mHeaderTimeView = (TextView) mHeaderView .findViewById(R.id.xlistview_header_time); addHeaderView(mHeaderView); // init footer view mFooterView = new XListViewFooter(context); // init header height mHeaderView.getViewTreeObserver().addOnGlobalLayoutListener( new OnGlobalLayoutListener() { @Override public void onGlobalLayout() { mHeaderViewHeight = mHeaderViewContent.getHeight(); getViewTreeObserver() .removeGlobalOnLayoutListener(this); } }); }
加载脚:
由于用到了分页,因此使用了适配器adapter。而脚的加载就在调用适配器的时候加载的
@Override public void setAdapter(ListAdapter adapter) { // make sure XListViewFooter is the last footer view, and only add once. if (mIsFooterReady == false) { mIsFooterReady = true; addFooterView(mFooterView); } super.setAdapter(adapter); }当然,也是可以和头部一样在初始化的时候就直接add,但是在分页的过程中当数据太少满足不了一页的量的时候我们就没必要在显示脚,可能就是一个提示“加载完毕”,此时如果还将脚在初始化的时候就add,这样就不是很好控制,所以建议脚的加载要和数据量挂钩,此刻,我们在 xlistView中还抛出两个方法来显示和隐藏脚,如:
public void hideFooterView() { setPullLoadEnable(false); } public void showFooterView() { setPullLoadEnable(true); }
触摸监听(滑动监听):
方法onTouchEvent是listView中的一个重要的监听机制,其参数MotionEvent触控是android一个重要的人机交互模型,主要有以下的常量:
public static final int ACTION_DOWN= 0;
单点触摸动作
public static final int ACTION_UP= 1;
单点触摸离开动作
public static final int ACTION_MOVE= 2;触摸点移动动作
public static final int ACTION_CANCEL= 3;触摸动作取消
public static final int ACTION_OUTSIDE= 4;触摸动作超出边界
public static final int ACTION_POINTER_DOWN= 5;多点触摸动作
public static final int ACTION_POINTER_UP= 6;多点离开动作
具体代码
@Override public boolean onTouchEvent(MotionEvent ev) { if (mLastY == -1) { mLastY = ev.getRawY(); } switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: mLastY = ev.getRawY(); break; case MotionEvent.ACTION_MOVE: final float deltaY = ev.getRawY() - mLastY; mLastY = ev.getRawY(); System.out.println("数据监测:" + getFirstVisiblePosition() + "---->" + getLastVisiblePosition()); 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() == mTotalItemCount - 1 && (mFooterView.getBottomMargin() > 0 || deltaY < 0)) { // last item, already pulled up or want to pull up. updateFooterHeight(-deltaY / OFFSET_RADIO); } break; default: mLastY = -1; // reset if (getFirstVisiblePosition() == 0) { // invoke refresh if (mEnablePullRefresh && mHeaderView.getVisiableHeight() > mHeaderViewHeight) { mPullRefreshing = true; mHeaderView.setState(XListViewHeader.STATE_REFRESHING); if (mListViewListener != null) { mListViewListener.onRefresh(); } } resetHeaderHeight(); } if (getLastVisiblePosition() == mTotalItemCount - 1) { // invoke load more. if (mEnablePullLoad && mFooterView.getBottomMargin() > PULL_LOAD_MORE_DELTA) { startLoadMore(); } resetFooterHeight(); } break; } return super.onTouchEvent(ev); }
最后抛出一个接口,在activity中实现一下,重写相关方法
public interface IXListViewListener { public void onRefresh(); public void onLoadMore(); }