在项目开发的过程中,可能会遇到需要处理的 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);
}
}