横向ViewPager2内部嵌套竖向的RecyclerView,在滑动RecyclerView的时候很容易触发外部ViewPager2的横向滑动

本文分析了ViewPager2与内部RecyclerView滑动冲突的原因,并提供了解决方案。通过重写RecyclerView的dispatchTouchEvent方法,在ACTION_MOVE事件中判断滑动方向,避免在上下滑动时拦截触摸事件,从而解决冲突。
摘要由CSDN通过智能技术生成

一 、原因

ViewPager2的内部实现是RecyclerView,当手势横向移动的距离大于touchSlop的时候,就会认定你有横向滑动的手势,进而驱动ViewPager2进行左右滑动

二、解决办法

重写内部嵌套的RecyclerView:

public class RecyclerViewInVP2 extends RecyclerView {

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

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

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

    private int startX, startY;

    @Override
    public boolean dispatchTouchEvent(MotionEvent ev) {
        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                startX = (int) ev.getX();
                startY = (int) ev.getY();
                getParent().requestDisallowInterceptTouchEvent(true);//告诉viewgroup不要去拦截我
                break;
            case MotionEvent.ACTION_MOVE:
                int endX = (int) ev.getX();
                int endY = (int) ev.getY();
                int disX = Math.abs(endX - startX);
                int disY = Math.abs(endY - startY);
                if (disX > disY) {
                    getParent().requestDisallowInterceptTouchEvent(false);
                } else {
                    getParent().requestDisallowInterceptTouchEvent(true);//下拉的时候是false
                }
                break;
            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                getParent().requestDisallowInterceptTouchEvent(true);
                break;
        }
        return super.dispatchTouchEvent(ev);
    }
}

从源码层面分析:

viewpager2+recyclerview/nestscrollview滑动冲突问题 - 掘金既然知道了是在action_move过程中是因为dx或dy大于了mTouchSlop,导致viewpager2中拦截了touch事件,所以我们有没有办法让上下滑动列表recyclerview的时候,不去拦截touch事件呢,答案就是通过上面的requestDisallowInt…https://juejin.cn/post/6886037403413250062

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
您可以按照以下步骤在ViewPager2中使用Fragment来实现RecyclerView的左右滑动: 1. 首先,确保您的项目中已经添加了ViewPager2的依赖项。在您的项目的 build.gradle 文件中的 dependencies 部分添加以下代码: ```groovy implementation 'androidx.viewpager2:viewpager2:1.0.0' ``` 2. 创建一个包含 RecyclerView 的 Fragment。您可以在该 Fragment 中设置 RecyclerView 的布局和数据适配器。 3. 创建一个继承自 FragmentStateAdapter 的适配器类。该适配器将负责管理 ViewPager2 中的 Fragment。 ```kotlin class ViewPagerAdapter(fragmentManager: FragmentManager, lifecycle: Lifecycle) : FragmentStateAdapter(fragmentManager, lifecycle) { private val fragmentList = mutableListOf<Fragment>() fun addFragment(fragment: Fragment) { fragmentList.add(fragment) } override fun getItemCount(): Int { return fragmentList.size } override fun createFragment(position: Int): Fragment { return fragmentList[position] } } ``` 4. 在您的 Activity 或 Fragment 中,初始化 ViewPager2 并设置适配器。 ```kotlin val viewPager2 = findViewById<ViewPager2>(R.id.viewPager2) val adapter = ViewPagerAdapter(supportFragmentManager, lifecycle) adapter.addFragment(YourFragment1()) adapter.addFragment(YourFragment2()) // 添加更多的 Fragment viewPager2.adapter = adapter ``` 5. 在 XML 布局文件中添加 ViewPager2。 ```xml <androidx.viewpager2.widget.ViewPager2 android:id="@+id/viewPager2" android:layout_width="match_parent" android:layout_height="match_parent" /> ``` 现在,您的 ViewPager2 中的 Fragment 将能够实现 RecyclerView 的左右滑动效果。您可以在 Fragment 中设置不同的布局和逻辑来显示不同的数据。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值