Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Navigation Component set transition animation programmatically

yesterday i come across with a problem that i needed to set animation from nav_graph.xml in my baseFragment and programatically get action object from current node which includes enterAnim and exitAnim resource. Could not find solution here so here we go.

First we need to feed anim folder with our animations in res folder because its hungry.

slide_in_left.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:duration="250"
        android:fromXDelta="-100%"
        android:fromYDelta="0%"
        android:toXDelta="0%"
        android:toYDelta="0%" />
</set>

other animations you can easily found on github or stackoverflow.

Here is my nav_graph.xml fragment from which we gonna make transition

<fragment
    android:id="@+id/kebabsFragment"
    android:name="com.kebabkrabby.kebabapp.KebabFragment"
    android:label="so many kebabs"
    tools:layout="@layout/fragment_kebab">

    <action
        android:id="@+id/action_kebabs_to_kebab_detail"
        app:destination="@id/kebabDetailFragment"
        app:enterAnim="@anim/slide_in_right"
        app:exitAnim="@anim/slide_out_left" />
</fragment>

now in KebabFragment.tk u gonna call baseFragment method for transition to get into detail of our desired kebab and then popFromBackStack

//navigateAndClean(actionId, cleanFragmentId)
navigateAndClean(R.id.action_kebabs_to_kebab_detail, R.id.kebabsFragment)

in our baseFragment.kt

internal fun navigateAndClean(actionId: Int, currentFragmentIdToClear: Int) {

    val navBuilder = NavOptions.Builder()

    val navController = Navigation.findNavController(getRootView())
    val currNavigationNode = navController.graph.findNode(currentFragmentIdToClear) // NavDestination of kebabsFragment object in nav_graph.xml
    val action = currNavigationNode?.getAction(actionId) // finally we get this action_kebabs_to_kebab_detail action object

    action?.navOptions?.enterAnim?.let {  //do we have animation or not?
        navBuilder.setEnterAnim(it)
    }

    action?.navOptions?.exitAnim?.let {
        navBuilder.setExitAnim(it)
    }

    navBuilder.setPopUpTo(currentFragmentIdToClear, true)       //remove from backstack

    navController.navigate(actionId, null, navBuilder.build())
}

Some people will ask. Hey, Mr. Kebab but how do i get getRootView() and Mr. Kebab will look at u and say "buddy, look at this world, together we can achieve big things"

override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
    rootView = inflater.inflate(mContentLayoutResourceId, container, false)
    return rootView
}

fun getRootView(): View {
    return rootView
}

Durum kebab. Enjoy.

like image 987
Kebab Krabby Avatar asked Nov 24 '25 12:11

Kebab Krabby


1 Answers

Navigation components provides built in animation options for entry and exit transitions, a sample code block is attached below for reference

Code block to add animations within java/kotlin

navigate(
navController, resId, bundle,
NavOptions.Builder()
    .setPopUpTo(R.id.splashFragment, true)
    .setEnterAnim(R.anim.fade_in)
    .setExitAnim(R.anim.fade_out)
    .setPopEnterAnim(R.anim.fade_in)
    .setPopExitAnim(R.anim.fade_out)
    .build()
)

Code block for adding animation in xml file

<fragment
android:id="@+id/kebabsFragment"
android:name="com.kebabkrabby.kebabapp.KebabFragment"
android:label="so many kebabs"
tools:layout="@layout/fragment_kebab">
<action
    android:id="@+id/confirmationAction"
    app:destination="@id/confirmationFragment"
    app:enterAnim="@anim/slide_in_right"
    app:exitAnim="@anim/slide_out_left"
    app:popEnterAnim="@anim/slide_in_left"
    app:popExitAnim="@anim/slide_out_right" />
</fragment>
like image 91
Arbaz Pirwani Avatar answered Nov 26 '25 11:11

Arbaz Pirwani



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!