在项目中有这样需求要对ListView或ScrollView或RecyclerView滚动进行监听,来做一些处理,下面来看对应实现

一:Listview上下滑动监听

通过实现AbsListView.OnScrollListener接口onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount)实现(通过判断firstItem与前一次的差值比较)

下面是对接口封装处理

abstract class AbsListViewScrollDetector implements AbsListView.OnScrollListener {
private int mLastScrollY;
private int mPreviousFirstVisibleItem;
private AbsListView mListView;
private int mScrollThreshold; abstract void onScrollUp(); abstract void onScrollDown(); @Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
} @Override
public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {
if(totalItemCount == 0) return;
if (isSameRow(firstVisibleItem)) {
int newScrollY = getTopItemScrollY();
boolean isSignificantDelta = Math.abs(mLastScrollY - newScrollY) > mScrollThreshold;
if (isSignificantDelta) {
if (mLastScrollY > newScrollY) {
onScrollUp();
} else {
onScrollDown();
}
}
mLastScrollY = newScrollY;
} else {
if (firstVisibleItem > mPreviousFirstVisibleItem) {
onScrollUp();
} else {
onScrollDown();
} mLastScrollY = getTopItemScrollY();
mPreviousFirstVisibleItem = firstVisibleItem;
}
} public void setScrollThreshold(int scrollThreshold) {
mScrollThreshold = scrollThreshold;
} public void setListView(AbsListView listView) {
mListView = listView;
} private boolean isSameRow(int firstVisibleItem) {
return firstVisibleItem == mPreviousFirstVisibleItem;
} private int getTopItemScrollY() {
if (mListView == null || mListView.getChildAt(0) == null) return 0;
View topChild = mListView.getChildAt(0);
return topChild.getTop();
}
}

这里分为两种情况处理:

1,比较两次firstItem差值进行判断 ,这种情况比较容易考虑到,还有另外一种情况2

2,如果当滑动距离较小时(或者itemView高度较大)为一个ItemView,需要判断Itemview距离顶部距离判断进行比较处理

二:ScrollView滚动上下滚动监听

ScrollView并没有提供像ListViewt那样监听器,那如何实现呢?答案就是继承ScrollView 重新onScrollChanged方法判断,并提供监听回调

具体实现:

public class ObservableScrollView extends ScrollView {

    public interface OnScrollChangedListener {
void onScrollChanged(ScrollView who, int l, int t, int oldl, int oldt);
} private OnScrollChangedListener mOnScrollChangedListener; public ObservableScrollView(Context context) {
super(context);
} public ObservableScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
} public ObservableScrollView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
} @Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
super.onScrollChanged(l, t, oldl, oldt);
if (mOnScrollChangedListener != null) {
mOnScrollChangedListener.onScrollChanged(this, l, t, oldl, oldt);
}
} public void setOnScrollChangedListener(OnScrollChangedListener listener) {
mOnScrollChangedListener = listener;
}
}

即当我们使用ScollView时,使用ObservableScrollView替换即可,这里需要注意的是onScrollChanged方法并不是ScrollView独有定义的,SrollView继承FrameLayout

FrameLayout继承ViewGroup,也不在ViewGroup,FrameLayout,而是来源于View基类,源码说明如下:

/**
* This is called in response to an internal scroll in this view (i.e., the
* view scrolled its own contents). This is typically as a result of
* {@link #scrollBy(int, int)} or {@link #scrollTo(int, int)} having been
* called.
*
* @param l Current horizontal scroll origin.
* @param t Current vertical scroll origin.
* @param oldl Previous horizontal scroll origin.
* @param oldt Previous vertical scroll origin.
*/
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
if (AccessibilityManager.getInstance(mContext).isEnabled()) {
postSendViewScrolledAccessibilityEventCallback();
} mBackgroundSizeChanged = true; final AttachInfo ai = mAttachInfo;
if (ai != null) {
ai.mViewScrollChanged = true;
} if (mListenerInfo != null && mListenerInfo.mOnScrollChangeListener != null) {
mListenerInfo.mOnScrollChangeListener.onScrollChange(this, l, t, oldl, oldt);
}
}

即当调用SrollBy(),或ScrollTo()是调用,而ScrollView内部就是调用这两方法,所有可以通过重写此方法实现

下面实现是监听实现:

abstract class ScrollViewScrollDetector implements ObservableScrollView.OnScrollChangedListener {
private int mLastScrollY;
private int mScrollThreshold; abstract void onScrollUp(); abstract void onScrollDown(); @Override
public void onScrollChanged(ScrollView who, int l, int t, int oldl, int oldt) {
boolean isSignificantDelta = Math.abs(t - mLastScrollY) > mScrollThreshold;
if (isSignificantDelta) {
if (t > mLastScrollY) {
onScrollUp();
} else {
onScrollDown();
}
}
mLastScrollY = t;
} public void setScrollThreshold(int scrollThreshold) {
mScrollThreshold = scrollThreshold;
}
}

三:RecyclerView实现滚动方向判断

比较简单,因为系统以提供对应接口RecyclerView.OnScrollListener ,滚动dx,dy已给出

实现如下:

