嵌套 RecyclerView 的事件处理方法

在项目开发的过程中,可能会遇到需要处理的 RecyclerView 嵌套的复杂需求,这里提供一个比较简单的实现模板,假如在 RecyclerView 里嵌套了一个 RecyclerView,在里面能滑动的同时,也可以在滑动到顶/底的时候,拖动父 RecyclerView

java 复制代码
package com.atoto.module.main.ui.view;

import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.RecyclerView;


/**
 * 描述: 技能子项:处理 RecyclerView 嵌套滚动问题
 * 创建者: IT乐手
 * 日期: 2025/3/31
 */

public class SubRecyclerView extends RecyclerView {

    private float mLastY = 0f;

    public SubRecyclerView(@NonNull Context context) {
        super(context);
    }

    public SubRecyclerView(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public SubRecyclerView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @Override
    public boolean dispatchTouchEvent(MotionEvent e) {
        switch (e.getAction()) {
            case MotionEvent.ACTION_DOWN: {
                boolean canUpScroll = canScrollVertically(1); //能否向上滑动
                boolean canDownScroll = canScrollVertically(-1); //能否向下滑动
                if (canUpScroll || canDownScroll) {//可见,并且能滑动,请求父Rv不拦截事件
                    getParent().requestDisallowInterceptTouchEvent(true);
                    mLastY = e.getY();
                }
            }
            break;
            case MotionEvent.ACTION_MOVE: {
                float diff = mLastY - e.getY();
                mLastY = e.getY();
                if (diff >= 0) {//手指向上滑动
                    if (canScrollVertically(1)) {//子Rv未滑到底部,请求父Rv不拦截事件
                        getParent().requestDisallowInterceptTouchEvent(true);
                    } else {//子Rv滑到底部了,父Rv可以拦截事件                        
                        getParent().requestDisallowInterceptTouchEvent(false);
                    }
                } else {//手指向下滑动
                    if (canScrollVertically(-1)) {//子Rv未滑到顶部,请求父Rv不拦截事件
                        getParent().requestDisallowInterceptTouchEvent(true);
                    } else {//子Rv滑到顶部了,父Rv可以拦截事件                        
                        getParent().requestDisallowInterceptTouchEvent(false);
                    }
                }
            }
            break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL: {
                getParent().requestDisallowInterceptTouchEvent(false);
                mLastY = 0f;
            }
            break;
        }
        return super.dispatchTouchEvent(e);
    }
}
相关推荐
ideaout技术团队2 分钟前
android集成react native组件踩坑笔记(Activity局部展示RN的组件)
android·javascript·笔记·react native·react.js
shaominjin1231 小时前
单例模式:设计模式中的“独一无二“之道
android·单例模式·设计模式
千里马学框架1 小时前
windows系统上aosp15上winscope离线html如何使用?
android·windows·html·framework·安卓窗口系统·winscope
码住懒羊羊1 小时前
【C++】模板进阶 | 继承
android·java·c++
urkay-1 小时前
Android 线程详解
android·java·kotlin·iphone·androidx
aqi002 小时前
FFmpeg开发笔记(八十七)采用Kotlin的手机开源播放器VLC-Android
android·ffmpeg·音视频·流媒体
峥嵘life3 小时前
Android EDLA项目导入mainline包后蓝牙签名报错分析解决
android·gitee
灵猫小西3 小时前
Android耗时卡顿原因排查工具Profiler
android·profiler·耗时卡顿
gfdgd xi4 小时前
好消息:KMRE 安卓模拟器现可在Debian/GXDE使用
android·python·架构·bug·deepin·龙芯
La Pulga4 小时前
【STM32】FLASH闪存
android·c语言·javascript·stm32·单片机·嵌入式硬件·mcu