How to set max height in BottomSheetDialogFragment?
Asked Answered
V

8

14

enter image description hereI 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?

Vite answered 31/10, 2019 at 21:58 Comment(1)
post your XML and your activity code!Holcombe
O
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
    }
}
Officialese answered 13/10, 2020 at 15:41 Comment(2)
BottomSheetBehavior.STATE_EXPANDEDAy
Unresolved reference: setExpandedOffsetLesialesion
L
9

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

}

enter image description here

Legible answered 31/10, 2019 at 22:24 Comment(12)
I have a NullPointerException in BottomSheetBehaviour.from()...Vite
If you are using the support library use android.support.design.R.id.design_bottom_sheet instead of R.id.design_bottom_sheet. With the material components library you can also use com.google.android.material.R.id.design_bottom_sheet.Legible
I dont understand you. It is a simple id and i am not using the support libraryVite
@YorkIsMine It is the id provided by the BottomSheet component (material components or support library). It is not in my xml layout.Legible
oh, I understood, but i still have the same ExceptionVite
@YorkIsMine which version are you using? and are you using the code in the onCreateDialog method?Legible
I have androidx material library and i have the same codeVite
Which version of material components? 1.0.0 or 1.1.0 ?Legible
@YorkIsMine You should try with 1.1.0-beta01Benzoin
Thank you. Please note that, setState(BottomSheetBehavior.STATE_EXPANDED) will remove round corner of bottom sheet dialog, in material design 3.Aggregate
@CheokYanCheng It happens also with M2. Check this answer if the workaround works also for M3.Legible
Oh, I miss thought corner is only introduced in M3. What I am doing is eliminate setState(BottomSheetBehavior.STATE_EXPANDED) all together, and use styling way to make the bottom sheet not drag-able. Here's my method - github.com/yccheok/wediary-sandbox/blob/master/bottom-sheet/app/…Aggregate
L
6

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
    }
Limited answered 17/9, 2020 at 7:48 Comment(0)
H
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);

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>
Holcombe answered 31/10, 2019 at 22:30 Comment(1)
and how to get behavior? A always get or NPE, or Fatal errorVite
L
1

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
    }


}
Lerner answered 10/12, 2021 at 5:5 Comment(0)
I
1

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

configuration.screenWidth --> Give Screen Size

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

Isolationism answered 22/9, 2022 at 16:57 Comment(0)
J
0

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**
             }
         })
   }
Jeuz answered 4/10, 2020 at 10:1 Comment(1)
Generally, answers are much more helpful if they include an explanation of what the code is intended to do, and why that solves the problem without introducing others.Terminal
B
-1

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);
Botanize answered 21/11, 2019 at 22:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.