简体   繁体   中英

How to set max height in BottomSheetDialogFragment?

在此处输入图像描述 I have a BottomSheetDialogFragment and i need to set my height in this dialog. I need, that when user tap on a button, dialog will appear and fills 85% of screen. How to do this?

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
    }
}

You can do something like:

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

}

在此处输入图像描述

Always expanded to full height can be set in onCreateDialog of your BottomSheetDialogFragment()

    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
    val dialog = BottomSheetDialog(requireContext(), theme)
    dialog.behavior.state = BottomSheetBehavior.STATE_EXPANDED
    dialog.behavior.skipCollapsed = true
    return dialog
}

Max height can be set in 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
    }

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

and in your 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>

Just adding to mohammadReza Abiri's and Gabriele Mariotti's answer:

If you're getting null for BottomSheetBehavior, wrap it around CoordinatorLayout.

BottomSheetBehavior is applied to a child of CoordinatorLayout to make that child a persistent bottom sheet.

Persistent bottom sheets are views that come up from the bottom of the screen, elevated over the main content. They can be dragged vertically to expose more or less of their content.

Note: If you want to use Bottom Sheets that are modal (dialogs), use BottomSheetDialogFragment.

BottomSheetBehavior works in tandem with CoordinatorLayout to let you display content on a Bottom sheet (a layer on top of the main content), perform enter/exit animations, respond to dragging/swiping gestures, etc.

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

To programmatically control the bottom sheet you can call the setState method on the BottomSheetBehavior. A common pattern is setting a peek height and setting the state to collapsed to make it visible to the user:

bottomSheetBehavior.setPeekHeight(300);
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);

when your items height is too short and doesn't fill your bottom sheet and other way doesn't solve it try below code:

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**
             }
         })
   }

It is very easy to handle

Let's Start

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 
}

From the above case if you set maxHeight = WindowManager.LayoutParams.MATCH_PARENT

this is simple when you display some fixed onCreateView on your bottmsheet But some time if Update UI after Main Thread It may be not show actula height Some time then its better to use viewTreeObserver

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


}

In 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 width size of 95 percentage

configuration.screenWidth --> Give Screen Size

divideToPercent(0.40f) --> It will give some percentage from screen

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM