I'm using Bottom Sheet from Android support library like this:
XML:
<LinearLayout
android:id="@+id/bottomSheetLinearLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/fourth_white"
android:orientation="vertical"
app:layout_behavior="android.support.design.widget.BottomSheetBehavior" />
I add child views to LinearLayout:
bottomSheet.addView(actionButtonView);
After I've finished adding child views, I initialize BottomSheetBehavior and expand it:
BottomSheetBehavior sheetBehavior = BottomSheetBehavior.from(bottomSheet);
sheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
This doesn't work. Nothing shows. Even if I preset the LinearLayout height inside XML, it's just all white.
If I add all the child views inside LinearLayout in XML, then everything works fine. It just doesn't work when I try to dynamically add views programatically.
Anyone had any similar issues?
Troubles with dynamic content on BottomSheetBehavior related to implementation of it's expanded size calculation. BottomSheetBehavior calculates expanded size in onLayoutChild method. But when you change content of sheet layout process launches asynchronous. Even if you call RequestLayout or something similar. So consequence of calls is like this:
It is surely the bug of BottomSheetBehaviour implementation.
In my project I found such workaround:
private void showPanel(final View panelContent) {
if (panelBehavior.getState()!=BottomSheetBehavior.STATE_EXPANDED) {
panelBehavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
@Override
public void onStateChanged(final View bottomSheet, int newState) {
if (newState==BottomSheetBehavior.STATE_EXPANDED) {
panelBehavior.setBottomSheetCallback(null);
contentView.removeAllViews();
contentView.addView(panelContent);
panelView.setVisibility(View.VISIBLE);
}
}
@Override
public void onSlide(View bottomSheet, float slideOffset) {
}
});
panelBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
return;
}
contentView.removeAllViews();
contentView.addView(panelContent);
panelView.setVisibility(View.VISIBLE);
}
private void hidePanel() {
panelBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
panelView.setVisibility(View.GONE);
contentView.removeAllViews();
}
So when you need to show BottomSheet with new content call ShowPanel. When you need to completely hide BottomSheet call hidePanel (if you need to hide it in your project. If not you could remove setVisibility from methods).
The idea of workaround is to never change content of BottomSheet when BottomSheetBehavior is not in expanded state. If state is not expanded just change it to expanded, wait until animation finished and only then change content.
Try to post runnable to view's message queue:
bottomSheet.post(new Runnable() {
@Override
public void run() {
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
}
});
Or with retrolambda:
bottomSheet.post(() -> bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With