Android Xlistview的源码浅度分析 监听ListView上下滑动 以及是否到顶和底部

2014年10月11日 7点热度 0条评论 来源: Tamic大白

  

  如转载 请注明出处 http://blog.csdn.net/sk719887916

   比如我们很多项目中会用到listview 并且要对listview滑动方向进行判断 也有需要的到listview是否是已滑到顶部和底部。这种需求一般是比如我们下滑listiew是时候影藏一个顶部的标题控件 或者展现一个顶部的提示控件,比如百家姓,电话本,就是要展现当前的首字母在屏幕中央 ,还有很多比如贴吧的app 我们对评论滑动的时候就得要去隐藏或者收缩顶部的楼主贴 这样对于小屏幕手机是一种不错的选择。现在让我们看看到底怎么去实现这个小功能。

  通过看xlixtview源码他就是在监听adapter的位置 从而进行对应的刷新和加载更多的回调函数

  先看看XLIstview 的关键代码

@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();
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();
} else if (getLastVisiblePosition() == mTotalItemCount - 1) {
// invoke load more.
if (mEnablePullLoad
&& mFooterView.getBottomMargin() > PULL_LOAD_MORE_DELTA
&& !mPullLoading) {
startLoadMore();
}
resetFooterHeight();
}
break;
}
return super.onTouchEvent(ev);
}

看完你也就明白了 他就是在看是不是Position的位置 接下来言归正传 看看我们今天解决的问题

 先找到xml定义好的listview 然后就在当前的activty进行初始化 

  之后谷歌给我们定义了一个回调监听事件 OnScrollListener 这个方法同样适用于gridview


listView.setOnScrollListener(new OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}


@Override
public void onScroll(AbsListView view, int firstVisibleItem,
int visibleItemCount, int totalItemCount) {
if (firstVisibleItem == 0) {
/* Log.e("log", "滑到顶部"); */
}
if (visibleItemCount -firstVisibleItem== 4) {
sets = GApplication.getInstance().shareUtil
.getMyCareCityLabel();
if (sets == null) {


Log.e("log", "中间");
/* handler.sendEmptyMessage(5);*/
}
      
}


if (visibleItemCount + firstVisibleItem == totalItemCount) {
/* Log.e("log", "滑到底部"); */


}
}
});

  是不是很简单呢 有了这个东西 你也可以自己去写个底部加载更多和顶部的刷新 只不过目前开源的框架是对一些ui进行封装和对onTouch事件处理 因为它比上面的方法更加精确 因为当我们滑到底部时 不知道item高度高 那么你没看完最底部的item 它就给你加载更多事件了  所以用此我们可以解决文章开头说的一些小功能 你可以在对应的位置进行一些事件操作和提示信息 一般的新手指导当你滑动listview一半时后就可以做也一些提示 

   接下来 这个事件完全不能满足我们更加高级的UI效果 有时候我们还要知道listview是否在滑动 是否滑动停止了 向哪个方向滑动 那么问题来了 你如果判断onTouch 那么你就必须获取点击的屏幕坐标和松开时候的坐标 这样也可以实现以上功能 但是比较费时间 现在给大家介绍下一个新的东东 其实还是上面的OnScrollListener 


    我们可以去实现此接口 重写他的方法

  @Override
public void onScroll(AbsListView arg0, int arg1, int arg2, int arg3) {


}


@Override
public void onScrollStateChanged(AbsListView abview, int scrollState) {


switch (scrollState) {


// 滚动之前,手还在屏幕上 记录滚动前的下标
case OnXScrollListener.SCROLL_STATE_TOUCH_SCROLL:


lvIndext = abview.getLastVisiblePosition();
break;


// 滚动停止
case OnXScrollListener.SCROLL_STATE_IDLE:


int scrolled = abview.getLastVisiblePosition();


if (scrolled > lvIndext) {

if (tv_content.getMaxLines() != 50 && oldlines != 1) {
lienar_questiondetails.startAnimation(mShowAction);
tv_content.setMaxLines(50);
   //比如这里我们可以是伸开(显示)一个文本控件
}


}
// 向上滚动了
else if (scrolled < lvIndext) {


if (tv_content.getMaxLines() != 1 && oldlines != 1) {
lienar_questiondetails.startAnimation(mHiddenAction);
tv_content.setMaxLines(1);
 //比如这就是收缩(隐藏)一个文本控件

}


}
break;
}
}


@Override
public void onXScrolling(View view) {


}


   可以看到 里面有正在滑动 位置改变 滑动停止事件 那么我们就可以在对应方法里面进行对应需求操作  是不是很简单呢  如有不确切地方 还需要大家的矫正。 

   

    原文作者:Tamic大白
    原文地址: https://blog.csdn.net/sk719887916/article/details/39989857
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系管理员进行删除。