web-dev-qa-db-ja.com

BottomSheetBehaviorと内部CoordinatorLayoutの使用

デザインサポートライブラリ_v. 23.2_はBottomSheetBehaviorを導入しました。これにより、コーディネーターの子がボトムシート(画面の下部からドラッグ可能なビュー)として機能できます。

私がやりたいのは、ボトムシートビューとして、次のビュー(典型的なコーディネーター+崩壊するもの)を持つことです:

_<CoordinatorLayout
    app:layout_behavior=“@string/bottom_sheet_behavior”>

   <AppBarLayout>
        <CollapsingToolbarLayout>
           <ImageView />
        </CollapsingToolbarLayout>
    </AppBarLayout>

    <NestedScrollView>
        <LinearLayout>
            < Content ... />
        </LinearLayout>
    </NestedScrollView>

</CoordinatorLayout>
_

残念ながら、ボトムシートビューはネストされたスクロールを実装する必要があります。そうしないと、スクロールイベントが発生しません。メインアクティビティを試してからこのビューをボトムシートとして読み込むと、スクロールイベントは紙の「シート」に対してのみ作用し、読み続けると奇妙な動作をすることがわかります。

これはCoordinatorLayoutをサブクラス化することで、またはBottomSheetBehaviorをサブクラス化することでさらに良くなると確信しています。ヒントはありますか?

いくつかの考え

  • いくつかの条件で親からイベントを盗むために、requestDisallowInterceptTouchEvent()を使用する必要があります。

    • AppBarLayoutオフセットが> 0の場合
    • AppBarLayoutオフセットが== 0であるが、上にスクロールしている場合(少し考えてみればわかります)
  • 最初の条件は、OnOffsetChangedを内部アプリバーに設定することで取得できます。

  • 2番目は、たとえば次のようなイベント処理を必要とします。

    _switch (MotionEventCompat.getActionMasked(event)) {
        case MotionEvent.ACTION_DOWN:
            startY = event.getY();
            lastY = startY;
            userIsScrollingUp = false;
            break;
        case MotionEvent.ACTION_CANCEL:
        case MotionEvent.ACTION_UP:
            userIsScrollingUp = false;
            break;
        case MotionEvent.ACTION_MOVE:
            lastY = event.getY();
            float yDeltaTotal = startY - lastY;
            if (yDeltaTotal > touchSlop) { // Moving the finger up.
                userIsScrollingUp = true;
            }
            break;
    }
    _

課題

言うまでもなく、私は今この仕事をすることはできません。条件が満たされたときにイベントをキャッチできず、他のケースではそれらをキャッチできません。以下の画像では、標準のCoordinatorLayoutで何が起こるかを確認できます。

  • アプリバーを下にスクロールするとシートは閉じられますが、ネストされたコンテンツを下にスクロールするとシートは閉じられません。ネストされたスクロールイベントは、コーディネーターの動作に伝達されないようです。

  • 内側のアプリバーにも問題があります:ネストされたスクロールコンテンツは、折りたたまれているときにアプリバーに追従しません。

enter image description here

これらの問題を示す githubのサンプルプロジェクト をセットアップしました。

明確にするために、望ましい動作は次のとおりです。

  • シート内のアプリバー/スクロールビューの正しい動作。

  • シートが展開されると、下にスクロールすると折りたたまれますが、内部のアプリバーも完全に展開されている場合のみです。現時点では、アプリバーの状態に関係なく、アプリバーをドラッグした場合にのみ折りたたみます。

  • シートが折りたたまれると、上にスクロールするジェスチャーで展開されます(内側のアプリバーには影響しません)。

連絡先アプリの例(おそらくBottomSheetBehaviorを使用しませんが、これは私が望むものです):

enter image description here

54
natario

私はついに実装をリリースしました。それを見つける Githubで またはjcenterから直接:

compile 'com.otaliastudios:bottomsheetcoordinatorlayout:1.0.0’

必要なことは、BottomSheetCoordinatorLayoutをボトムシートのルートビューとして使用することだけです。自動的に動作動作を膨らませるので、心配する必要はありません。

私はこれを長い間使用していますが、スクロールの問題が発生したり、ABLでのドラッグがサポートされたりすることはありません。

5
natario

上記の質問の方法に従って、さらに説明が必要なソリューションを考え出しました。サンプルコードに従って、xmlに追加部分を統合して、BottomSheeetの動作のように動作させてください。

