How do I change the default height of a BottomShee

2019-01-31 00:12发布

问题:

I've been using the new BottomSheetDialog added in Support Library 23.2, but I want to change the default height of the dialog. I know it probably has to do with the behavior_peekHeight attribute which controls the initial height, but how do I set that in the BottomSheetDialog when I don't have direct access to the BottomSheetBehavior?

回答1:

You can set a bottomSheetDialogTheme in your Activity, overriding the bottomSheetStyle attribute's behavior_peekHeight:

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
  <item name="bottomSheetDialogTheme">@style/AppBottomSheetDialogTheme</item>
</style>

<style name="AppBottomSheetDialogTheme"
       parent="Theme.Design.Light.BottomSheetDialog">
  <item name="bottomSheetStyle">@style/AppModalStyle</item>
</style>

<style name="AppModalStyle"
       parent="Widget.Design.BottomSheet.Modal">
  <item name="behavior_peekHeight">@dimen/custom_peek_height</item>
</style>

This same technique can be used for other attributes as well, such as adding <item name="behavior_hideable">true</item> to the AppModalStyle to change whether the bottom sheet is hideable.



回答2:

you can use BottomSheetBehaviorin your code

BottomSheetDialog dialog = new BottomSheetDialog(content);
.
.
.
dialog.setContentView(view);
BottomSheetBehavior mBehavior = BottomSheetBehavior.from((View) view.getParent());
mBehavior.setPeekHeight(your dialog height)
dialog.show();


回答3:

styles.xml

<style name="BottomSheetDialog" parent="Theme.Design.Light.BottomSheetDialog">
    <item name="bottomSheetStyle">@style/bottomSheetStyleWrapper</item>
</style>

<style name="bottomSheetStyleWrapper" parent="Widget.Design.BottomSheet.Modal">
    <item name="behavior_peekHeight">500dp</item>
</style>

BottomSheetDialog dialog = new BottomSheetDialog(this, R.style.BottomSheetDialog);
            dialog.setContentView(R.layout.layout_bottom_sheet);
            dialog.show();


回答4:

Another way is inheriting BottomSheetDialogFragment and have control how and when you set the content view. Going up the view tree, you can get the behavior that BottomSheetDialog wraps up the content view. It's not really good solution, because it requires more layout passes. It is important that when the state of the bottom sheet is STATE_HIDDEN we have to dismiss the dialog, if we don't we clearly violate the implementation provided in the library.

After setting the peek height programmatically, content view must call requestLayout() which is indeed another layout pass.

public class CustomBottomSheetDialogFragment extends BottomSheetDialogFragment {


    private BottomSheetBehavior.BottomSheetCallback mBottomSheetBehaviorCallback = new BottomSheetBehavior.BottomSheetCallback() {

        @Override
        public void onStateChanged(@NonNull View bottomSheet, int newState) {
            setStateText(newState);
            if (newState == BottomSheetBehavior.STATE_HIDDEN) {
                dismiss();
            }

        }

        @Override
        public void onSlide(@NonNull View bottomSheet, float slideOffset) {
        }
    };

@Override
    public void setupDialog(Dialog dialog, int style) {
        super.setupDialog(dialog, style);
        View contentView = View.inflate(getContext(), R.layout.bottom_sheet_dialog_content_view, null);
        dialog.setContentView(contentView);
        mBottomSheetBehavior = BottomSheetBehavior.from(((View) contentView.getParent()));
        if (mBottomSheetBehavior != null) {
           mBottomSheetBehavior.setBottomSheetCallback(mBottomSheetBehaviorCallback);    
           mBottomSheetBehavior.setPeekHeight(peekHeight);
           contentView.requestLayout();
        }
}


回答5:

Combining Nick and litao's solution, this is a complete version of what we do:

 BottomSheetDialog bottomSheet = new BottomSheetDialog(context);
 View view = View.inflate(context, R.layout.your_action_sheet, null);
 bottomSheet.setContentView(view);
 BottomSheetBehavior bottomSheetBehavior = BottomSheetBehavior.from(((View) view.getParent()));
 bottomSheetBehavior.setPeekHeight(1000);
 bottomSheet.show();


回答6:

I got one hack and used it.

If you want to do programmatically.

    behavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
        @Override
        public void onStateChanged(@NonNull View view, int i) {
            behavior.setPeekHeight(yourMinHeight);
        }

        @Override
        public void onSlide(@NonNull View view, float v) {

        }
    });

Thank you.