滚动视图的 requestDisallowInterceptTouchEvent

requestDisallowInterceptTouchEvent for Scrollview

我在滚动视图中的线性布局中有一个 StreetViewPanoramaView:

  <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/scrollview">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical"
            android:id="@+id/linear">

            <com.google.android.gms.maps.StreetViewPanoramaView
                android:id="@+id/street_view_panorama"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"/>

                <other views - textviews etc>

        </LinearLayout>

    </ScrollView>

StreetViewPanoramaView 允许用户上下左右移动街景相机。我希望滚动视图在用户移动相机时停止拦截用户触摸事件。目前,如果用户在 StreetViewPanoramaView 中移动相机,scrollview 会拦截触摸并移动 scrollview。

我尝试了 https://mobiarch.wordpress.com/2013/11/21/prevent-touch-event-theft-in-android/ 中的这段代码,但它似乎不起作用(滚动视图仍在接收触摸事件):

      mStreetViewPanoramaView = (StreetViewPanoramaView) findViewById(R.id.street_view_panorama);
        LinearLayout.LayoutParams streetViewLp =
                new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, displaymetrics.widthPixels/3);
        mStreetViewPanoramaView.setLayoutParams(streetViewLp);

        disableTouchTheft(mStreetViewPanoramaView);

public static void disableTouchTheft(View view) {
    view.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View view, MotionEvent motionEvent) {
            view.getParent().getParent().requestDisallowInterceptTouchEvent(true);
            switch (motionEvent.getAction() & MotionEvent.ACTION_MASK) {
            case MotionEvent.ACTION_UP:
                view.getParent().getParent().requestDisallowInterceptTouchEvent(false);
                break;
            }
            return false;
        }
    });
}

编辑:

我尝试过的事情:

我制作了自定义视图并将代码 dispatchTouchEvent 导入到我的 activity 代码中:

    @Override
    public boolean dispatchTouchEvent(MotionEvent event) {

        int[] loc = {0, 0};
        mStreetViewPanoramaView.getLocationOnScreen(loc);

        Rect rect = new Rect(loc[0], loc[1] , loc[0] + mStreetViewPanoramaView.getWidth(), loc[1] + mStreetViewPanoramaView.getHeight());


        if (rect.contains((int) event.getRawX(), (int) event.getRawY())) {
            Log.e("stretview", "dispatched");
            return mStreetViewPanoramaView.dispatchTouchEvent(event);
/*            return true;*/

        }else{
            //Continue with touch event
            return super.dispatchTouchEvent(event);
        }
    }

public class CustomStreetViewPanoramaView extends StreetViewPanoramaView {

    public CustomStreetViewPanoramaView(Context context) {
        super(context);
    }

    public CustomStreetViewPanoramaView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public CustomStreetViewPanoramaView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    public CustomStreetViewPanoramaView(Context context, StreetViewPanoramaOptions options) {
        super(context, options);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
        return false; // Do not intercept touch event, let the child handle it
    }
}

代码似乎工作了一半 - StreetViewParnoramaView 似乎将获得视图上半部分的触摸事件,但下半部分不会获得任何触摸事件。

我的完整布局文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:id="@+id/container"
    android:layout_height="match_parent">

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:minHeight="?attr/actionBarSize"
        android:background="?attr/colorPrimary"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        />

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/scrollview">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical"
            android:id="@+id/linearlayout">

            <com.example.simon.customshapes.CustomStreetViewPanoramaView
                android:id="@+id/street_view_panorama"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"/>

            <android.support.v7.widget.CardView
                android:layout_width="match_parent"
                android:layout_height="500dp"
                android:id="@+id/card"
                >
                <TextView
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="Hello card"
                    android:layout_gravity="center" />

            </android.support.v7.widget.CardView>

            <TextView
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:text="Save panorama"
                android:padding="8dp"
                android:id="@+id/savepano"/>

            <android.support.v7.widget.RecyclerView
                android:id="@+id/my_recycler_view"
                android:scrollbars="vertical"
                android:layout_width="match_parent"
                android:layout_height="wrap_content">
            </android.support.v7.widget.RecyclerView>

        </LinearLayout>
    </ScrollView>

</LinearLayout> 

你能试试下面的方法吗...

@Override
public boolean dispatchTouchEvent(MotionEvent event) {

    int[] loc = {0, 0};
    mStreetViewPanoramaView.getLocationOnScreen(loc);

    Rect rect = new Rect(loc[0], loc[1] , loc[0] + mStreetViewPanoramaView.getWidth(), loc[1] + mStreetViewPanoramaView.getHeight());


    if (rect.contains((int) event.getRawX(), (int) event.getRawY())) {            
        mStreetViewPanoramaView.dispatchTouchEvent(event);
        return true;

    }else{
        //Continue with touch event
        return super.dispatchTouchEvent(event);
    }
}

这有望检查触摸是否在全景视图上并进行相应处理。

Johann 的回答是正确的方法,但仍然行不通 - 这个行得通

    @Override
public boolean dispatchTouchEvent(MotionEvent event) {

    if (streetView != null) {
        streetView.getGlobalVisibleRect(rect);

        if (rect.contains((int) event.getRawX(), (int) event.getRawY())) {
            event.offsetLocation(-rect.left, -rect.top);
            streetView.dispatchTouchEvent(event);
            return true;

        } else {
            //Continue with touch event
            return super.dispatchTouchEvent(event);
        }
    } else {
        return super.dispatchTouchEvent(event);
    }
}

dispatchTouchEvent activity 并将事件偏移到 streetView