<CoordinatorLayout>
   <AppBarLayout>
        <Toolbar
            app:layout_collapseMode="pin">
        </Toolbar>
    </AppBarLayout>
    <NestedScrollView
         app:layout_behavior=“@string/bottom_sheet_behavior” >
        <include layout="@layout/items" />
    </NestedScrollView>

    <!-- Bottom Sheet -->

     <BottomSheetCoordinatorLayout>
        <AppBarLayout
            <CollapsingToolbarLayout">
             <ImageView />
                <Toolbar />
            </CollapsingToolbarLayout>
        </AppBarLayout>
        <NestedScrollView">
            <include layout="@layout/items" />
        </NestedScrollView>
    </BottomSheetCoordinatorLayout>
</CoordinatorLayout>

注:あなたの質問の最後のコメントですでに説明した解決策

より良い移植:https://github.com/laenger/BottomSheetCoordinatorLayout

1

NestedScrollViewLinearLayoutを使用しないようにしてください。これは私のアプリでも問題を引き起こしています。代わりにLinearLayoutのみを使用してください、私にとってはうまくいきます。

次を試してください:

<CoordinatorLayout
app:layout_behavior=“@string/bottom_sheet_behavior”>

<AppBarLayout>
    <CollapsingToolbarLayout>
       <ImageView />
    </CollapsingToolbarLayout>
</AppBarLayout>

<LinearLayout>
     <!--don't forget to addd this line-->
     app:layout_behavior="@string/appbar_scrolling_view_behavior">

        < Content ... />
</LinearLayout>
0
rahul

この問題に関して、laengerの最初のgithubテストプロジェクトをフォローしました。アプリでもこの動作が必要だったので、彼の問題のいくつかの解決策を共有できてうれしいです。

これは彼の問題の解決策です:❌ツールバーが時々早く崩壊する

これを防ぐには、カスタムAppBarLayout.Behaviorを作成する必要があります。それは、AppBarLayout.behaviorがスクロールモーションを取得するのはドラッグ中に上にスクロールするときだからです。 STATE_DRAGGINGにあるかどうかを検出し、ツールバーを早めに非表示/折りたたみにしないように戻る必要があります。

public class CustomAppBarLayoutBehavior extends AppBarLayout.Behavior {

    private CoordinatorLayoutBottomSheetBehavior behavior;

    public CustomAppBarLayoutBehavior() {
    }

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

    @Override
    public boolean onStartNestedScroll(CoordinatorLayout parent, AppBarLayout child, View directTargetChild, View target, int nestedScrollAxes) {
        behavior = CoordinatorLayoutBottomSheetBehavior.from(parent);
        return super.onStartNestedScroll(parent, child, directTargetChild, target, nestedScrollAxes);
    }

    @Override
    public void onNestedPreScroll(CoordinatorLayout coordinatorLayout, AppBarLayout child, View target, int dx, int dy, int[] consumed) {
        if(behavior.getState() == CoordinatorLayoutBottomSheetBehavior.STATE_DRAGGING){
            return;
        }else {
            super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed);
        }
    }

    @Override
    public void setDragCallback(@Nullable DragCallback callback) {
        super.setDragCallback(callback);
    }
}

これは、他の問題をどのように解決するかについての良い出発点かもしれません。

dragツールバーはドラッグで折りたたむことはできません

❌メインコーディネーターのレイアウトはスクロールを消費します

私は実際には良いUI /アニメーションの人ではありませんが、実装するための適切なコールバック/オーバーライド関数を見つけて、時々コードを理解することは大変です。

これをappbarlayoutの動作として設定します

<Android.support.design.widget.AppBarLayout
    Android:id="@+id/bottom_sheet_appbar"
    style="@style/BottomSheetAppBarStyle"
    Android:layout_width="match_parent"
    Android:layout_height="wrap_content"
    app:layout_behavior="your.package.CustomAppBarLayoutBehavior">
0
user3115201

最初の子がnestedscrollの場合、他の問題が発生します。この解決策は私の問題を解決し、あなたも解決することを願っています。

<CoordinatorLayout
    app:layout_behavior=“@string/bottom_sheet_behavior”>

   <AppBarLayout>
        <CollapsingToolbarLayout>
           <ImageView />
        </CollapsingToolbarLayout>
    </AppBarLayout>
</LinearLayout>
    <NestedScrollView>
        <LinearLayout>
            < Content ... />
        </LinearLayout>
    </NestedScrollView>
</LinearLayout>
</CoordinatorLayout>
0
Eren Utku