In a BottomSheetDialogFragment
, I want to inflate a view that always stick at the bottom of the screen, no matter what state (collapsed / expanded) the BottomSheetBehavior
is in.
In a subclass of BottomSheetDialogFragment
, I inflate a view from XML and add it as a child of CoordinatorLayout
(which is BottomSheetDialogFragment
's parent's parent):
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
setupBottomBar(getView());
}
private void setupBottomBar (View rootView) {
CoordinatorLayout parentView = (CoordinatorLayout) ((FrameLayout)rootView.getParent()).getParent();
parentView.addView(LayoutInflater.from(getContext()).inflate(R.layout.item_selection_bar, parentView, false), -1);
}
The code runs without error.
And when I use Layout Inspector to look at the View hierarchy, the view structure is also correct:
You can also download the layout inspector result here, and open it using your own Android Studio.
However, even though it is inserted as the last child of the CoordinatorLayout
, it is still being blocked by the BottomSheetDialogFragment
.
When I slowly scroll the BottomSheetDialogFragemnt
downwards (from collapsed state to hidden state), I can finally see the view that I want to inflate behind the fragment.
Why is this happening?
As @GoodDev pointed out correctly, it is because the root view (design_bottom_sheet) has been set a Z translation by BottomSheetDialog
.
This provides an important information that - not only sequence in a View hierarchy will determine its visibility, but also its Z translation.
The best way is to get the Z value of design_bottom_sheet
and set it to the bottom bar layout.
private void setupBottomBar (View rootView) {
CoordinatorLayout parentView = (CoordinatorLayout) (rootView.getParent().getParent());
View barView = LayoutInflater.from(getContext()).inflate(R.layout.item_selection_bar, parentView, false);
ViewCompat.setTranslationZ(barView, ViewCompat.getZ((View)rootView.getParent()));
parentView.addView(barView, -1);
}
EDIT 2
Ok, now I see your requirement, try this one:
private void setupBottomBar (View rootView) {
CoordinatorLayout parentView = (CoordinatorLayout) ((FrameLayout)rootView.getParent()).getParent();
View view = LayoutInflater.from(getContext()).inflate(R.layout.item_selection_bar, parentView, false);
// using TranslationZ to put the view on top of bottom sheet layout
view.setTranslationZ(100);
parentView.addView(view, -1);
}
EDIT:
OK, I check your layout and check the BottomSheetDialogFragment
source code, found the reason:
In BottomSheetDialogFragment
using BottomSheetDialog
dialog, the method setContentView
in BottomSheetDialog using wrapInBottomSheet
to put the content view in R.id.design_bottom_sheet
layout. So you need override the BottomSheetDialogFragment
's public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
to fix your problem.
Or, change your setupBottomBar
method to:
private void setupBottomBar (View rootView) {
FrameLayout frame = (FrameLayout)rootView.getParent();
frame.addView(LayoutInflater.from(getContext()).inflate(R.layout.item_selection_bar, frame, false), -1);
}
and in your item_selection_bar
layout file, change height and layout_gravity:
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_gravity="bottom"
android:layout_width="match_parent"
android:layout_height="wrap_content">
BottomSheetDialogFragment doc says: Modal bottom sheet. This is a version of DialogFragment that shows a bottom sheet using BottomSheetDialog
instead of a floating dialog.
So the BottomSheetDialogFragment
is a Dialog
, Dialog
is a floating view, so will cover the Activity content when BottomSheetDialogFragment
is showing.