Android 如何 ListView 判断滚动到最顶部或者底部

来源:互联网 发布:淘宝网产品销量排名 编辑:程序博客网 时间:2024/05/22 10:47

转自:http://blog.csdn.net/wangbaochu/article/details/50630371

如何判断 ListView 滑动到顶部和底部?网上一搜,最多的答案都是这样的:

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1.  mListView.setOnScrollListener(new AbsListView.OnScrollListener() {  
  2.     @Override  
  3.     public void onScrollStateChanged(AbsListView view, int scrollState) {  
  4.     }  
  5.   
  6.   
  7.     @Override  
  8.     public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {  
  9.         if (firstVisibleItem == 0) {  
  10.             Log.d("ListView""##### 滚动到顶部 #####");  
  11.         } else if ((firstVisibleItem + visibleItemCount) == totalItemCount) {  
  12.             Log.d("ListView""##### 滚动到底部 ######");  
  13.         }  
  14.     }  
  15. });  

这一段代码并不能够精确地判断 ListView 是否到达最顶部或者最底部。因为只要ListView中第一个item出现在屏幕上端,即使只出现一部分,firstVisibleItem 的值也依然为0, onScroll()回调就会发生; 同样ListView 的最后一个 item 即使只显示一部分,((firstVisibleItem + visibleItemCount) == totalItemCount) 的值也是等于totalItemCount。

那么倒底如何精确判断 ListView 是否滚动到顶部或者底部?

一、首先想到的是 ListView.onScrollChanged()

这个函数是protected,直接引用不到,但是可以继承ListView类,然后重写这个函数:

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. @Override  
  2. protected void onScrollChanged(int l, int t, int oldl, int oldt) {  
  3.     super.onScrollChanged(l, t, oldl, oldt);  
  4.       
  5.     Log.d("ListView", String.format("onScrollChanged: l = %d, t = %d, oldl = %d, oldt = %d, ScrollY = %d", l, t, oldl, oldt, this.getScrollY()));  
  6.     if (t == 0) {  
  7.         Log.d("ListView""onScrollChanged <----滚动到顶部----->");  
  8.     }  
  9. }  
经过测试发现:ListView的 onScrollChanged() 以及 getScrollX() 和 getScrollY() 总是返回0,根本不起作用。但是对于Android ScrollView 这三个函数都是有效的,为什么ListView就不起作用呢?尼玛,绝对没有想到Android 这么坑爹!

可以参看 http://stackoverflow.com/questions/24856063/listview-onscrollchanged-always-returns-0

二、只能继续改进 ListView.setOnScrollListener() 

1. 改进是否滚动到顶部:增加判断第一个 item 距离 ListView 顶部的距离是否为 0

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. if (firstVisibleItem == 0) {  
  2.     View firstVisibleItemView = mListView.getChildAt(0);  
  3.     if (firstVisibleItemView != null && firstVisibleItemView.getTop() == 0) {  
  4.         Log.d("ListView""##### 滚动到顶部 ######");  
  5.     }  
  6. }  
2. 改进是否滚动到底部:增加判断当前屏幕中可见的最后一个 item 的底端距离 ListView 的顶端是否为 ListView 的高度:

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. if ((firstVisibleItem + visibleItemCount) == totalItemCount) {  
  2.     View lastVisibleItemView = mListView.getChildAt(mListView.getChildCount() - 1);  
  3.     if (lastVisibleItemView != null && lastVisibleItemView.getBottom() == mListView.getHeight()) {  
  4.         Log.d("ListView""##### 滚动到底部 ######");         
  5.     }  
  6. }  
全部完整代码如下:

[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. mListView.setOnScrollListener(new OnScrollListener() {  
  2.     @Override  
  3.     public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {  
  4.         if (firstVisibleItem == 0) {  
  5.             View firstVisibleItemView = mListView.getChildAt(0);  
  6.             if (firstVisibleItemView != null && firstVisibleItemView.getTop() == 0) {  
  7.                 Log.d("ListView""##### 滚动到顶部 #####");  
  8.             }  
  9.         } else if ((firstVisibleItem + visibleItemCount) == totalItemCount) {  
  10.             View lastVisibleItemView = mListView.getChildAt(mListView.getChildCount() - 1);  
  11.             if (lastVisibleItemView != null && lastVisibleItemView.getBottom() == mListView.getHeight()) {  
  12.                 Log.d("ListView""##### 滚动到底部 ######");         
  13.             }  
  14.         }  
  15.     }  
  16.   
  17.     @Override  
  18.     public void onScrollStateChanged(AbsListView view, int scrollState) {  
  19.         //do nothing  
  20.     }  
  21.       
  22. });  
经过测试发现:上述代码能够正确判断 ListView 是否滚动到顶部或者底部
阅读全文
0 0
原创粉丝点击