在项目中有这样需求要对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. 关于服务器上的XML

    服务器上的 XML XML 文件是类似 HTML 文件的纯文本文件. XML 能够通过标准的 Web 服务器轻松地存储和生成. 在服务器上存储 XML 文件 XML 文件在 Internet 服务器上 ...

  2. php的几种接值方式

    1.传单个参数 单个参数这种比较简单,例如 想像edit操作里面传递一个id值,如下写法__URL__/edit/id/1 http://localhost/index.php/user/edit/i ...

  3. 前端如何给bearer token传值

    Bearer token是一种常见的身份验证机制,通常用于Web API和其他Web服务.在前端中,Bearer token通常是通过HTTP头(HTTP header)发送的,具体来说是通过&quo ...

  4. npm发布和修改详细教程

    登录 登录npm账号(没有账号需要先前往npm注册 https://www.npmjs.com/) npm login npm notice Log in on https://registry.np ...

  5. web执行shell脚本

    转载请注明来源:https://www.cnblogs.com/Sherlock-L/p/15584456.html 缘起 去年写过一个shell脚本用来校验统计打点,工作使用.发现同事不太熟悉这块, ...

  6. elastalert部署和使用

    一.Elastalert简介 Elastalert是Yelp公司基于python开发的ELK日志告警插件,Elastalert通过查询Elasticsearch中的记录与定于的告警规则进行对比,判断是 ...

  7. Android使用volley发送带参数的post请求

    用参数方式可以解决E/Volley: [777] BasicNetwork.performRequest: Unexpected response code 500 for XXXXX 1.Strin ...

  8. PySide6之初级使用

    背景介绍pyside6提供了Qt6的Python侧API. 在GUI程序撰写方面, 笔者不太喜欢频繁的编译过程, 倾向于随时更改代码即时查看效果. 因此, 推荐在简单应用的情况下使用pyside6, ...

  9. 下载安装i5ting_toc

    全部都是以管理员身份运行powershell 1.打开powershell之后输入命令npm i i5ting_toc -g 这样就全局安装了 2.set-ExecutionPolicy Remote ...

  10. selenium执行下载多个文件操作,谷歌浏览器弹出"xxx想要下载多个文件"的处理方法

    背景:   使用selenium框架,批量下载多个目录的不同文件,而下载多个文件时,浏览器会弹出如下窗口 解决方案有2个:1.代码定位到元素并点击[允许].2.修改浏览器的设置,使其能够拥有自动下载的 ...