Android:嵌套ScrollViews和Horizo​​ntalScrollViews,拦截

Android: nested ScrollViews and HorizontalScrollViews, interception

我在 Android 中的 ScrollViews 内部使用 ScrollViews 时遇到问题。我知道这不是最佳做法,但我需要让它发挥作用。

public static void disableScrollOnParentHorizontalScrollView(View v) {  
    v.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            int action = event.getAction();
            switch (action) {
            case MotionEvent.ACTION_DOWN:
                requestDisallowInterceptTouchEventByDirection(v, true, HorizontalScrollView.class);
                break;
            case MotionEvent.ACTION_UP:
                requestDisallowInterceptTouchEventByDirection(v, false, HorizontalScrollView.class);
                break;
            }
            v.onTouchEvent(event);
            return true;
        }
    });
}

对于垂直滚动视图,我使用与上面相同的方法,并将 ScrollView.class 作为参数。

private static void requestDisallowInterceptTouchEventByDirection(View v, boolean b, Class<?> clazz) {
    while (v.getParent() != null && v.getParent() instanceof View) {
        if (clazz.isInstance(v.getParent())) {
            v.getParent().requestDisallowInterceptTouchEvent(b);
        }
        v = (View) v.getParent();
    }
}

这是一个屏幕截图,我想告诉你到底是什么问题。

这在大多数情况下都有效。

TextViews 5和9嵌套在ScrollViews中,TextViews 6和10嵌套在Horizo​​ntalScrollViews中。

因此任何视图在其自身不可滚动时都应该滚动它的父视图。

我的问题是垂直滚动视图 (4) 内的垂直滚动视图 (5) 不会滚动外部垂直视图的水平滚动父视图 (3)。

另一个方向的相同问题(视图 #10(水平滚动)不滚动它的父级(8,水平滚动)父级(4,垂直滚动),但视图 #10 的视图右侧滚动,8 (水平)和 4(垂直)。

貌似有些view截取错误了,但是没找到问题

谁能帮帮我?

此致

可能的解决方案

好的,完成这个:我找到了一个糟糕的解决方案,但它有效。

如果有两个嵌套的 Horizo​​ntalScrollView,我会搜索第一个(或最里面的)垂直 ScrollView 并禁用拦截。

public static void disableScrollOnParentHorizontalScrollView(View v) {

    v.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            int action = event.getAction();

            switch (action) {
            case MotionEvent.ACTION_DOWN:
                requestDisallowInterceptTouchEventByDirection(v, true, HorizontalScrollView.class); //funzt weitgehend
                if (isDirectlyHorizontalScrollViewAbove(v)) {
                    findFirstScrollViewAbove(v).requestDisallowInterceptTouchEvent(false);
                    findFirstScrollViewAbove(v).getParent().requestDisallowInterceptTouchEvent(true);
                }                   
                break;
            case MotionEvent.ACTION_UP:
                requestDisallowInterceptTouchEventByDirection(v, false, HorizontalScrollView.class);
                break;
            }
            v.onTouchEvent(event);
            return true;
        }
    });
}


private static boolean isDirectlyHorizontalScrollViewAbove(View v) {
    while (v.getParent() != null && v.getParent() instanceof View) {
        if (v.getParent() instanceof HorizontalScrollView) {
            return true;
        } else if (v.getParent() instanceof ScrollView) {
            return false;
        }
        v = (View) v.getParent();
    }
    return false;
}


private static ScrollView findFirstScrollViewAbove(View v) {
    while (v.getParent() != null && v.getParent() instanceof View) {
        if (v.getParent() instanceof ScrollView) {
            return (ScrollView) v.getParent();
        }
        v = (View) v.getParent();
    }
    return null;
}

// same method like before
private static void requestDisallowInterceptTouchEventByDirection(View v, boolean b, Class<?> clazz) {
    while (v.getParent() != null && v.getParent() instanceof View) {
        if (clazz.isInstance(v.getParent())) {
            v.getParent().requestDisallowInterceptTouchEvent(b);
        }
        v = (View) v.getParent();
    }
}

如果有人有更好的解决方案(或者发现我截取的问题),请回答:)

此致