如何在BottomSheetDialogFragment中设置最大高度?

14

enter image description here我有一个BottomSheetDialogFragment,需要在此对话框中设置高度。我希望当用户点击按钮时,对话框会出现并填充屏幕的85%。如何实现?


请发布您的XML和活动代码! - mohammadReza Abiri
8个回答

16

BottomSheetDialogFragment:

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)

    val offsetFromTop = 200
    (dialog as? BottomSheetDialog)?.behavior?.apply {
        isFitToContents = false
        setExpandedOffset(offsetFromTop)
        state = BottomSheetBehavior.STATE_EXPANDED
    }
}

BottomSheetBehavior.STATE_EXPANDED - PeterPazmandi

9
你可以这样做:
public class MyBottomSheetDialog extends BottomSheetDialogFragment {

   //....

   @NonNull @Override public Dialog onCreateDialog(Bundle savedInstanceState) {
    Dialog dialog = super.onCreateDialog(savedInstanceState);
    dialog.setOnShowListener(new DialogInterface.OnShowListener() {
      @Override public void onShow(DialogInterface dialogInterface) {
        BottomSheetDialog bottomSheetDialog = (BottomSheetDialog) dialogInterface;
        setupRatio(bottomSheetDialog);
      }
    });
    return  dialog;
  }

  private void setupRatio(BottomSheetDialog bottomSheetDialog) {
    //id = com.google.android.material.R.id.design_bottom_sheet for Material Components
    //id = android.support.design.R.id.design_bottom_sheet for support librares
    FrameLayout bottomSheet = (FrameLayout) 
        bottomSheetDialog.findViewById(R.id.design_bottom_sheet);
    BottomSheetBehavior behavior = BottomSheetBehavior.from(bottomSheet);
    ViewGroup.LayoutParams layoutParams = bottomSheet.getLayoutParams();
    layoutParams.height = getBottomSheetDialogDefaultHeight();
    bottomSheet.setLayoutParams(layoutParams);
    behavior.setState(BottomSheetBehavior.STATE_EXPANDED);
  }
  private int getBottomSheetDialogDefaultHeight() {
    return getWindowHeight() * 85 / 100;
  }
  private int getWindowHeight() {
    // Calculate window height for fullscreen use
    DisplayMetrics displayMetrics = new DisplayMetrics();
    ((Activity) getContext()).getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
    return displayMetrics.heightPixels;
  }

}

enter image description here


我在BottomSheetBehaviour.from()中遇到了NullPointerException... - user11163395
@YorkIsMine 是由底部弹出窗口组件(材料组件或支持库)提供的ID。它不在我的XML布局中。 - Gabriele Mariotti
@YorkIsMine 你在使用哪个版本?你是在onCreateDialog方法中使用代码吗? - Gabriele Mariotti
我有AndroidX材料库,而且我有相同的代码。 - user11163395
1
哦,我错过了想法角落仅在M3中引入的事实。 我现在做的是完全消除 setState(BottomSheetBehavior.STATE_EXPANDED),并使用样式方式使底部表单不可拖动。 这是我的方法 - https://github.com/yccheok/wediary-sandbox/blob/master/bottom-sheet/app/src/main/java/com/yocto/bottom_sheet/DemoBottomDialogFragment.java#L52 - Cheok Yan Cheng
显示剩余7条评论

5
始终展开到全高可以在您的BottomSheetDialogFragment()onCreateDialog中进行设置。
    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
    val dialog = BottomSheetDialog(requireContext(), theme)
    dialog.behavior.state = BottomSheetBehavior.STATE_EXPANDED
    dialog.behavior.skipCollapsed = true
    return dialog
}

onCreateView 中可以设置最大高度。

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        val view = inflater.inflate(R.layout.bottom_sheet_dialog, container, false)
        // Set max height to half screen
        view.findViewById<ConstraintLayout>
(R.id.root_layout_of_bottom_sheet).maxHeight =
            (resources.displayMetrics.heightPixels * 0.5).toInt()
        return view
    }

