BottomSheetDialogFragment - How to set expanded height (or min top offset)
Sure, here's a comprehensive answer to how to set the expanded height (or min top offset) of a BottomSheetDialogFragment:
BIG UPDATE:
To avoid duplicated code, you can find a complete answer with explanations for achieving full behavior like Google Maps at this link:
[Link to Full Answer]
Question:
I want to adjust the maximum expanded height of a BottomSheetDialogFragment. How can I do that?
Answer:
Both BottomSheet and BottomSheetDialogFragment use a BottomSheetBehavior that you can found in Support Library 23.x.
That Java class has two different uses for mMinOffset. One of them is used to define the area of the parent it will use to draw its content (maybe a NestedScrollView). The other use is for defining the expanded anchor point. If you slide it up to form STATE_COLLAPSED, it will animate your BottomSheet until it reaches this anchor point, but you can still keep sliding up to cover all parent height (CoordinatorLayout Height).
If you need the second behavior, follow these steps:
1. Create a Java class and extend it from CoordinatorLayout.Behavior.
2. Copy-paste code from the default BottomSheetBehavior file to your new one.
3. Modify the clampViewPositionVertical method 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);
}
```
4. Add a new state:
```
public static final int STATE_ANCHOR_POINT = X;
```
5. Modify the following methods: onLayoutChild, onStopNestedScroll, BottomSheetBehavior from(V view), and setState (optional).
Example:
Here's an example of how it looks like:
[Image of CustomBottomSheetBehavior with 3 states]
Another Answer:
A much simpler answer is to obtain the FrameLayout for the bottom sheet using the following code:
```
View bottomSheet = dialog.findViewById(R.id.design_bottom_sheet);
```
Once you have the FrameLayout, you can set the height on the layout params for that View to whatever height you want to set the expanded height to.
For example:
```
bottomSheet.getLayoutParams().height = ViewGroup.LayoutParams.MATCH_PARENT;
```
Yet Another Answer:
The height is being wrapped because the inflated view is added to the FrameLayout which has layout_height=wrap_content. To make the bottom sheet full screen, background transparent, and fully expanded to the top, you can use the following class:
```java
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)
});
}
}
```
Kotlin Solution:
In Kotlin, you can define a fixed height by using the following code:
```kotlin
val bottomSheet: View? = dialog.findViewById(R.id.design_bottom_sheet)
BottomSheetBehavior.from(bottomSheet!!).peekHeight = 250
```
Accessing BottomSheetBehavior Directly:
You can also access the BottomSheetBehavior directly to set the peek height or other properties. For example:
```kotlin
val behavior by lazy { (dialog as BottomSheetDialog).behavior }
behavior.isFitToContents = false
behavior.expandedOffset = 100
```
Setting Expanded Height for Jetpack Compose Views:
For Jetpack Compose views inside BottomSheetDialogFragment, you can override the onCreateDialog() method:
```kotlin
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val dialog = super.onCreateDialog(savedInstanceState)
dialog.setOnShowListener { dialogInterface ->
val bottomSheetDialog = dialogInterface as? BottomSheetDialog
bottomSheetDialog?.behavior?.setPeekHeight(3000)
}
return dialog
}
```
Conclusion:
There are several ways to set the expanded height (or min top offset) of a BottomSheetDialogFragment. The best approach depends on your specific requirements and the version of the Android Support Library you are using. However, the solutions mentioned above provide a comprehensive overview of the possible options.