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?

Gabriele Mariotti
  • 320,139
  • 94
  • 887
  • 841

8 Answers8

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
    }
}
PeterPazmandi
  • 533
  • 10
  • 13
Yeldar Nurpeissov
  • 1,786
  • 14
  • 19
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

Gabriele Mariotti
  • 320,139
  • 94
  • 887
  • 841
  • I have a NullPointerException in BottomSheetBehaviour.from()... –  Oct 31 '19 at 22:37
  • 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`. – Gabriele Mariotti Oct 31 '19 at 22:47
  • I dont understand you. It is a simple id and i am not using the support library –  Oct 31 '19 at 22:51
  • @YorkIsMine It is the id provided by the BottomSheet component (material components or support library). It is not in my xml layout. – Gabriele Mariotti Oct 31 '19 at 22:53
  • oh, I understood, but i still have the same Exception –  Oct 31 '19 at 22:58
  • @YorkIsMine which version are you using? and are you using the code in the onCreateDialog method? – Gabriele Mariotti Oct 31 '19 at 22:59
  • I have androidx material library and i have the same code –  Oct 31 '19 at 23:03
  • Which version of material components? 1.0.0 or 1.1.0 ? – Gabriele Mariotti Oct 31 '19 at 23:06
  • @YorkIsMine You should try with `1.1.0-beta01` – MatPag Oct 31 '19 at 23:57
  • Thank you. Please note that, `setState(BottomSheetBehavior.STATE_EXPANDED)` will remove round corner of bottom sheet dialog, in material design 3. – Cheok Yan Cheng Jan 18 '23 at 15:12
  • @CheokYanCheng It happens also with M2. Check this [answer](https://stackoverflow.com/a/57627229/2016562) if the workaround works also for M3. – Gabriele Mariotti Jan 18 '23 at 15:16
  • 1
    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 - https://github.com/yccheok/wediary-sandbox/blob/master/bottom-sheet/app/src/main/java/com/yocto/bottom_sheet/DemoBottomDialogFragment.java#L52 – Cheok Yan Cheng Jan 18 '23 at 15:40
5

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
    }
MakinTosH
  • 623
  • 7
  • 12
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>
mohammadReza Abiri
  • 1,759
  • 1
  • 9
  • 20
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
    }


}
Tarif Chakder
  • 1,708
  • 1
  • 11
  • 10
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

Tippu Fisal Sheriff
  • 2,177
  • 11
  • 19
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**
             }
         })
   }
  • 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. – DCCoder Oct 04 '20 at 16:15
-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);
Pavitra Kansara
  • 819
  • 8
  • 14