Tunji_D
Tunji_D

Reputation: 3687

FloatingActionButton Behavior call back not working in DrawerLayout

I have a DrawerLayout with a Coordinator layout hosted as the main content. When I create a SnackBar with the Snackbar.make method, the FAB hosted in the Coordinator layout refuses to animate.

I find this odd, because I've used the same FAB in Coordinator layouts that aren't wrapped in a DrawerLayout and it animates just fine, leading to believe the DrawerLayout is somehow blocking the call back.

I've tried making the CoordinatorLayout the top level view, wrapping the DrawerLayout, but that also doesn't work. What I'm going to attempt is forking the FloatingActionButton Behavior class and making the updateFabTranslationForSnackbar method public so I can call it myself. I'd much rather not do this, so any ideas will be much appreciated.

For both activities, the Snackbar.make call is called from a fragment added dynamically to the RelativeLayout with the ID "container". The view passed to the call is the CoordinatorLayout in the activity XML with the id "coordinator_layout".

Again, everything works as it should in the first XML, but not in the second.

This is my default XML for other activities, the FAB animates fine here:

<android.support.design.widget.CoordinatorLayout
android:id="@+id/coordinator_layout"
android:name="com.app.mobile.app.ui.BusinessActivityFragment"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:fab="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">

<ProgressBar
    android:id="@+id/progress_bar"
    style="?android:attr/progressBarStyleLarge"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:layout_marginBottom="8dp" />

<RelativeLayout
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:visibility="gone">

    <ImageView
        android:id="@+id/background"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:scaleType="centerCrop"
        android:src="@drawable/bg_sign_up"
        android:visibility="invisible" />

    <View
        android:id="@+id/background_mask"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_alignParentTop="true"
        android:background="@color/black_40"
        android:visibility="invisible" />
</RelativeLayout>

<include
    android:id="@+id/action_bar"
    layout="@layout/toolbar"
    android:layout_width="match_parent"
    android:layout_height="@dimen/abc_action_bar_default_height_material"
    android:layout_gravity="top" />

<android.support.design.widget.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|end"
        android:layout_margin="16dp" />

<ProgressBar
    android:id="@+id/load_more"
    style="?android:attr/progressBarStyleHorizontal"
    android:layout_width="match_parent"
    android:layout_height="@dimen/half_margin"
    android:layout_gravity="bottom"
    android:indeterminate="true"
    android:visibility="gone" />

This is the XML for my main activity where the FAB refuses to animate:

<android.support.v4.widget.DrawerLayout
android:id="@+id/navigation_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"
tools:context="com.app.mobile.app.ui.HomeActivity">
<!-- As the main content view, the view below consumes the entire
     space available using match_parent in both dimensions. -->
<android.support.design.widget.CoordinatorLayout
    android:id="@+id/coordinator_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:animateLayoutChanges="true">
    <!-- Toolbar is the last item in the FrameLayout to cause it to overlay -->
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:animateLayoutChanges="true"
        android:orientation="vertical">

        <ProgressBar
            android:id="@+id/home_progress"
            style="?android:attr/progressBarStyleLarge"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:layout_gravity="center"
            android:layout_marginBottom="8dp" />

        <RelativeLayout
            android:id="@+id/container"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:visibility="gone" />
    </RelativeLayout>

    <include
        android:id="@+id/action_bar"
        layout="@layout/toolbar"
        android:layout_width="match_parent"
        android:layout_height="@dimen/abc_action_bar_default_height_material"
        android:layout_gravity="top" />

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|end"
        android:layout_margin="16dp" />

    <ProgressBar
        android:id="@+id/load_more"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="match_parent"
        android:layout_height="@dimen/half_margin"
        android:layout_gravity="bottom"
        android:indeterminate="true"
        android:visibility="gone" />
</android.support.design.widget.CoordinatorLayout>
<!-- android:layout_gravity="start" tells DrawerLayout to treat
     this as a sliding drawer on the left side for left-to-right
     languages and on the right side for right-to-left languages.
     If you're not building against API 17 or higher, use
     android:layout_gravity="left" instead. -->
<!-- The drawer is given a fixed width in dp and extends the full height of
     the container. -->
<fragment
    android:id="@+id/navigation_drawer"
    android:name="com.app.mobile.app.ui.NavigationDrawerFragment"
    android:layout_width="300dp"
    android:layout_height="match_parent"
    android:layout_gravity="start"
    android:tag="NAVIGATION_DRAWER_TAG"
    tools:layout="@layout/fragment_navigation_drawer" />

Upvotes: 1

Views: 1064

Answers (2)

Tunji_D
Tunji_D

Reputation: 3687

I found the solution. You apparently must move to the Navigation view widget in the new design library. Moving to this and keeping all else constant, the FAB animates again.

For implementation see The official blog post for the support libary and this demo of the library by Chris Banes.

This is not an ideal fix, as you lose the flexibility of a fragment to a static inflated XML resource, but it's the only way I've found to make the FAB still animate.

Upvotes: 0

natario
natario

Reputation: 25204

Make sure you are passing the right view to the Snackbar.make() method. As per the docs,

Snackbar will try and find a parent view to hold Snackbar's view from the value given to view. Snackbar will walk up the view tree trying to find a suitable parent, which is defined as a CoordinatorLayout or the window decor's content view, whichever comes first.

So you should pass a view that is actually inside the CoordinatorLayout, so that Snackbar will find the coordinator as the first parent available.

Upvotes: 1

Related Questions