ViewPager2两层嵌套滑动

969 阅读1分钟

ViewPager2嵌套滑动

ViewPager2的滑动问题,可以看作是RecyclerView嵌套滑动的问题,只是无法用继承的方法去解决。

前置知识:RecyclerView不会拦截DOWN/UP事件。

解决办法:给里层的ViewPager2套上一层ViewGroup。

在ViewGroup去处理事件。

接收到DOWN事件后,请求之后的事件的也不要拦截。

原因:若存在子view消耗掉DOWN事件,那么之后的事件父容器也可以拦截,所以在DOWN事件中请求RecyclerView不要拦截之后的事件

requestDisallowInterceptTouchEvent

由于up和canel事件会取消这个请求标记,所以每一次DOWN事都要设置一下。

注意,这个给里层的ViewPager2套上的一层ViewGroup的大小不要超过允许嵌套滑动的范围。

直接用这个套上就可以了

/**
 * com.fhj.mymusic.customview
 */
public class ViewPager2FrameLayoutHost extends FrameLayout {


    public ViewPager2FrameLayoutHost(@NonNull Context context) {
        this(context, null);
    }

    public ViewPager2FrameLayoutHost(@NonNull Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public ViewPager2FrameLayoutHost(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        this(context, attrs, defStyleAttr, 0);
    }

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

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        handleInterceptTouchEvent(ev);
        return super.onInterceptTouchEvent(ev);
    }

    private void handleInterceptTouchEvent(MotionEvent e) {
        switch (e.getActionMasked()) {
            case MotionEvent.ACTION_DOWN: {
                ViewGroup viewPager2 = findViewPager2();
                if(viewPager2!=null)
                {
//                    只在Down中请求就可以
                    viewPager2.requestDisallowInterceptTouchEvent(true);
                }
                break;
            }
            case MotionEvent.ACTION_MOVE: {

            }
        }
    }

    private ViewPager2 findViewPager2()
    {
        int count = getChildCount();
        for (int i = 0; i < count; i++) {
            View child  = getChildAt(i);
            if(child instanceof ViewPager2)
            {
                return (ViewPager2)child;
            }
        }
        return null;
    }

}