如何防止Android ScrollView拦截其父级点击事件

时间:2014-01-16 06:47:41

标签: android android-xml android-scrollview

我知道有这样的问题已经有了答案,但我没有任何运气,所以这是最后的手段。

我有一个包含ScrollView的LinearLayout。我希望LinearLayout响应点击,点击,触摸你想要调用它的任何内容,但ScrollView是干扰的,所以从不调用LinearLayout的点击处理程序。我不介意对ScrollView进行子类化并覆盖onTouchEvent(但我不明白要放入什么内容),但另一种解决方案也很好。我尝试在LinearLayout,ScrollView和ScrollView的第一个子节点上使用 requestDisallowInterceptTouch(true),但它不起作用(TBH,该方法的javadoc让我困惑)。

如果我在自定义滚动视图中使用此覆盖:

@Override
public boolean onTouchEvent(MotionEvent event) {
    return false;
}

... LinearLayout确实响应了点击,但完全禁用了滚动,并且每种类型的触摸手势都会导致调用LinearLayout点击处理程序。那么,我需要做些什么才能像往常一样处理滚动动作,并让ScrollView忽略点击/点按?

对于它的价值,XML看起来像这样:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"            
    xmlns:tools="http://schemas.android.com/tools" 
    android:id="@+id/my_layout"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <TextView 
        .../>

   <com.package.MyScrollView
        android:id="@+id/my_scroller"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:fillViewport="true"
        android:scrollbars="vertical">
    ...  
    ...

在正常情况下,TextView区域将检测使用LinearLayout注册的点击,但ScrollView不会。

2 个答案:

答案 0 :(得分:2)

首先,遗憾的是,requestDisallowInterceptTouch(true)完全与您想要实现的完全相反。它强制所有父ViewGroup包括您调用该方法的父onInterceptTouchEvent()忽略true中传递给它们的事件。

通常情况下,没有设置此标志为ViewGroups,新的触摸事件首先从根到叶传递到视图树,允许父母(即true)拦截那些事件通过返回ViewGroup将同一手势的所有后续事件重定向到此onTouchEvent() s true方法。到达视图树叶后(假设没有人在onInterceptTouchEvent()中返回onTouchEvent()),事件通过true方法返回到根。再次返回onTouchEvent()意味着在视图中使用该事件,并且所有其他事件将直接传递给您的onInterceptTouch()方法,而不是遍历整个视图树。因此,onTouch()requestDisallowInterceptTouchEvent(true)之间的差异是遍历视图树的方向 - 阅读所有我不确定它是否比javadoc更易于理解。^^

然而,长话短说:OnClickListener在这里不是解决方案。

这是为了prolog。还在?幸运的是 - 因为 是一种(有点难看)的解决方法,因为你观察到的情况:在ScrollView孩子上加performClick()并让你LinearLayout上的ScrollView应该做的伎俩。这会使onTouch保持工作状态(与您覆盖LinearLayout的尝试不同),但会将所有点击事件(仅限那些事件)传递到外部{{1}}。

答案 1 :(得分:0)

尝试将ScrollView的focusable属性设置为false。

<ScrollView
   android:focusable="false"
   >
   <!-- other stuff-->
</ScrollView>