如何更改BottomSheetDialog的默认高度?

时间:2016-02-25 17:33:23

标签: android android-support-library android-support-design

我一直在使用Support Library 23.2中添加的新BottomSheetDialog,但我想更改对话框的默认高度。我知道这可能与控制初始高度的behavior_peekHeight属性有关,但如果我无法直接访问BottomSheetDialog,如何在BottomSheetBehavior中设置该属性?

17 个答案:

答案 0 :(得分:62)

您可以在活动中设置bottomSheetDialogTheme,覆盖bottomSheetStyle属性的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>

同样的技术也可以用于其他属性,例如将<item name="behavior_hideable">true</item>添加到AppModalStyle以更改底部工作表是否可隐藏。

答案 1 :(得分:22)

您可以在代码中使用BottomSheetBehavior

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

答案 2 :(得分:13)

styles.xml

private Observable<Integer> getNFromCache(){
    return Observable.empty;
}


public Observable<Integer> getNumber(){
      return getNFromCache(scope)
              .switchIfEmpty(this::doHttpRequest);
}


private Observable<Integer> doHttpRequest(){
    return Observable.of(1)
                     .doOnSubscribe(() -> System.out.pritnln("START !"))
}

public static void main(String...args) {
   getNumber(); // display nothing => values are not emitted !
   getNumber().subscribe(); // display "START !"
}

答案 3 :(得分:5)

另一种方法是继承BottomSheetDialogFragment并控制设置内容视图的方式和时间。在查看树中,您可以获得BottomSheetDialog包装内容视图的行为。它不是一个很好的解决方案,因为它需要更多的布局通行证。重要的是,当底页的状态为STATE_HIDDEN时,我们必须关闭对话框,如果我们没有明显违反库中提供的实现。

以编程方式设置查看高度后,内容视图必须调用requestLayout(),这确实是另一个布局过程。

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();
        }
}

答案 4 :(得分:1)

结合Nick和litao的解决方案,这是我们所做的完整版本:

 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();

答案 5 :(得分:1)

我的锅

  override fun onStart() {
    super.onStart()
    dialog?.also {
        val bottomSheet = dialog.findViewById<View>(R.id.design_bottom_sheet)
        bottomSheet.layoutParams.height = ViewGroup.LayoutParams.MATCH_PARENT
        val behavior = BottomSheetBehavior.from<View>(bottomSheet)
        behavior.peekHeight = resources.displayMetrics.heightPixels //replace to whatever you want
        view?.requestLayout()
    }
}

答案 6 :(得分:1)

您可以使用BottomSheetDialogFragment并以编程方式进行操作。

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
    (dialog as? BottomSheetDialog)?.let {
      it.behavior.peekHeight = PEEK_HEIGHT
    }
    return inflater.inflate(R.layout.bottom_sheet_dialog_fragement, container, false)
  }

答案 7 :(得分:1)

如果您使用的是BottomSheetDialogFragment,请复制并粘贴此代码

private View bottomSheet;

@Override public void onStart() {
    super.onStart();
    Dialog dialog = getDialog();
    if (dialog != null) {
      bottomSheet = dialog.findViewById(R.id.design_bottom_sheet);
      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        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());
// Here you can play with the height of the bottom sheet like pass height as- [view.getMeasuredHeight()/2]

            ((View) bottomSheet.getParent()).setBackgroundColor(Color.TRANSPARENT);
          });
        }
      }

答案 8 :(得分:0)

我的底部工作表对话框具有回收器视图并且没有要显示的项目,因此它正在缩小,但是假设您想将查看高度设置为 85%,而不管 Recyclerview 中是否存在项目,请尝试此解决方案。< /p>

在扩展BottomSheetDialogFragment的类中添加以下代码

PK_myid
PK_ my id

答案 9 :(得分:0)

如果您要扩展BottomSheetDialogFragment,您可以执行以下操作来获取BottomSheetBehavior:

public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
    Dialog dialog = super.onCreateDialog(savedInstanceState);
    //Must add any view here, actual view will be inflated in onCreateView
    dialog.setContentView(new View(getContext()));
    //Dialog wraps view in frame layout
    View root = dialog.findViewById(R.id.design_bottom_sheet);
    //Now we have access to BottomSheetBehavior
    BottomSheetBehavior<View> behavior = BottomSheetBehavior.from(root);
    //Do whatever you need:
    behavior.setPeekHeight(320, true);
    behavior.setState(BottomSheetBehavior.STATE_HALF_EXPANDED);

    return dialog;
}