1
在Kotlin和Jetpack Compose中:
val configuration = LocalConfiguration.current
val screenWidth = configuration.screenWidthDp.divideToPercent(0.40f) // total screen width size of 40 percentage
val screenHeight = configuration.screenHeightDp.divideToPercent(0.95f) // total screen height size of 95 percentage

configuration.screenWidth --> 提供屏幕尺寸

divideToPercent(0.40f) --> 它将从屏幕中给出一些百分比


1

这很容易处理。

让我们开始吧。

override fun onStart() {
    super.onStart()
    val height = Resources.getSystem().displayMetrics.heightPixels

    // in this case I want set max height half of the device height
    val maxHeight = (height * 0.5).toInt()

    val behaviour = BottomSheetBehavior.from(requireView().parent as View)


    /* Note that If you want to display max height 
      as per your bottomsheet view 
      val maxHeight = WindowManager.LayoutParams.MATCH_PARENT */

    // now set your max peek height 
    behavior.peekHeight = maxHeight 
}

从上述案例中,如果您设置 maxHeight = WindowManager.LayoutParams.MATCH_PARENT

当您在底部表单上显示一些固定的 onCreateView 时,这很简单。 但是有时候如果在主线程之后更新UI它可能不会显示实际高度,这时最好使用viewTreeObserver

override fun onStart() {
    super.onStart()
    
    view?.viewTreeObserver?.addOnGlobalLayoutListener {
        val behavior = BottomSheetBehavior.from(view!!.parent as View)
        behavior.peekHeight = WindowManager.LayoutParams.MATCH_PARENT
    }


}

1

try this :

 DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
     int height = displayMetrics.heightPixels;
     int maxHeight = (int) (height*0.80);


 View bottomSheet = findViewById(R.id.bottom_sheet);  
 BottomSheetBehavior behavior = BottomSheetBehavior.from(bottomSheet);         
 behavior.setPeekHeight(maxHeight);

在你的 XML 中:
<LinearLayout 
    android:id="@+id/bottom_sheet"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    app:behavior_hideable="true"
    app:layout_behavior="android.support.design.widget.BottomSheetBehavior"



      .
      .
      .

</LinearLayout>

如何获取行为?总是得到A或NPE,或致命错误。 - user11163395

0

当你的项目高度太短,无法填充底部表格,并且其他方法无法解决时,请尝试以下代码:

BottomSheetFragment:

override fun onStart() {
      super.onStart()
        view?.viewTreeObserver?.addOnGlobalLayoutListener(object :
            ViewTreeObserver.OnGlobalLayoutListener {
            override fun onGlobalLayout() {
                val behavior = BottomSheetBehavior.from(view!!.parent as View)
                behavior.peekHeight = **your height**
             }
         })
   }

通常情况下,如果答案包含代码的意图和解决问题的原因,而不会引入其他问题,那么这些答案会更有帮助。 - DCCoder

-1

补充mohammadReza AbiriGabriele Mariotti的答案:

如果您得到BottomSheetBehavior的null值,请将其包装在CoordinatorLayout周围。

BottomSheetBehavior应用于CoordinatorLayout的子项,使该子项成为持久的底部工作表。

持久的底部工作表是从屏幕底部弹出的视图,高于主要内容。它们可以垂直拖动以显示更多或更少的内容。

注意:如果您想使用模态(对话框)的底部工作表,请使用BottomSheetDialogFragment。

BottomSheetBehavior与CoordinatorLayout配合使用,让您在底部工作表(主内容上方的一层)上显示内容,执行进入/退出动画,响应拖动/滑动手势等。

<androidx.coordinatorlayout.widget.CoordinatorLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <!-- This is your BottomSheetBehavior Layout -->
    <include layout="@layout/bottom_sheet" />


    </androidx.coordinatorlayout.widget.CoordinatorLayout>

要以编程方式控制底部工作表,您可以在BottomSheetBehavior上调用setState方法。常见的模式是设置一个窥视高度并将状态设置为折叠,以使其对用户可见:
bottomSheetBehavior.setPeekHeight(300);
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接