This GIF pretty much shows what I am talking about:
I have a fairly complicated DrawerLayout -> CoordinatorLayout -> ViewPager -> Fragment -> RecyclerView situation going on in my app.
When a user long clicks on one of the items in the RecyclerView it sends a Broadcast to the ParentActivity which then signals the BottomSheet to appear.
Usually it works fine but every once in a while the BottomSheet doesn't appear. I have a FrameLayout that acts as an overlay between the ParentActivity and the ViewPager. When you click the Overlay it tells the BottomSheet to collapse. You can see in the GIF above, that in situations when the BottomSheet does not appear it still animates on collapse.
This behavior happens pretty frequently on my Nexus 5 Genymotion (API 21) emulator. On real devices it almost never happens, but it does sometimes.
What I have noticed is that if I do the long click and hold until the BottomSheet appears, it always appears. It's when I release immediately after the long click is registered that the BottomSheet might not appear.
I'm fairly certain that this is a situation where the RecyclerView is interfering in some way, but I can't really figure out why or how. Any debugging tips would be appreciated.
For reference here is the layout in question:
<android.support.v4.widget.DrawerLayout android:id="@+id/drawer_layout"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/gray"
android:fitsSystemWindows="true">
<android.support.design.widget.CoordinatorLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:id="@+id/app_bar_layout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar">
<android.support.design.widget.CollapsingToolbarLayout
android:id="@+id/collapsing_toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:contentScrim="?attr/colorPrimary"
app:expandedTitleMarginEnd="64dp"
app:expandedTitleMarginStart="48dp"
app:layout_scrollFlags="scroll|exitUntilCollapsed|snap">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="@color/green"
android:elevation="4dp"
android:theme="@style/ThemeOverlay.AppCompat.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light" />
<android.support.design.widget.TabLayout
android:id="@+id/budget_display_mode_tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@color/green"
android:elevation="4dp"
android:visibility="gone"
app:tabGravity="fill"
app:tabIndicatorColor="@color/green"
app:tabMode="fixed" />
</LinearLayout>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="@+id/view_pager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior" >
<LinearLayout
android:id="@+id/content"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/gray"
android:orientation="vertical" />
</FrameLayout>
<FrameLayout
android:id="@+id/primary_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="?attr/actionBarSize"
android:background="@null"
android:orientation="vertical">
<ProgressBar
android:id="@+id/progress"
style="@style/ProgressBar"/>
</FrameLayout>
<LinearLayout
android:id="@+id/full_screen_overlay"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone"
android:background="@color/blackLight"
android:orientation="vertical"/>
<LinearLayout
android:id="@+id/bottom_sheet"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipToPadding="true"
android:background="@color/gray"
android:orientation="vertical"
app:layout_behavior="android.support.design.widget.BottomSheetBehavior">
<TextView
android:id="@+id/bottom_edit"
style="@style/BottomSheetButton"
android:text="@string/option 1"/>
</LinearLayout>
</android.support.design.widget.CoordinatorLayout>
<android.support.v7.widget.RecyclerView
android:id="@+id/nav_list"
android:layout_width="300dp"
android:layout_height="match_parent"
android:layout_gravity="left|start"
android:background="@color/kEDColorGrayLightest" />
</android.support.v4.widget.DrawerLayout>
primaryView
and content
are set to View.GONE
when the ViewPager is turned on.
This is the receiver that triggers the BottomSheet:
private final BroadcastReceiver modifyBudgetItemBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(final Context context, final Intent intent) {
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
fullScreenOverlay.setVisibility(View.VISIBLE);
}
};
UPDATE: I have a sub-optimal work around in place. I have BottomSheetBehavior state listener that waits for the BottomSheet to be Expand and it does bottomSheet.requestLayout()
this causes the sheet to at least appear. The experience is poor though because the sheet appears to 'flicker' in, instead of sliding up. The requestLayout
work around doesn't seem to produce a flicker on real devices.
This is the known issue as dicussed by google developers On some Pre-lollipop devices bottom sheet does not work
I found a solution after R&D for a day. Try this
ViewCompat.postOnAnimation(yourCoordinator, new Runnable() {
@Override
public void run() {
ViewCompat.postInvalidateOnAnimation(yourCoordinator);
}
});
Put this code after initializing views
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