g g
g g

Reputation: 107

toolbar blinks when switch between bottom nav fragments

【update】 Actually it's easy to reproduce the issue by just disabling the default ActionBar and adding Toolbar per fragment. Then you can see the toolbar blinks when switching bottom destinations. enter image description here Please check out the tiny demo at https://github.com/025nju/BottomNav

【original post】 I'm new on Android and my demo project is a BottomNav single activity project. I checked many posts and looks many people suffered from handling the toolbar in this senario, all fragments need to have its own toolbar.

The toolbar backgroud color blinks when switching between bottom tabs. Please see the gif and ignore the last blank frame. enter image description here

How to eliminate the blink? btw, no such issue when I was using the default ActionBar, which is not recommanded by official. I tested on Nexus 6 api26 AVD and a real handset android version 9. Same issue. Below is related code for your referrence. Thanks a lot.

FragmentMoney.xml:

<?xml version="1.0" encoding="utf-8"?>
<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">
<data>
</data>
<androidx.constraintlayout.widget.ConstraintLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".ui.money.MoneyFragment">

    <include android:id="@+id/fragment_base" layout="@layout/fragment_base"/>

    <TextView
        android:id="@+id/text_money"
        ... />
</androidx.constraintlayout.widget.ConstraintLayout>

fragment_base.xml which is for the toolbar defination:

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
<com.google.android.material.appbar.AppBarLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content">

    <com.google.android.material.appbar.MaterialToolbar
        android:id="@+id/mToolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="?attr/colorPrimary"
        android:elevation="4dp"
        android:theme="@style/ThemeOverlay.AppCompat.ActionBar"
        app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
        app:layout_constraintTop_toTopOf="parent">
    </com.google.android.material.appbar.MaterialToolbar>

</com.google.android.material.appbar.AppBarLayout>

</androidx.coordinatorlayout.widget.CoordinatorLayout>

MoneyFragment.java:

public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View root = fragmentMoneyBinding.getRoot();
    ...
    Toolbar mToolbar = (Toolbar) root.findViewById(R.id.mToolbar);
    mToolbar.setTitle(R.string.title_money);
    ((AppCompatActivity) getActivity()).setSupportActionBar(mToolbar);
    return root;
    }
}

activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent">

<fragment
    android:id="@+id/nav_host_fragment"
    android:name="androidx.navigation.fragment.NavHostFragment"
    android:layout_width="match_parent"
    android:layout_height="0dp"
    app:defaultNavHost="true"
    app:layout_constraintBottom_toTopOf="@+id/nav_view"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    app:navGraph="@navigation/mobile_navigation" />

<com.google.android.material.bottomnavigation.BottomNavigationView
    android:id="@+id/nav_view"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_marginStart="0dp"
    android:layout_marginEnd="0dp"
    android:background="?android:attr/windowBackground"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintTop_toBottomOf="@id/nav_host_fragment"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:menu="@menu/bottom_nav_menu" />

<com.google.android.material.floatingactionbutton.FloatingActionButton
    android:id="@+id/floatingActionButton"
    ... />

</androidx.constraintlayout.widget.ConstraintLayout>

MainActivity.java:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    BottomNavigationView navView = findViewById(R.id.nav_view);
    appBarConfiguration = new AppBarConfiguration.Builder(
            R.id.navigation_note, R.id.navigation_money, R.id.navigation_time)
            .build();
    navController = Navigation.findNavController(this, R.id.nav_host_fragment);
    NavigationUI.setupWithNavController(navView, navController);
}
...
}

Upvotes: 2

Views: 1130

Answers (1)

Michalsx
Michalsx

Reputation: 3621

You have to disable (replace) animation between fragments.

Create empty animation:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <!--Empty to disable animation-->
</set>

And put it into following files:

res/animator/nav_default_enter_anim.xml
res/animator/nav_default_exit_anim.xml
res/animator/nav_default_pop_enter_anim.xml
res/animator/nav_default_pop_exit_anim.xml

Upvotes: 6

Related Questions