web-dev-qa-db-ja.com

BottomSheetDialogFragment-展開された高さ(または最小の上部オフセット)を設定する方法

BottomSheetDialogFragmentを作成し、最大拡張高さを調整します。どうやってやるの? BottomSheetBehaviourを取得できますが、ピークの高さのセッターだけが見つかりますが、拡張された高さのセッターはありません。

public class DialogMediaDetails extends BottomSheetDialogFragment
{
    @Override
    public void setupDialog(Dialog dialog, int style)
    {
        super.setupDialog(dialog, style);
        View view = View.inflate(getContext(), R.layout.dialog_media_details, null);
        dialog.setContentView(view);

        ...

        View bottomSheet = dialog.findViewById(R.id.design_bottom_sheet);
        BottomSheetBehavior behavior = BottomSheetBehavior.from(bottomSheet);
        behavior.setPeekHeight(...);
        // how to set maximum expanded height???? Or a minimum top offset?

    }
}

編集

なぜ必要なのですか?全画面アクティビティでBottomSheetダイアログを表示し、BottomSheetが上にスペースを残すと見た目が悪くなるためです...

39
prom85

layout_height=wrap_contentを持つFrameLayoutに拡大されたビューが追加されるため、高さがラップされています。 https://github.com/dandar3/Android-support-design/blob/master/res/layout/design_bottom_sheet_dialog.xml のFrameLayout(R.id.design_bottom_sheet)を参照してください。

以下のクラスは、ボトムシートをフルスクリーンにし、背景を透明にし、上部まで完全に展開します。

public class FullScreenBottomSheetDialogFragment extends BottomSheetDialogFragment {


    @CallSuper
    @Override
    public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        ButterKnife.bind(this, view);
    }


    @Override
    public void onStart() {
        super.onStart();
        Dialog dialog = getDialog();

        if (dialog != null) {
            View bottomSheet = dialog.findViewById(R.id.design_bottom_sheet);
            bottomSheet.getLayoutParams().height = ViewGroup.LayoutParams.MATCH_PARENT;
        }
        View view = getView();
        view.post(() -> {
            View parent = (View) view.getParent();
            CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) (parent).getLayoutParams();
            CoordinatorLayout.Behavior behavior = params.getBehavior();
            BottomSheetBehavior bottomSheetBehavior = (BottomSheetBehavior) behavior;
            bottomSheetBehavior.setPeekHeight(view.getMeasuredHeight());
            ((View)bottomSheet.getParent()).setBackgroundColor(Color.TRANSPARENT)

        });
    }

}

--- 2018年8月30日編集--- 1年後、背景が間違ったビューに色付けされていることに気付きました。これにより、ユーザーがダイアログをドラッグしているときに背景がコンテンツとともにドラッグされました。下のシートの親ビューが色付けされるように修正しました。

22
Rubin Yoo

もっと簡単な答えを見つけました。このコードを使用してボトムシートのFrameLayoutを取得する例では

View bottomSheet = dialog.findViewById(R.id.design_bottom_sheet);

その後、そのビューのレイアウトパラメーターの高さを、拡張された高さに設定する任意の高さに設定できます。

bottomSheet.getLayoutParams().height = ViewGroup.LayoutParams.MATCH_PARENT;
18
Jason Sznol

BIG UPDATE重複コードの回避 完全な回答 へのリンクを提供しています。 Googleマップのような完全な動作を取得します。


最大拡張高さを調整したいです。どうやってやるの?

BottomSheetBottomSheetDialogFragmentは両方とも、Support Library 23.xにあるBottomSheetBehaviorを使用します

そのJavaクラスにはmMinOffsetの2つの異なる用途があり、そのうちの1つは、コンテンツの描画に使用する親の領域を定義するために使用されます(おそらくNestedScrollView)。そして、拡張アンカーポイントを定義する場合のもう1つの用途は、STATE_COLLAPSEDitから上にスライドすると、BottomSheetitがアニメーション化され、このアンカーポイントに到達するまでです。親の高さ(CoordiantorLayout Height)。

BottomSheetDialogを見ると、次のメソッドが表示されます。

private View wrapInBottomSheet(int layoutResId, View view, ViewGroup.LayoutParams params) {
    final CoordinatorLayout coordinator = (CoordinatorLayout) View.inflate(getContext(),
            Android.support.design.R.layout.design_bottom_sheet_dialog, null);
    if (layoutResId != 0 && view == null) {
        view = getLayoutInflater().inflate(layoutResId, coordinator, false);
    }
    FrameLayout bottomSheet = (FrameLayout) coordinator.findViewById(Android.support.design.R.id.design_bottom_sheet);
    BottomSheetBehavior.from(bottomSheet).setBottomSheetCallback(mBottomSheetCallback);
    if (params == null) {
        bottomSheet.addView(view);
    } else {
        bottomSheet.addView(view, params);
    }
    // We treat the CoordinatorLayout as outside the dialog though it is technically inside
    if (shouldWindowCloseOnTouchOutside()) {
        final View finalView = view;
        coordinator.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if (isShowing() &&
                        MotionEventCompat.getActionMasked(event) == MotionEvent.ACTION_UP &&
                        !coordinator.isPointInChildBounds(finalView,
                                (int) event.getX(), (int) event.getY())) {
                    cancel();
                    return true;
                }
                return false;
            }
        });
    }
    return coordinator;
}



これら2つの動作のどちらを使用するかはわかりませんが、2番目の動作が必要な場合は、次の手順に従ってください。

  1. Javaクラスを作成し、CoordinatorLayout.Behavior<V>から拡張します
  2. デフォルトのBottomSheetBehaviorファイルから新しいコードにコードを貼り付けます。
  3. メソッドclampViewPositionVerticalを次のコードで変更します。

    @Override
    public int clampViewPositionVertical(View child, int top, int dy) {
        return constrain(top, mMinOffset, mHideable ? mParentHeight : mMaxOffset);
    }
    int constrain(int amount, int low, int high) {
        return amount < low ? low : (amount > high ? high : amount);
    }
    
  4. 新しい状態を追加する

    public static final int STATE_ANCHOR_POINT = X;
    
  5. 次のメソッドを変更します:onLayoutChildonStopNestedScrollBottomSheetBehavior<V> from(V view)およびsetState(オプション)

そして、それは次のようになります:
[CustomBottomSheetBehavior]

13
MiguelHincapieC