Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android FAB HideBottomViewOnScrollBehavior statys hidden after changing fragments

I am using a drawer navigation (combined with android navigation jetpack component) to navigate between several fragments. I am using app:layout_behavior="com.google.android.material.behavior.HideBottomViewOnScrollBehavior" on my Floating Action Button (which is placed inside a coordinator layout) to hide the FAB when i scroll up and then it reappears when i scroll down. My layout is as follows:

activity_main.xml

<androidx.drawerlayout.widget.DrawerLayout
    android:id="@+id/Drawer_Main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".ui.main.main.MainActivity">

    <androidx.coordinatorlayout.widget.CoordinatorLayout
        android:id="@+id/Layout_Coordinator_Main"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:fitsSystemWindows="true">
...

       <com.google.android.material.floatingactionbutton.FloatingActionButton
            android:id="@+id/FAB_Add"
            style="@style/Locky.FloatingActionButton.Normal"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_gravity="bottom|end"
            android:layout_margin="@dimen/fab_margin"
            app:layout_behavior="com.google.android.material.behavior.HideBottomViewOnScrollBehavior"
            app:srcCompat="@drawable/ic_add" />


</androidx.coordinatorlayout.widget.CoordinatorLayout>

</androidx.drawerlayout.widget.DrawerLayout>

The behaviour is working as expected. However if i scroll up and it hides the FAB and then i switch screen, the FAB stays hidden. I could've scrolled down for the FAB to reappear but in some cases when i can't scroll down (when my recyclerview is empty), there is no way for the FAB to reappear.

I tried to do something like this:

MainActivity.kt

private fun navigationDestinationChangeListener(navController: NavController) {
    navController.addOnDestinationChangedListener { nc, nd, _ ->
        when (nd.id) {
            nc.graph.startDestination,
            R.id.Fragment_Card,
            R.id.Fragment_Device -> {
                _binding.DrawerMain.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED)

                //Show all the FABs
                showFabs()
            }
            else -> {
                _binding.DrawerMain.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED)

                //Hide all the FABs
                hideFabs()
            }
        }
    }
}

I added a navigation destination change listener where i force the FAB to reappear in my showFabs() function but it's not working.

Can someone help me with a workaround on how to fix this? Or maybe a better way to code this in case I've been coding this the wrong way.

Thank you for your help.

like image 543
Mervin Hemaraju Avatar asked May 11 '20 17:05

Mervin Hemaraju


1 Answers

Change your "showFabs" by this

Kotlin

fun showFab(fab: FloatingActionButton, isVisible: Boolean) {
    val layoutParams: ViewGroup.LayoutParams = fab.layoutParams
    if (layoutParams is CoordinatorLayout.LayoutParams) {
        val behavior = layoutParams.behavior
        if (behavior is HideBottomViewOnScrollBehavior) {
            if (isVisible) {
                behavior.slideUp(fab)
            } else {
                behavior.slideDown(fab)
            }
        }
    }
}

Java

public void showFabs(FloatingActionButton fab, boolean visible) {
    ViewGroup.LayoutParams layoutParams = fab.getLayoutParams();
    if (layoutParams instanceof CoordinatorLayout.LayoutParams) {
        CoordinatorLayout.Behavior coordinatorLayoutBehavior =
            ((CoordinatorLayout.LayoutParams) layoutParams).getBehavior();
        if (coordinatorLayoutBehavior instanceof HideBottomViewOnScrollBehavior) {
            @SuppressWarnings("unchecked")
            HideBottomViewOnScrollBehavior<FloatingActionButton> behavior =
                (HideBottomViewOnScrollBehavior<FloatingActionButton>) coordinatorLayoutBehavior;
            if (visible) {
                behavior.slideUp(fab);
            } else {
                behavior.slideDown(fab);
            }
        }
    }
}

Until it's fixed by google, it's the only solution I found that works.

like image 104
Joris Avatar answered Oct 17 '22 23:10

Joris