然后像往常一样覆盖 onCreateView :

    public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    //inflate your bottom sheet layout:
    View root = inflater.inflate(R.layout.browser_bottom_sheet, container, false);
    //Do what you need with views:
    ViewPager viewPager = root.findViewById(R.id.viewpager);
                  ...........

    return root;
}

答案 10 :(得分:0)

这对我来说可以全屏显示BottomSheetDialog(STATE_EXPANDED)。我正在“活动”中使用它。

private void showBottomSheetDialog() {
        View dialogView = LayoutInflater.from(this).inflate(R.layout.your_custom_layout, null);
        BottomSheetDialog dialog = new BottomSheetDialog(NewWorkoutPlanActivity.this);
        dialog.setContentView(dialogView);

       
        FrameLayout bottomSheet = (FrameLayout) dialog.findViewById(R.id.design_bottom_sheet);
        BottomSheetBehavior behavior = BottomSheetBehavior.from(bottomSheet);
        ViewGroup.LayoutParams layoutParams = bottomSheet.getLayoutParams();

        int windowHeight = getWindowHeight();
        if (layoutParams != null) {
            layoutParams.height = windowHeight;
        }
        bottomSheet.setLayoutParams(layoutParams);
        behavior.setState(BottomSheetBehavior.STATE_EXPANDED);

        dialog.show();

    }

    private int getWindowHeight() {
        // Calculate window height for fullscreen use
        DisplayMetrics displayMetrics = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
        return displayMetrics.heightPixels;
    }

答案 11 :(得分:0)

您可以在BottomSheetBehavior方法中从getBehaviour()检索onStart()对象,然后从那里修改窥视高度。

@Override
protected void onStart() {
    super.onStart();
    getBehavior().setPeekHeight(/* Peek Height in px */);
}

答案 12 :(得分:0)

使用此代码设置DialogFragment或BottomSheetDialogFragment的高度。对话框将根据不同的屏幕高度调整其高度

  override fun onStart() {
        super.onStart()
        val window = dialog!!.window
        val ratio = 1.0
        if (window != null && activity != null) {
            val heightDialog = (getScreenHeight(requireActivity()) * 0.9f).toInt()
            window.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, (heightDialog * ratio).toInt())
            window.setGravity(Gravity.BOTTOM)
        }
    }

答案 13 :(得分:0)

我们要实现这一目标的真正方法是使LayoutParams有效。扩大对话框的内容视图时,未在对话框parentView中传递Window会使rootView的xml配置实际上不起作用。

所以这是一个解决方案:

val contentWidth = ViewGroup.LayoutParams.MATCH_PARENT
val contentHeight = 500 // px
dialog.setContentView(view, ViewGroup.LayoutParams(contentWidth, contentHeight))

答案 14 :(得分:0)

老实说,我不知道为什么没有人提到这些简单的方法:

override fun onResume() {
    super.onResume()

    dialog.behavior.state = BottomSheetBehavior.STATE_EXPANDED
    // or since com.google.android.material:material:1.1.0-beta01
    (dialog as? BottomSheetDialog)?.behavior?.state = BottomSheetBehavior.STATE_EXPANDED

}
//or
dialog.behavior.peekheight = YOUR_VALUE

直接回答问题

  

:如何直接访问BottomSheetBehavior?

     

A dialog.behavior.peekheight

答案 15 :(得分:0)

这是我对问题的决定:

   override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        val dialog = BottomSheetDialog(context)
        val view = View.inflate(context, R.layout.bottom_dialog, null)

        val heightInPixels = 500
        val params = ViewGroup.LayoutParams(MATCH_PARENT, heightInPixels)

        dialog.setContentView(view, params)

        return dialog
    }

主要部分是方法setContentView(view, params),您可以在其中设置对话框的视图和布局参数,并在其中设置所需的高度。

答案 16 :(得分:0)

我有一个黑客并使用了它。

如果要以编程方式进行操作。

    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) {

        }
    });

谢谢。