canScroll方法完美解决ViewPager内部控件滑动冲突问题

代码结构

1.最外层是一个ViewPager
2.ViewPager的每个item又是一个ExpandableListview
3.ExpandableListview的childItem是一个单行的ViewPager

问题描述

  • 滑动最底层的ViewPager时,很容易引起最外层的ViewPager滑动


    截图.png

解决思路

1.分析最外层ViewPager的onIntercepterTouchEvent方法的代码可以知道,在MotionEvent.ACTION_MOVE中会调用canScroll方法

 if (dx != 0 && !isGutterDrag(mLastMotionX, dx)
                        && canScroll(this, false, (int) dx, (int) x, (int) y)) {
                    // Nested view has scrollable area under this point. Let it be handled there.
                    mLastMotionX = x;
                    mLastMotionY = y;
                    mIsUnableToDrag = true;
                    return false;
                }

2.查看canScroll源码

 /**
     * Tests scrollability within child views of v given a delta of dx.
     *
     * @param v View to test for horizontal scrollability
     * @param checkV Whether the view v passed should itself be checked for scrollability (true),
     *               or just its children (false).
     * @param dx Delta scrolled in pixels
     * @param x X coordinate of the active touch point
     * @param y Y coordinate of the active touch point
     * @return true if child views of v can be scrolled by delta of dx.
     */
    protected boolean canScroll(View v, boolean checkV, int dx, int x, int y) {
        if (v instanceof ViewGroup) {
            final ViewGroup group = (ViewGroup) v;
            final int scrollX = v.getScrollX();
            final int scrollY = v.getScrollY();
            final int count = group.getChildCount();
            // Count backwards - let topmost views consume scroll distance first.
            for (int i = count - 1; i >= 0; i--) {
                // TODO: Add versioned support here for transformed views.
                // This will not work for transformed views in Honeycomb+
                final View child = group.getChildAt(i);
                if (x + scrollX >= child.getLeft() && x + scrollX < child.getRight()
                        && y + scrollY >= child.getTop() && y + scrollY < child.getBottom()
                        && canScroll(child, true, dx, x + scrollX - child.getLeft(),
                                y + scrollY - child.getTop())) {
                    return true;
                }
            }
        }

        return checkV && v.canScrollHorizontally(-dx);
    }

从参数说明中就很容易知道,如果子view可以滑动,返回为true

3.在自定义的最外层ViewPager中重写canScroll()方法

 public class HomeViewPager extends ViewPager {

    public HomeViewPager(Context context) {
        this(context, null);
    }

    public HomeViewPager(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected boolean canScroll(View v, boolean checkV, int dx, int x, int y) {
        if (v != this && (v instanceof ViewPager
                || v instanceof CartoonRecycleView
                || v instanceof SingleLineZoomScrollView)) {
            return true;
        } else if (v != this && v instanceof GridView) {
            return false;
        }
        return super.canScroll(v, checkV, dx, x, y);
    }
}

最底层的ViewPager我是放在SingleLineZommScrollView当中的,故当手指滑动在此控件范围中canScroll返回true,问题完美解决。

最后编辑于 :
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 180,563评论 25赞 708
  • 在Android开发中,如果是一些简单的布局,都很容易搞定,但是一旦涉及到复杂的页面,特别是为了兼容小屏手机而使用...
    闲庭阅读 3,690评论 0赞 16
  • 用两张图告诉你,为什么你的 App 会卡顿? - Android - 掘金 Cover 有什么料? 从这篇文章中你...
    hw1212阅读 14,607评论 2赞 59
  • 感恩去参加广州峰会的伙伴今转播现场情况到群里,让我们没去现场的伙伴可以同步看到,一起感受公司的大爱,今天广州...
    邢金峰阅读 186评论 0赞 0
  • 大家都说,朋友圈是一个向你的朋友显示自我行为和状态的一个展示平台,朋友圈就是一张行走的名片。那么这里是不是有一个误...
    琳娜911阅读 848评论 0赞 2

友情链接更多精彩内容