How to prevent ScrollView from intercepting click/touch events of the view behind it?

馋奶兔 提交于 2021-02-06 15:30:25

问题


I have a ScrollView and an ImageView inside a FrameLayout. The ImageView is behind the scroll view

My ScrollView have a transparent space (LinearLayout s_layout_transparent with 925px height).

So my ImageView can be seen through this transparent space but can not be click.

I have tried to add some value (android:clickable="false" android:focusable=" android:focusableInTouchMode="false") to scroll view to prevent it intercepts the click envent of the ImageView but this not work at all.

Here is my layout:

<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>

回答1:


if you can fill the transparent parts with an empty view (lets call it dummyView), you can do something like...

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;
    }
});



回答2:


I solved this issue. Posting this for someone facing the same issue at present/in the future. Thanks for the suggestion Mahesh. Based on the suggestion from Mahesh, this is how i did it. This is my 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>

After adding LinearLayouts @id/dummy and @id/scroll_ , I was unable to click on TextView @id/bg_tv. The following code solved my problem.

//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;
    }
});

In the case of mLayout, TouchEvents are dispatched only after the scrollView goes to the bottom of the screen.

PS: I am writing an answer for the first time. I am sorry if you find the formatting very poor or if the answer is not written the way it is supposed to be.




回答3:


I cant give exact solution

Check it may helps

yourscrollview.setOnTouchListener(new OnTouchListener() {

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



回答4:


The ScrollView is last in FrameLayout therefore it has preference.

When your LinearLayout with ImageView is activated, you need to say

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

and vice versa, when ScrollView is activated, the "sibling" Layout view must be set invisible.




回答5:


Check to see if the coordinates of the event are within the bounds of the view you want to receive the event. If there is a match, use the performClick method to pass the event along to the desired view. Here is an example:

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)
}



回答6:


I also used scroll offset and it gave a perfect result on click events.

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


来源:https://stackoverflow.com/questions/25839816/how-to-prevent-scrollview-from-intercepting-click-touch-events-of-the-view-behin

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!