how to make animation transition between fragments in navigation by drawer in android

Viewed 978

I have a drawer in my app and I switch fragments by navigation. I would like to have animation transition when I click on the button in the drawer. I know how to do it with regular button but I do not konw how to do it with navigation drawer Thank you.

this is my main Activity

class MainActivity : AppCompatActivity() {

    private lateinit var appBarConfiguration: AppBarConfiguration

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        setSupportActionBar(toolbar)

        val drawerLayout: DrawerLayout = findViewById(R.id.drawer_layout)
        val navView: NavigationView = findViewById(R.id.nav_view)
        val navController = findNavController(R.id.nav_host_fragment)

        appBarConfiguration = AppBarConfiguration(setOf(
            R.id.nav_food_text_analysis,
            R.id.nav_recipe_analysis
        ), drawerLayout)
        setupActionBarWithNavController(navController, appBarConfiguration)
        navView.setupWithNavController(navController)
    }

    override fun onSupportNavigateUp(): Boolean {
        val navController = findNavController(R.id.nav_host_fragment)
        return navController.navigateUp(appBarConfiguration) || super.onSupportNavigateUp()
    }


}

this is my navigation xml

<navigation 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/mobile_navigation"
    app:startDestination="@id/nav_food_text_analysis">

    <fragment
        android:id="@+id/nav_food_text_analysis"
        android:name="com.example.nutritionfacts.ui.foodTextAnalysis.FoodAnalysisFragment"
        android:label="Food analysis"
        tools:layout="@layout/fragment_food_text_analysis" >
        <action
            android:id="@+id/action_nav_food_text_analysis_to_nav_recipe_analysis"
            app:destination="@id/nav_recipe_analysis"
            app:enterAnim="@anim/enter_from_right"
            app:exitAnim="@anim/exit_to_right"
            app:popEnterAnim="@anim/enter_from_right"
            app:popExitAnim="@anim/exit_to_right" />
    </fragment>
    <fragment
        android:id="@+id/nav_recipe_analysis"
        android:name="com.example.nutritionfacts.ui.recipeAnalysis.RecipeAnalysisFragment"
        android:label="Recipe analysis"
        tools:layout="@layout/fragment_recipe_analysis" >
        <action
            android:id="@+id/action_nav_recipe_analysis_to_nav_food_text_analysis2"
            app:destination="@id/nav_food_text_analysis"
            app:enterAnim="@anim/enter_from_right"
            app:exitAnim="@anim/exit_to_right"
            app:popEnterAnim="@anim/enter_from_right"
            app:popExitAnim="@anim/exit_to_right" />
    </fragment>
</navigation>
1 Answers

I was just working on this and have a solution that listens for the navigation drawer clicks and reacts in the same way you would with a button.

I am using a single activity with several fragments. Make sure to set up the navigtaion graph for your fragments, then call the correct FragmentDirections action by using the setNavigationItemSelectedListener in the Main Activity.

In my example, the settingsFragment will be loaded with an animation but the aboutFragment will not since it doesn't call a Directions.action function.

MainActivity (inside onCreate function)

        /** Handle clicks in Nav Drawer **/
        val navigationView = findViewById<NavigationView>(R.id.navView)
        navigationView.setNavigationItemSelectedListener { menuItem ->
            Timber.d("Nav Drawer Item Clicked: %s", menuItem.title)
            when (menuItem.itemId) {
                R.id.settingsFragment -> {
                    navController.navigate(
                        RecipeListFragmentDirections
                        .actionRecipeListToSettingsFragment()
                    )
                }
                R.id.aboutFragment -> {
                    navController.navigate(R.id.aboutFragment)
                }
                R.id.refreshRecipes -> {
                    Timber.i("TODO: Implement repository refresh method call")
                }
            }

            true
        }

navigation.xml

<?xml version="1.0" encoding="utf-8"?>
<navigation 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/navigation"
    app:startDestination="@id/recipeList">

    <fragment
        android:id="@+id/recipeList"
        android:name="com.jumptuck.recipebrowser2.recipelist.RecipeListFragment"
        tools:layout="@layout/fragment_recipe_list">
        <action
            android:id="@+id/action_recipeList_to_singleRecipeFragment"
            app:destination="@id/singleRecipeFragment"
            app:enterAnim="@anim/slide_in_right"
            app:exitAnim="@anim/slide_out_right"
            app:popEnterAnim="@anim/slide_in_left"
            app:popExitAnim="@anim/slide_out_left" />
        <action
            android:id="@+id/action_recipeList_to_aboutFragment"
            app:destination="@id/aboutFragment"
            app:enterAnim="@anim/slide_in_left"
            app:exitAnim="@anim/slide_out_left"
            app:popEnterAnim="@anim/slide_in_right"
            app:popExitAnim="@anim/slide_out_right" />
        <action
            android:id="@+id/action_recipeList_to_settingsFragment"
            app:destination="@id/settingsFragment"
            app:enterAnim="@anim/slide_in_right"
            app:exitAnim="@anim/slide_out_right"
            app:popEnterAnim="@anim/slide_in_left"
            app:popExitAnim="@anim/slide_out_left" />
    </fragment>

One of the reasons I've used this approach is because I want to start a service from the refreshRecipes menu item rather than causing a navigation and this intercepts the click. One of the drawbacks is that the navigation bar items themselves don't show an animation when clicked (however I think this can be fixed).

Related