一般判断ListView方向的方法大致是:ListView设置滑动监听器:
listView.setOnScrollListener(new AbsListView.OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
}
@Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount{
//根据firstVisibleItem的在滑动前后的不同值,判断滑动方向。
}
});
但这样有一个问题,如果ListView只滑动一小段距离(不超过一个item的高度),firstVisibleItem是保持不变的啊!这样就判断不了是上滑还是下滑!所以这样做是有缺陷的!
但今天在使用一个控件时。偶然看了其源代码,发现了其中有对ListView方向更全面的判断方法,其实也很简单,代码如下:
import android.support.annotation.NonNull;
import android.view.View;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
abstract class AbsListViewScrollDetector implements OnScrollListener {
private int mLastScrollY; //第一个可视的item的顶部坐标
private int mPreviousFirstVisibleItem; //上一次滑动的第一个可视item的索引值
private AbsListView mListView;//列表控件,如ListView
/**
*滑动距离响应的临界值,这个值可根据需要自己指定
*只有只有滑动距离大于mScrollThreshold,才会响应滑动动作
*/
private int mScrollThreshold;
AbsListViewScrollDetector() {}
//当认为ListView向上滑动时会被调用,由子类去定义的。
abstract void onScrollUp();
//当认为ListView下滑动时会被调用,由子类去定义的。
abstract void onScrollDown();
public void onScrollStateChanged(AbsListView view, int scrollState) { }
//核心方法,该方法封装了滑动方向判断的逻辑,但ListView产生滑动之后,该方法会被调用。
//1.首先,判断滑动后第一个可视的item和滑动前是否同一个,如果是同一个,进入第2步,否则进入第3步
//2.则这次滑动距离小于一个Item的高度,比较第一个可视的item的顶部坐标在滑动前后的差值,就知道了滑动的距离
//3.这个好办,直接比较滑动前后firstVisibleItem的值就可以判断滑动方向了。
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount){
if(totalItemCount != 0) {
// 滑动距离:不超过一个item的高度
if(this.isSameRow(firstVisibleItem)) {
int newScrollY = this.getTopItemScrollY();
//判断滑动距离是否大于 mScrollThreshold
boolean isSignificantDelta = Math.abs(this.mLastScrollY - newScrollY) > this.mScrollThreshold;
if(isSignificantDelta) {
//对于第一个可视的item,根据其前后两次的顶部坐标判断滑动方向
if(this.mLastScrollY > newScrollY) {
this.onScrollUp();
} else {
this.onScrollDown();
}
}
this.mLastScrollY = newScrollY;
} else {//根据第一个可视Item的索引值不同,判断滑动方向
if(firstVisibleItem > this.mPreviousFirstVisibleItem) {
this.onScrollUp();
} else {
this.onScrollDown();
}
this.mLastScrollY = this.getTopItemScrollY();
this.mPreviousFirstVisibleItem = firstVisibleItem;
}
}
}
public void setScrollThreshold(int scrollThreshold) {
this.mScrollThreshold = scrollThreshold;
}
public void setListView(@NonNull AbsListView listView) {
this.mListView = listView;
}
private boolean isSameRow(int firstVisibleItem) {
return firstVisibleItem == this.mPreviousFirstVisibleItem;
}
private int getTopItemScrollY() {
if(this.mListView != null && this.mListView.getChildAt(0) != null) {
View topChild = this.mListView.getChildAt(0);
return topChild.getTop();
} else {
return 0;
}
}
}
----------------------------我是分给线-----------------------------------
多看别人造的轮子还是很用的!
对了,这个我看的是这个开源库的:com.melnykov:floatingactionbutton:1.3.0。
Android studio 上应该能找到。
博客内容介绍了如何更准确地判断ListView在Android中的滑动方向,指出仅依赖firstVisibleItem判断的缺陷,并分享了一个开源库com.melnykov:floatingactionbutton:1.3.0中的解决方案,强调学习他人代码的重要性。

1373

被折叠的 条评论
为什么被折叠?