abstract class RecyclerViewScrollDetector extends RecyclerView.OnScrollListener {
private int mScrollThreshold; abstract void onScrollUp(); abstract void onScrollDown(); @Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
boolean isSignificantDelta = Math.abs(dy) > mScrollThreshold;
if (isSignificantDelta) {
if (dy > 0) {
onScrollUp();
} else {
onScrollDown();
}
}
} public void setScrollThreshold(int scrollThreshold) {
mScrollThreshold = scrollThreshold;
}
}

说明,mScrollThreshold的大小这里设置4dp,可以根据具体环境进行调整。

ListView,ScrollView,RecyclerView上下滑动监听的更多相关文章

  1. Listview的OnScrollListener的滑动监听实现分页加载

    //---------------主布局文件---------------------------- <ListView android:layout_width="fill_pare ...

  2. Android 自定义ScrollView的滑动监听事件

    项目结构: 1.LazyScrollView类(自定义ScrollView) package android.zhh.com.myapplicationscrollview; /** * Create ...

  3. Android RecyclerView滑动监听,判断是否滑动到了最后一个item

    项目中的需求,RecyclerView横向滑动列表,要有加载更多的功能,给RecyclerView设置一个滑动监听,在onScrolled方法中判断一下滑动方向,然后在onScrollStateCha ...

  4. 使用swipecard实现卡片视图左右滑动监听以及点击监听

     前言: 大家好,今天给大家介绍安卓一种特别实用有很酷炫的组件swipecard,当然这并不是安卓爸爸创造的,这是国内的一个我认为是大牛的一个人随便写着玩儿搞出来了,我看了他的代码介绍已经很清晰了,但 ...

  5. 移动端H5页面惯性滑动监听

    移动端H5页面惯性滑动监听 在移动端,当你快速滑动有滚动条的页面时,当你手指离开屏幕时,滚动条并不会立即停止,而是会随着"惯性"继续滑动一段距离. 在做项目的过程中,需要监听惯性滑 ...

  6. ScrollView滑动到底部或顶部监听,ScrollView滑动到底部或顶部再继续滑动监听;

    ScrollView滑动到底部或顶部后,再继续滑动达到一定距离的监听: ScrollView滑动到底部或顶部的监听: /** * 监听ScrollView滚动到顶部或者底部做相关事件拦截 */ pub ...

  7. ListView添加item的事件监听

    1. 点击事件(OnItemClickListener) onItemClick(AdapterView<?> parent, View view, int position, long ...

  8. ionic2+Angular ionScroll页面滑动监听

    第一:需要在组件中引入相关模块: 第二:如果只是监听页面滑动,只需要标注@ViewChild(Content) content: Content;就可以了. 附加:如果要监听页面的某个元素,并对其进行 ...

  9. JavaScript之屏幕上下左右滑动监听

    前言 存在这么一个需求,根据用户在屏幕不同的滑动方向(上.下.左.右),使用js脚本判断出不同的滑动行为,更新网页为不同的界面. 源码 参考了博文[1]的源码,但由于存在一些漏洞,比如:上下滑动事件监 ...

  10. swiper 使用参考 禁止手动滑动 监听事件

    最外层容器加类名  swiper-no-swiping 监听切换事件 onTransitionEnd: function(swiper){ console.log('过渡结束'); }

随机推荐

  1. RIDE,如何指定report,log,output的存放位置

    创建测试用例,执行后,report.html,log.html,output.txt 会默认存放到 C:\Users\你的用户名\AppData\Local\Temp下, 例如我的存放在 如果要指定存 ...

  2. 微信小程序tabBar不显示的问题

    刚刚入门 随便试吧了几个小功能.在用到tabBar时,在未出现代码错误的情况下,tabBar不显示 后来改了改发现是打开的首页并没有包含在tabBar列表里.

  3. 【Direct3D 12】什么是Direct3D 12

    什么是DirectX? Microsoft DirectX是一套图形API,可以用来创建游戏和高性能的图形应用.DirectX支持2D和3D图形. 什么是Direct3D 12? Direct3D是D ...

  4. WSL2安装nvm并配置npm镜像源

    1.下载安装脚本并执行 curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash 2.关闭命令行后 ...

  5. vue2 项目引入Fontawesome

    官网: https://fontawesome.com/ 1.安装 `` `powershell npm i --save @fortawesome/fontawesome-svg-core Usin ...

  6. 基于Spring AOP切面实现请求入参出参加解密

    1.Mavne导入加密解密所需的依赖 <dependency> <groupId>org.apache.commons</groupId> <artifact ...

  7. 带有FIFO硬件缓存的串口

    目录 51单片机的串口并没有配置FIFO硬件,故收发数据时只能一字节一字节地收发.最近接触了FIFO(先进先出)的硬件缓存,这样串口的配置就更多了一个维度. 以CH58x系列单片机为例,在CH583的 ...

  8. 超级详细的Vue安装与配置教程

    原文: https://www.jb51.net/article/251371.htm 超级详细的Vue安装与配置教程   Vue web前端三大主流框架之一,是一套用于构建用户界面的渐进式框架,下面 ...

  9. 设计模式,mvc,mvp,mvvm

    mvc model模型-视图view-控制器controller 视图可以直接访问模型,所以视图里面包括模型信息,mvc关注的是模型不变,所以在mvc中,模型不依赖视图,但是view是依赖model的 ...

  10. apollo兼容mysql的时候报错Table 'apolloportaldb.hibernate_sequence' doesn't exist

    解决方案: 配置文件里加: spring.jpa.properties.hibernate.hbm2ddl.auto=update