BottomSheetDialogFragment - How to set expanded height (or min top offset)
Solution 1
The height is being wrapped because the inflated view is added to the FrameLayout which has layout_height=wrap_content
. See FrameLayout (R.id.design_bottom_sheet) at https://github.com/dandar3/android-support-design/blob/master/res/layout/design_bottom_sheet_dialog.xml.
The class below makes the bottom sheet full screen, background transparent, and fully expanded to the top.
public class FullScreenBottomSheetDialogFragment extends BottomSheetDialogFragment {
@CallSuper
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
ButterKnife.bind(this, view);
}
@Override
public void onStart() {
super.onStart();
Dialog dialog = getDialog();
if (dialog != null) {
View bottomSheet = dialog.findViewById(R.id.design_bottom_sheet);
bottomSheet.getLayoutParams().height = ViewGroup.LayoutParams.MATCH_PARENT;
}
View view = getView();
view.post(() -> {
View parent = (View) view.getParent();
CoordinatorLayout.LayoutParams params = (CoordinatorLayout.LayoutParams) (parent).getLayoutParams();
CoordinatorLayout.Behavior behavior = params.getBehavior();
BottomSheetBehavior bottomSheetBehavior = (BottomSheetBehavior) behavior;
bottomSheetBehavior.setPeekHeight(view.getMeasuredHeight());
((View)bottomSheet.getParent()).setBackgroundColor(Color.TRANSPARENT)
});
}
}
--- EDIT Aug 30, 2018 --- I realized a year later that the background was colored on the wrong view. This dragged the background along with the content while a user was dragging the dialog. I fixed it so that the parent view of the bottom sheet is colored.
Solution 2
I found a much simpler answer; in your example where you obtain the FrameLayout for the bottom sheet using this code
View bottomSheet = dialog.findViewById(R.id.design_bottom_sheet);
you can then set the height on the layout params for that View to whatever height you want to set the expanded height to.
bottomSheet.getLayoutParams().height = ViewGroup.LayoutParams.MATCH_PARENT;
Solution 3
BIG UPDATE Avoiding duplicated code I'm giving a link to the full answer in where you can find all the explanations about how to get full behavior like Google Maps.
I want to adjust its maximum expanded height. How can I do that?
Both BottomSheet
and BottomSheetDialogFragment
use a BottomSheetBehavior that you can found in Support Library 23.x
That Java class has 2 different uses for mMinOffset
, one of them is used to define the area of the parent it will use to draw his content (maybe a NestedScrollView
). And the other use is for defining the expanded anchor point, I mean, if you slide it up to form STATE_COLLAPSED
it will animate your BottomSheet
until he reached this anchor point BUT if you can still keep sliding up to cover all parent height (CoordiantorLayout Height).
If you took a look at BottomSheetDialog
you will see this method:
private View wrapInBottomSheet(int layoutResId, View view, ViewGroup.LayoutParams params) {
final CoordinatorLayout coordinator = (CoordinatorLayout) View.inflate(getContext(),
android.support.design.R.layout.design_bottom_sheet_dialog, null);
if (layoutResId != 0 && view == null) {
view = getLayoutInflater().inflate(layoutResId, coordinator, false);
}
FrameLayout bottomSheet = (FrameLayout) coordinator.findViewById(android.support.design.R.id.design_bottom_sheet);
BottomSheetBehavior.from(bottomSheet).setBottomSheetCallback(mBottomSheetCallback);
if (params == null) {
bottomSheet.addView(view);
} else {
bottomSheet.addView(view, params);
}
// We treat the CoordinatorLayout as outside the dialog though it is technically inside
if (shouldWindowCloseOnTouchOutside()) {
final View finalView = view;
coordinator.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
if (isShowing() &&
MotionEventCompat.getActionMasked(event) == MotionEvent.ACTION_UP &&
!coordinator.isPointInChildBounds(finalView,
(int) event.getX(), (int) event.getY())) {
cancel();
return true;
}
return false;
}
});
}
return coordinator;
}
No idea which one of those 2 behaviors you want but if you need the second one follow those steps:
-
Create a Java class and extend it from
CoordinatorLayout.Behavior<V>
-
Copy paste code from the default
BottomSheetBehavior
file to your new one. -
Modify the method
clampViewPositionVertical
with the following code:@Override public int clampViewPositionVertical(View child, int top, int dy) { return constrain(top, mMinOffset, mHideable ? mParentHeight : mMaxOffset); } int constrain(int amount, int low, int high) { return amount < low ? low : (amount > high ? high : amount); }
-
Add a new state
public static final int STATE_ANCHOR_POINT = X;
-
Modify the next methods:
onLayoutChild
,onStopNestedScroll
,BottomSheetBehavior<V> from(V view)
andsetState
(optional)
And here is how it looks like
[]
Solution 4
Its works for me. Add code on BottomSheetDialogFragment's onViewCreated() methode
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
view.viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener {
override fun onGlobalLayout() {
view.viewTreeObserver.removeOnGlobalLayoutListener(this)
val dialog = dialog as BottomSheetDialog
val bottomSheet = dialog.findViewById<View>(com.google.android.material.R.id.design_bottom_sheet) as FrameLayout?
val behavior = BottomSheetBehavior.from(bottomSheet!!)
behavior.state = BottomSheetBehavior.STATE_EXPANDED
val newHeight = activity?.window?.decorView?.measuredHeight
val viewGroupLayoutParams = bottomSheet.layoutParams
viewGroupLayoutParams.height = newHeight ?: 0
bottomSheet.layoutParams = viewGroupLayoutParams
}
})
dialogView = view
}
Don't forget to remove viewTreeObserver.
override fun onDestroyView() {
dialogView?.viewTreeObserver?.addOnGlobalLayoutListener(null)
super.onDestroyView()
}
Solution 5
Get reference to sheet behavior,
private val behavior by lazy { (dialog as BottomSheetDialog).behavior }
turn fitToContents
off and set expandedOffset
to desired pixels.
behavior.isFitToContents = false
behavior.expandedOffset = 100
prom85
Updated on July 05, 2022Comments
-
prom85 almost 2 years
I create a
BottomSheetDialogFragment
and I want to adjust it's maximum expanded height. How can I do that? I can retrieve theBottomSheetBehaviour
but all I can find is a setter for the peek height but nothing for the expanded height.public class DialogMediaDetails extends BottomSheetDialogFragment { @Override public void setupDialog(Dialog dialog, int style) { super.setupDialog(dialog, style); View view = View.inflate(getContext(), R.layout.dialog_media_details, null); dialog.setContentView(view); ... View bottomSheet = dialog.findViewById(R.id.design_bottom_sheet); BottomSheetBehavior behavior = BottomSheetBehavior.from(bottomSheet); behavior.setPeekHeight(...); // how to set maximum expanded height???? Or a minimum top offset? } }
EDIT
Why do I need that? Because I show a
BottomSheet
Dialog in a full screen activity and it looks bad if theBottomSheet
leaves a space on top...-
eRaisedToX about 7 yearsI am interested in knowing that how can I set
max height
for `modal bottom sheet``. I need my modal bottom sheet to go till half screen only and never till top even after dragging...Any clues? -
Pratik Butani over 5 years@abat Hope it will helps : stackoverflow.com/a/53791225/1318946
-
Pratik Butani over 5 years@eRaisedToX You can also try : stackoverflow.com/a/53791225/1318946
-
-
hmac almost 4 yearswith androidX use:
dialog?.findViewById<View>( com.google.android.material.R.id.design_bottom_sheet )
-
hmac almost 4 yearswith androidX use:
dialog?.findViewById<View>( com.google.android.material.R.id.design_bottom_sheet )
-
hmac almost 4 yearscan someone explain why the find bottom sheet view doesn't seem to work from
onCreateDialog
oronViewCreated
? -
Javad B almost 4 yearsThis is a great solution! Thanks for this complete answer Miguel
-
Owen Chen about 3 yearsUsing
addOnGlobalLayoutListener
will cause screen flash, the main logic can be legal inonViewCreated
-
akashzincle about 3 yearsone thing I noticed, this works, only when the parent layout of our bottomsheet is RelativeLayout
-
akashzincle about 3 yearsOne thing I noticed, decorview is considering Navigation view height too, so any view aligned bottom of parent is cutting at the bottom, after replacing activity?.window?.decorView?.measuredHeight with height fetched in pixels using displaymetrics, worked for me
-
Shailendra Madda about 2 years
View bottomSheet = dialog.findViewById(R.id.design_bottom_sheet); bottomSheet.getLayoutParams().height = ViewGroup.LayoutParams.MATCH_PARENT;
This is what I am looking for