Search code examples
javaandroidandroid-coordinatorlayoutandroid-bottomappbar

How to override CoordinatorLayout.Behavior without breaking CoordinatorLayout.LayoutParams


I'm creating an Android application and I want to hide the BottomAppBar (it has a fab anchored on the center) whenever I scroll the RecyclerView who's inside the fragment of my activity without changing the layout of the BottomAppBar.

Following some online guides, I've created my own class that extends CoordinatorLayout.Behavior and override onStartNestedScroll & onNestedPreScroll so that the BottomAppBar get hidden whenever I scroll.

<android.support.design.widget.CoordinatorLayout ...>
    ...
    <android.support.design.bottomappbar.BottomAppBar
        style="@style/Widget.MaterialComponents.BottomAppBar"
        android:id="@+id/bottom_app_bar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom"
        app:backgroundTint="@color/colorPrimary"
        app:fabAlignmentMode="center"
        app:fabCradleRoundedCornerRadius="15dp"/>

    <android.support.design.widget.FloatingActionButton
        android:id="@+id/fab"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/ic_add_white_24dp"
        app:layout_anchor="@id/bottom_app_bar" />
</android.support.design.widget.CoordinatorLayout>
BottomAppBar bab = (BottomAppBar) findViewById(R.id.bottom_app_bar);
CoordinatorLayout.LayoutParams layoutParams = (CoordinatorLayout.LayoutParams) bab.getLayoutParams();
BottomNavigationBehavior bnb = new BottomNavigationBehavior();
layoutParams.setBehavior(bnb);



class BottomNavigationBehavior<V extends View> extends CoordinatorLayout.Behavior<V>{

    @Override
    public boolean onStartNestedScroll(@NonNull CoordinatorLayout coordinatorLayout, @NonNull V child, @NonNull View directTargetChild, @NonNull View target, int axes, int type) {
        return axes == ViewCompat.SCROLL_AXIS_VERTICAL;
    }

    @Override
    public void onNestedPreScroll(@NonNull CoordinatorLayout coordinatorLayout, @NonNull V child, @NonNull View target, int dx, int dy, @NonNull int[] consumed, int type) {
        super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed, type);
        child.setTranslationY(Math.max(0f, Math.min(child.getHeight(),child.getTranslationY() + dy)));
    }
}

Without the custom class, this is the (desired) result (but the scrolling-hiding behavior is obviously not working)

Desired layout

With the custom class, this is the (unwanted) result (but the scrolling-hiding behavior does work)

Undesired layout

I thought that since I'm not modifying the layoutParams parameters but only the behavior the layout should be the same, but obviously there's something I'm missing...
Does anybody know how to fix this?


Solution

  • I only glanced through source code, but drawing cutout is part of default BottomAppBar.Behavior.

    Your best bet is having your custom behavior extend it instead of empty CoordinatorLayout.Behavior (or at least copy relevant code for drawing cutout) and work Your way up from there.

    By the way, is app:hideOnScroll (related question) not working for You?