android – 带有子视图的ScrollView,如何有条件地拦截滚动

android – 带有子视图的ScrollView,如何有条件地拦截滚动,第1张

概述我有一个容器ViewGroup,让我们在ScrollView中调用它.这个容器视图包含许多其他视图,让我们称它们为小部件,其中一些有兴趣阻止ScrollView滚动并使用MotionEvent自己(例如一个pannable图像) 我无法弄清楚要使用的正确的事件拦截策略. ScrollView始终在子项之前处理事件,或者子项处理事件但禁用scrollview. 我读到了如果这个视图想要捕获事件但在子 我有一个容器VIEwGroup,让我们在ScrollVIEw中调用它.这个容器视图包含许多其他视图,让我们称它们为小部件,其中一些有兴趣阻止ScrollVIEw滚动并使用MotionEvent自己(例如一个pannable图像)

我无法弄清楚要使用的正确的事件拦截策略. ScrollVIEw始终在子项之前处理事件,或者子项处理事件但禁用scrollvIEw.

我读到了如果这个视图想要捕获事件但在子视图中发出getParent().requestdisableIntercepttouchEvent(),但是他们的ontouchEvent没有被调用,我想是因为ScrollVIEw事先已经吞没了事件.我想我有两级图层(容器小部件)的事实阻止了它的工作,我想容器VIEwGroup必须在这里发挥重要作用,但我无法弄清楚哪一个……

我可以知道,在ScrollVIEw的onIntercepttouchEvent级别,触摸了容器vIEwGroup上的哪个小部件来决定是否应该拦截?

要么…

VIEwGroup中的’Widget’层如何在ScrollVIEw之前获取事件,因此我可以调用getParent().onRequestdisableIntercepttouch()…或者是getParent().getParent().onRequestdisableIntercepttouch()?

提前致谢

我已经阅读了相关问题,但没有运气……
Handle touch events in ScrollView Android

解决方法 经过一夜可口可乐&调试我设法使这个工作.我会分享解决方案以防万一对任何人感兴趣,因为我花了很多时间才能让它运行起来.

我没有设法让它运行getParent().onRequestdisableIntercepttouch(),我很接近,但是一旦我拦截了父项上的触摸,找不到让子小部件获取滚动所需的MotionEvent的方法,所以即使外部滚动被正确阻止,内部小部件也不会滚动.

所以解决方法是仅在子节点中拦截触发事件,如果子节点是可滚动的(已知属性),并且触摸是ACTION_DOWN,则禁用上面两级的scrollvIEw.如果触摸是ACTION_UP,我们启用scrollvIEw.

要启用/禁用滚动视图,我只是拦截触摸事件,并使用标志过滤事件与否.

我做了三个辅助类,一个用于ScrollVIEw,一个用于容器,一个用于小部件:

这个类包装了每个小部件,如果我调用setNeedsScroll(true),那么将拦截触摸,当它被触摸时,它将(告诉容器)告诉scrollvIEw禁用它自己.触摸释放后,将重新启用滚动视图.

class WidgetWrapperLayout extends FrameLayout {    private boolean mNeedsScroll=false;    public WidgetWrapperLayout(Context context) {        super(context);    }  /** Called anytime,IE,during construction,to indicate that this     * Widget uses vertical scroll,so we need to disable its container scroll     */    public voID setNeedsScroll(boolean needsScroll) {         mNeedsScroll=needsScroll;     }    @OverrIDe    public boolean onIntercepttouchEvent(MotionEvent ev) {        if (mNeedsScroll)  {            switch (ev.getAction()) {              case MotionEvent.ACTION_DOWN:                ((SlIDeLayout)getParent()).setEnableScroll(false);                break;            case MotionEvent.ACTION_UP:                ((SlIDeLayout)getParent()).setEnableScroll(true);                break;            }            return false;        }        return super.onIntercepttouchEvent(ev);    }}

这是容器,只是scrollvIEw的子项,并包含不同的小部件.它只为孩子们提供方法,以便他们可以启用/禁用滚动:

public class ContainerLayout extends FrameLayout {    public ContainerLayout(Context context) {        super(context);    }    public voID setEnableScroll(boolean status) {        if (Conf.LOG_ON) Log.d(TAG,"Request enable scroll: "+status);        ((StoppableScrollVIEw)getParent()).setScrollEnabled(status);    }}

最后是一个能够停用的滚动视图.它禁用滚动’old-skool’,拦截和阻止事件.

public class StoppableScrollVIEw extends ScrollVIEw {    private String TAG="StoppableScrollVIEw";    private boolean mdisableScrolling=false;    public StoppableScrollVIEw(Context context) {        super(context);    }    /** Enables or disables ScrollVIEw scroll */    public voID setScrollEnabled (boolean status) {         if (Conf.LOG_ON) Log.d(TAG,"Scroll Enabled "+status);        mdisableScrolling=!status;     }    @OverrIDe    public boolean onIntercepttouchEvent(MotionEvent ev) {        if (mdisableScrolling) return false;        return super.onIntercepttouchEvent(ev);    }}
总结

以上是内存溢出为你收集整理的android – 带有子视图的ScrollView,如何有条件地拦截滚动全部内容,希望文章能够帮你解决android – 带有子视图的ScrollView,如何有条件地拦截滚动所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/web/1148902.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-31
下一篇 2022-05-31

发表评论

登录后才能评论

评论列表(0条)

保存