web-dev-qa-db-ja.com

Android:DrawerLayoutがタッチイベントを基になるビューに渡さないようにする方法

アプリでサポートライブラリのDrawerLayoutを使用しています。 Drawerビューの空の領域をクリックすると、基になるビュー(ListViewを含む)がTouchイベントを受け取り、それに反応することに気付きました。

onInterceptTouchEventDrawerLayoutメソッドは次のようになります。

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
    final int action = MotionEventCompat.getActionMasked(ev);

    // "|" used deliberately here; both methods should be invoked.
    final boolean interceptForDrag = mLeftDragger.shouldInterceptTouchEvent(ev) |
            mRightDragger.shouldInterceptTouchEvent(ev);

    boolean interceptForTap = false;

    switch (action) {
        case MotionEvent.ACTION_DOWN: {
            final float x = ev.getX();
            final float y = ev.getY();
            mInitialMotionX = x;
            mInitialMotionY = y;
            if (mScrimOpacity > 0 &&
                    isContentView(mLeftDragger.findTopChildUnder((int) x, (int) y))) {
                interceptForTap = true;
            }
            mDisallowInterceptRequested = false;
            mChildrenCanceledTouch = false;
            break;
        }

        case MotionEvent.ACTION_MOVE: {
            // If we cross the touch slop, don't perform the delayed peek for an Edge touch.
            if (mLeftDragger.checkTouchSlop(ViewDragHelper.DIRECTION_ALL)) {
                mLeftCallback.removeCallbacks();
                mRightCallback.removeCallbacks();
            }
            break;
        }

        case MotionEvent.ACTION_CANCEL:
        case MotionEvent.ACTION_UP: {
            closeDrawers(true);
            mDisallowInterceptRequested = false;
            mChildrenCanceledTouch = false;
        }
    }

    return interceptForDrag || interceptForTap || hasPeekingDrawer() || mChildrenCanceledTouch;
}

DrawerLayoutでの私の見解:

<Android.support.v4.widget.DrawerLayout
        xmlns:Android="http://schemas.Android.com/apk/res/Android"
        Android:id="@+id/drawer_layout"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent">

    <FrameLayout
            Android:id="@+id/content"
            Android:layout_width="wrap_content"
            Android:layout_height="wrap_content"/>

    <FrameLayout
            Android:id="@+id/sidebar_container"
            Android:layout_width="300dp"
            Android:layout_height="match_parent"
            Android:layout_gravity="left"/>

</Android.support.v4.widget.DrawerLayout>

この動作を防ぐために、(DrawerLayoutクラスを拡張せずに可能であれば)何ができますか?ドロワーが開いている限り、クリックイベントがバックグラウンドビューに到達しないようにします。

45
janoliver

引き出しでクリック可能をtrueに設定します-タッチを消費します。

<Android.support.v4.widget.DrawerLayout
    xmlns:Android="http://schemas.Android.com/apk/res/Android"
    Android:id="@+id/drawer_layout"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent">

    <FrameLayout
        Android:id="@+id/content_view"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"/>

    <FrameLayout
        Android:id="@+id/drawer_view"
        Android:layout_width="300dp"
        Android:clickable="true"
        Android:importantForAccessibility="no"
        Android:layout_height="match_parent"
        Android:layout_gravity="left"/>

</Android.support.v4.widget.DrawerLayout>

追加した Android:importantForAccessibility="no"ドロワーをインタラクティブ(クリック可能またはフォーカス可能)としてマークすると、ドロワー全体がTalkBackなどのユーザー補助サービスに表示されます。

これはあなたが望むものではありません(通常)-多くの場合、アイテム内部引き出しはサービスにアクセスできる必要があります。

この属性はAPI 16以降でのみ使用できます。

81
ataulm