6

How to set maximum expanded height in android support design bottom sheet?

The question is an extension to the above question, i want to set the max expanded height of the sheet but dynamically according to the screen size.

I have tried setting new layout params to the view implementing bottomsheet behaviour but it does nothing good.

saurabh dhillon
  • 798
  • 7
  • 17

4 Answers4

2

Please use this and chill :)

  1. const val BOTTOMSHEET_HEIGHT_TO_SCREEN_HEIGHT_RATIO = 0.80 //change according to your requirement
  2. override onCreateDialog() in your bottomsheetFragment

override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        val dialog = super.onCreateDialog(savedInstanceState) as BottomSheetDialog
        dialog.setOnShowListener {
            dialog.findViewById<FrameLayout>(com.google.android.material.R.id.design_bottom_sheet)
                ?.apply {
                    val maxDesiredHeight =
                        (resources.displayMetrics.heightPixels * BOTTOMSHEET_HEIGHT_TO_SCREEN_HEIGHT_RATIO).toInt()
                    if (this.height > maxDesiredHeight) {
                        val bottomSheetLayoutParams = this.layoutParams
                        bottomSheetLayoutParams.height = maxDesiredHeight
                        this.layoutParams = bottomSheetLayoutParams
                    }
                    BottomSheetBehavior.from(this)?.apply {
                        this.state = BottomSheetBehavior.STATE_EXPANDED
                        this.skipCollapsed = true
                    }
                }
        }
        return dialog
    }
1

2021 I'm late but someone will need Kotlin extenxion:

fun View.setupFullHeight(maxHeight: Double = 0.3) {
val displayMetrics = context?.resources?.displayMetrics
val height = displayMetrics?.heightPixels
val maximalHeight = (height?.times(maxHeight))?.toInt()
val layoutParams = this.layoutParams
maximalHeight?.let {
    layoutParams.height = it
}
this.layoutParams = layoutParams

}

How to use:

override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
    return object : BottomSheetDialog(requireContext(), R.style.DialogRoundedCornerStyle) {

        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)

            dialog?.setOnShowListener {
                val bottomSheetDialog = it as BottomSheetDialog
                val parentLayout =
                    bottomSheetDialog.findViewById<View>(R.id.design_bottom_sheet)
                parentLayout?.let { view ->
                    val behavior = BottomSheetBehavior.from(view)
                    view.setupFullHeight()
                    behavior.apply {
                        state = BottomSheetBehavior.STATE_EXPANDED
                        isDraggable = false
                        isCancelable = false
                    }
                }
            }
        }

        override fun onBackPressed() {
            super.onBackPressed()
            dialog?.dismiss()
        }
    }
}
Романыч
  • 247
  • 7
  • 13
0

The simplest solution is to set the maxHeight property of the bottom sheet like this.

DisplayMetrics displayMetrics = new DisplayMetrics();
        activity.getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
 bottomSheet.setMaxHeight((int) (displayMetrics.heightPixels * 0.65));
Nidhin Rejoice
  • 1,367
  • 1
  • 16
  • 26
-4

Finally found it,

This question troubled me a lot with no solution reported anywhere, and the answer lies in the behavior itself.

The minimum offset is the max value upto which the bottomsheet should move and we set the lower cap of the value to our desired height upto which we want the bottomsheet to move. You can expose a function to set the value or do it direclty in our behavior.

To dynamically set the max expanded height for bottomsheet we need to increase the minimum offset value from 0 to our desired value in BottomSheetBehavior class, let me show the code.

Happy coding!!

         // The minimum offset value upto which your bottomsheet to move
         private int mMinOffset;

        /**
          * Called when the parent CoordinatorLayout is about the layout the given child view.
          */
        @Override
        public boolean onLayoutChild(CoordinatorLayout parent, V child, int layoutDirection) {
               int dynamicHeight = Utils.dpToPx(parent.getContext(), **your_value_in_dp**);
               mMinOffset = Math.max(dynamicHeight, mParentHeight - child.getHeight());
               mMaxOffset = Math.max(mParentHeight - mPeekHeight, mMinOffset);
               mAnchorOffset = Math.min(mParentHeight - mAnchorHeight, mMaxOffset);

               if (mState == STATE_EXPANDED) {
                    ViewCompat.offsetTopAndBottom(child, mMinOffset);
                    anchorViews(mMinOffset);
               } 
        }
saurabh dhillon
  • 798
  • 7
  • 17
  • Not clear what you intended with this solution. Have you extended BottomSheetBehavior? Because mMaxOffset, mParentHeight, mPeekHeight are not public in that class, so I cannot understand how you implemented this – ARLabs Aug 16 '18 at 09:18
  • @ARLabs, Yes I have extended the bottom sheet behaviour and modified the values in 'onLayoutChild(CoordinatorLayout parent, V child, int layoutDirection)' method exposed by android. – saurabh dhillon Sep 07 '18 at 15:21
  • But you are using package-private members, so have you placed your custom BottomSheetBehavior in android.support.design.widget package? – ARLabs Sep 12 '18 at 13:23
  • @ARLabs No, why will i do that. I extended my behaviour with CoordinatorLayout.Behavior and pasted all methods in android sheet behaviour to my behaviour. – saurabh dhillon Sep 25 '18 at 09:20
  • Ok, sorry... you have not extended BottomSheetBehaviour... but cut/pasted from that. Thanks – ARLabs Sep 25 '18 at 09:36
  • @ARLabs, yes i have extended it with CoordinatorLayout.Behavior and pasted code from standard android behaviour to my new custom behaviour which makes it compilable. I hope this solves your issue please ping in case any more help needed. – saurabh dhillon Sep 25 '18 at 09:40
  • Isn't this too much pain. Why don't we just set max size of the bottom panel according to the screen size? – Nidhin Rejoice Feb 05 '19 at 20:54
  • In the latest release to date (**1.1.0-alpha07**) of `Material Components Android` there is a parameter for that : `behavior_expandedOffset`. Can be used in XML (but only pixeld, though, or in code via `BottomSheelBehavior#setExpandedOffset`. Works if `behavior_fitToContents` is set to **false** (set to true by default!). Check it out there: https://github.com/material-components/material-components-android/commit/e1222dd07f092892d10c97aa6811818bcb663c2d – Mackovich Jun 06 '19 at 15:10
  • @saurabhdhillon Can you just share some code as in i am not getting what you did? You extended a class with coordinator layout behaviour and pasting code of coordinator layout behaviour and nothing to do with bottom sheet behaviour . Right? – Lakshya Punhani Jul 27 '19 at 20:32
  • @LakshyaPunhani this is the exact code that will work, you need to create a custom behaviour and oveeride the method as above and replace the "your_value_in_dp". – saurabh dhillon Apr 25 '20 at 10:29
  • @WijaySharma let me know i will help you with the explanation, i got this to work when there was no feature like this, so i just override the private package method in BottomSheetBehavior by creating my own behaviour and explicitly mentioning the max height. – saurabh dhillon Apr 25 '20 at 10:32