如何防止ScrollView拦截其背后的点击/触摸事件?

时间:2014-09-15 01:54:25

标签: android android-layout touch-event

我在FrameLayout中有一个ScrollView和一个ImageView。 ImageView位于滚动视图后面

我的ScrollView有一个透明空间(LinearLayout s_layout_transparent,高度为925px)。

所以我的ImageView 可以通过这个透明空间看到,但无法点击

我试图添加一些值(android:clickable =" false" android:focusable =" android:focusableInTouchMode =" false")滚动视图以防止它截取ImageView的点击事件,但这根本不起作用。

这是我的布局:

<FrameLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent">
<LinearLayout
        android:gravity="top|center_horizontal"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingRight="10dp"
        >
    <ImageView
            android:visibility="visible"
            android:id="@+id/s_imgv_splash"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/temp_detail_screen_splash"
            android:adjustViewBounds="true"
            android:scaleType="fitXY"/>
</LinearLayout>
<com.dreambox.android.saven.Views.ScrollView
        android:id="@+id/s_scrollview_event_detail"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:scrollbars="none"
        android:visibility="visible"
        android:clickable="false"
        android:focusable="false"
        android:focusableInTouchMode="false"
        >
    <LinearLayout
            android:orientation="vertical"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:clickable="false"
            android:focusableInTouchMode="false"
            android:focusable="false">
        <LinearLayout
                android:id="@+id/s_layout_transparent"
                android:layout_gravity="center_vertical"
                android:layout_width="match_parent"
                android:layout_height="925px"
                android:orientation="horizontal"
                android:background="@color/trasparent"
                android:clickable="false"
                android:focusableInTouchMode="false"
                android:focusable="false">
        </LinearLayout>
        <LinearLayout...>
        <LinearLayout...>
    </LinearLayout>
</com.dreambox.android.saven.Views.ScrollView>
</FrameLayout>

6 个答案:

答案 0 :(得分:9)

如果你可以用空视图填充透明部分(让我们称之为dummyView),你可以做类似......

dummyView.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View view, MotionEvent event) {
        // pass on the touch event to the ImageView
        s_imgv_splash.dispatchTouchEvent(event);
        // returning true because we handled the event
        return true;
    }
});

答案 1 :(得分:4)

我解决了这个问题。在目前/将来面向同一问题的人发布此信息。 感谢Mahesh的建议。根据Mahesh的建议,我就是这样做的。这是我的layout.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/scroll_view"
    android:background="#ffffff"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/bg_tv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="TestView"
        android:layout_marginTop="5dip"/>

    <View android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@android:color/background_dark"
        android:alpha="0"
        />

    <ScrollView
        android:id="@+id/sv"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        >

       <LinearLayout
            android:id="@id+/wrapper"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:background="@android:color/transparent"
            android:orientation="vertical" >

           <LinearLayout
               android:id="@+id/dummy"
                android:layout_width="fill_parent"
                android:background="@android:color/transparent"
                android:layout_height="500dip"
                android:orientation="vertical"/>

           <LinearLayout
               android:id="@+id/scroll_"
              android:layout_width="fill_parent"
              android:layout_height="fill_parent"
              android:orientation="vertical" >

             ................
             ................


          </LinearLayout>

        </LinearLayout>

    </ScrollView>

</RelativeLayout>

添加LinearLayouts @ id / dummy和@ id / scroll_后,我无法点击TextView @ id / bg_tv。以下代码解决了我的问题。

//dispatch touch events
mDummyView = findViewById(R.id.dummy);
mDummyView.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View view, MotionEvent motionEvent) {
        mTextView.dispatchTouchEvent(motionEvent);
        return true;
    }
});

mLayout = (LinearLayout)findViewById(R.id.scroll_);
mLayout.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View view, MotionEvent motionEvent) {
        if (scrollPercent <= 0.25f) {
            mTextView.dispatchTouchEvent(motionEvent);
            return true;
        }
        return false;
    }
});

对于mLayout,只有在scrollView转到屏幕底部后才会调度TouchEvents。

PS:我是第一次写答案。如果您发现格式非常差或者答案没有以预期的方式编写,我很抱歉。

答案 2 :(得分:1)

我无法给出确切的解决方案

检查可能有帮助

yourscrollview.setOnTouchListener(new OnTouchListener() {

            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if(touch exists inside imageview boundaries)
                {
                    do imageview click action
                }
                return false;
            }
        })

答案 3 :(得分:0)

ScrollView是FrameLayout的最后一个,因此它有首选。

激活带有ImageView的LinearLayout时,您需要说

findViewById(R.id.s_scrollview_event_detail).setVisibility(View.INVISIBLE)

反之亦然,当ScrollView被激活时,&#34; sibling&#34;布局视图必须设置为不可见。

答案 4 :(得分:0)

我还使用了滚动偏移,它在点击事件上给出了完美的结果。

blockingViewInScroll.setOnTouchListener(new View.OnTouchListener() {
    @Override
    public boolean onTouch(View view, MotionEvent event) {
        event.offsetLocation(-scrollView.getScrollX(), -scrollView.getScrollY());
        blockedViewUnderScroll.dispatchTouchEvent(event);
        return true;
    }
});

答案 5 :(得分:0)

检查事件的坐标是否在您要接收事件的视图的范围内。如果存在匹配项,请使用performClick方法将事件传递到所需的视图。这是一个示例:

override fun onCreate(savedInstanceState: Bundle?) {
    ....
    val viewUnderDummySpace = findViewById<View>(R.id.your_textview_or_button_or_image)
    val dummySpace = scrollView.findViewById<View>(R.id.dummy_space)
    dummySpace.setOnTouchListener(object : View.OnTouchListener {
        override fun onTouch(p0: View?, event: MotionEvent?): Boolean {
            event?.let {
                if (event.getAction() == MotionEvent.ACTION_UP) {
                    if (inViewInBounds(viewUnderDummySpace, event.rawX.toInt(), event.rawY.toInt())) {
                        //Click performed within bounds of the desired view
                        viewUnderDummySpace.performClick()
                    }
                }
            }

            return true
        }
    })
}

private var outRect = Rect()
private var location = IntArray(2)

private fun inViewInBounds(view: View, x: Int, y: Int): Boolean {
    view.getDrawingRect(outRect)
    view.getLocationOnScreen(location)
    outRect.offset(location[0], location[1])
    return outRect.contains(x, y)
}