3

範囲

ViewPager を含むフラグメントがあります。ビューページャーの各ページにはアイテム フラグメントが含まれています。アイテム フラグメントに対してアクションを実行すると、アイテム フラグメント内にスナックバーが表示されます。スナックバーはアイテム フラグメントの一部です (CoordinatorLayout はアイテム フラグメント レイアウトの一部です)。

問題

私が直面している問題は、ビューページャーがスワイプ イベントをインターセプトし、スナックバーを閉じる代わりにページを変更するため、スナックバーを閉じることができないことです。

質問

ビューページャーがスナックバーへのタッチをインターセプトしないようにしますが、アイテム フラグメントの残りの部分へのタッチはインターセプトします (ユーザーは、スナックバーをスワイプしていないときでもスワイプしてページを変更できるはずです)。これを行う方法を知っている人はいますか?

問題を示すサンプル アプリを作成しました。https://github.com/gfrederick/ViewPagerSnackbarで入手できます。

4

1 に答える 1

2

githubで私のソリューションをチェックしてください。

何らかの理由でリンクが削除された場合に備えて、私が何をしたかを説明します。

  1. 関連する Snackbar クラスをプロジェクトにコピーしました。
  2. 同様の質問に対するこの回答に触発されて、Snackbar の Behavior サブクラスをビューページャーで動作するように変更しました。具体的には、ビュー階層にスナックバーの親としてビューページャーがあるかどうかを調べます。次に、スナックバーがタッチされると、viewpager によるタッチ イベントの処理を無効にします。スナックバーを離すと(タッチイベントが終了すると)再び有効になります。

重要なコードは次のとおりです。

final class Behavior extends SwipeDismissBehavior<SnackbarLayout> {

    @Override
    public boolean onInterceptTouchEvent(CoordinatorLayout parent, SnackbarLayout child,
                                         MotionEvent event) {

        ViewPager vp = getViewPagerParent(child);

        if (parent.isPointInChildBounds(child, (int) event.getX(), (int) event.getY())) {
            switch (event.getActionMasked()) {
                case MotionEvent.ACTION_DOWN:
                    ViewPagerSnackbarManager.getInstance().cancelTimeout(mManagerCallback);

                    // If touching Snackbar tell the viewpager not to intercept touch events
                    if (vp != null) {
                        vp.requestDisallowInterceptTouchEvent(true);
                    }
                    break;
                case MotionEvent.ACTION_UP:
                case MotionEvent.ACTION_CANCEL:
                    // As soon as this event (touching the Snackbar) is over tell viewpager to resume intercepting touch events
                    if (vp != null) {
                        vp.requestDisallowInterceptTouchEvent(false);
                    }
                    ViewPagerSnackbarManager.getInstance().restoreTimeout(mManagerCallback);
                    break;
            }
        }
        return super.onInterceptTouchEvent(parent, child, event);
    }

    // helper method that move up the view hierarchy searching for a Viewpager and returns it if found. Null if not found.
    private ViewPager getViewPagerParent(View child) {
        ViewParent parent = child.getParent();

        while (parent != null) {
            parent = child.getParent();
            if (parent instanceof ViewPager) {
                return (ViewPager) parent;
            } else if (!(parent instanceof View)) {
                return null;
            } else {
                child = (View) parent;
            }
        }
        return null;
    }
}
于 2016-01-05T11:14:31.720 に答える