Using a Persistent BottomSheet, within a CoordinatorLayout, how can one prevent the BottomSheet from covering other user interface elements when the BottomSheet is in its COLLAPSED aka peeked state?
I've successfully added a BottomSheet to my Navigation Drawer & Fragment based application; however, as mentioned above, the BottomSheet covers user interface elements within my fragment container when it's either COLLAPSED or EXPANDED
Covering part of the fragment is ok when the BottomSheet is expanded since, if needed, users can collapse the BottomSheet to its peek state. However, I've explicitly disabled* the user from hiding the BottomSheet and thus need a way of ensuring the fragment container remains above the BottomSheet at all times when the BottomSheet is in its collapsed state. Photos are worth a thousand words so hopefully the following clarify the issue
Above: A redacted screenshot of a fragment with two buttons, A & B, near the bottom of the screen. Note: The fragment's root is a scrollview which is why button B is cut off by the System's Back and Home buttons
Above: The same fragment as seen above but with the BottomSheet fully expanded. For reference the BottomSheet is everything below and including the green bar. Note: The fact that the BottomSheet covers button A & B is ok since the BottomSheet is fully expanded
Above: The same fragment as seen above but with the BottomSheet in its collapsed state. Note: Now that the BottomSheet is fully collapsed and cannot be collapsed further the issue can be seen in that it covers part of button B and more importantly the fragment scrolls below the BottomSheet
Originally I was hoping to fix the issue by subclassing AppBarLayout.ScrollingViewBehavior similar to this answer. Sadly I was unable adjust the child
view's height
within CoordinatorLayout.Behavior#onDependentViewChanged. When called, the child
's height
appears unset (-1
) and adding a OnLayoutChangedListener
requires the child
to be final
making it impossible to update the height
once the height
is defined in the layout changed listener callback. I'd still like to solve the problem using a subclassed Behavior
but for the time being I'm stumped
My next thought was to add a "spacer" view to each of my fragment layouts using the <include/>
tag. I then could provide add/show
and remove/hide
helper methods to an abstract
base fragment class which all fragments needing to display the BottomSheet would extend. This spacer view would be programmatically assigned the peek height
of the BottomSheet making room for it within the fragment. The BottomSheet would then cover the spacer view which is fine since I don't consider it part of the fragment's usable view area. I'm currently working on implementing this approach and while I think it'll work I'm skeptical it's good solution
Any advice, suggestions, and potential solutions are welcome and thanks in advance!
And to clarify below is a condensed version of my top-level application layout
<android.support.v4.widget.DrawerLayout>
<android.support.design.widget.CoordinatorLayout>
<android.support.design.widget.AppBarLayout>
<android.support.design.widget.CollapsingToolbarLayout>
<ImageView ... />
<android.support.v7.widget.Toolbar ... />
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<!-- All fragments assume the following view container via a FragmentTransaction's
replace method which in pseudocode looks something like
FragmentTransaction.replace(R.id.main_activity_fragment_container,
fragment, ...).commit();
-->
<FrameLayout android:id="@+id/main_activity_fragment_container" ... />
<com.xyz.abc.view.BottomSheetView ... />
<android.support.design.widget.FloatingActionButton ... />
</android.support.design.widget.CoordinatorLayout>
<android.support.design.widget.NavigationView ... />
</android.support.v4.widget.DrawerLayout>
*It appears BottomSheetBehavior#mHideable}
is false
by default