在项目中有这样需求要对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. 时间序列分析2.X AR与MA

    ARMA与ARIMA模型 对平稳时间序列和非平稳时间序列,分别假定适当的 ARMA 模型和 ARIMA 模型 对非平稳时间序列建立 ARIMA 模型,实际上是通过先用适当的变换将非平稳序列转化为平稳序 ...

  2. 2022-05-23内部群每日三题-清辉PMP

    1.在项目执行过程中,职能经理识别到有关外包团队的新内部风险,职能经理要求项目经理提供一个不会对项目产生负面影响的快速解决方案.项目经理应该怎么做? A.制定风险分解结构(RBS) B.根据影响的严重 ...

  3. dropbear 2019.78 Installing to target......Running build_buildroot failed!

    使能buildroot的环境变量 source envsetup.sh ;rv1126一般选择90make dropbear-dircleanmake dropbear./build.sh rootf ...

  4. python接口测试常见问题。

    一.入参问题 1.body字段类型 1.如果数据是从excel提取的那么中文数据会提示错误. 解决方法# media_value['body'] = media_value['body'].encod ...

  5. [746] Interlude Update 3

    [746] Interlude Update 3 Client 00 SendProtocolVersion 01 MoveBackwardToLocation 02 Say 03 RequestEn ...

  6. pythonanywhere 部署 webpy

    ======================= start ===================== 1. 在pythonanywhere中Add a new web app. 2. 新开一个Bas ...

  7. 【GROMACS】分子动力学模拟①——环境搭建

    系统环境 Win11 22H2 企业版 开启虚拟化.window subsystem for liunx等虚拟机相关的功能 应用商店中安装WSL2 安装步骤 打开Ubuntu,输入sudo apt f ...

  8. signalR从外部服务中推送消息和全局参数的设置

    在前面的章节中,我们都是采用两方模式, 客户端 <-> 服务端,也就是说在这种情况下如果有第三方如果有通知的没有办法插足的,下面解决方案 1:和之前的代码一样,在index页面加一个客户端 ...

  9. Linux学习 --- 系统网络配置

    前言 : 如果一台计算机想接入互联网,必须配置好IP地址,子网掩码,网关,DNS服务器.在Linux系统中,这些信息都可以修改对应的配置文件来进行配置.临时配置一下网络可以使用一些简单的命令来进行配置 ...

  10. 001. html篇之《基础内容》

    html基础内容 1. 什么是html Hypertext Markup Language 超文本标记语言 2. 基本结构 <!DOCTYPE html> <!-- 此为html5的 ...