How to add transition animation to all actions in Jetpack Navigation? - android

To add transition animation in Jetpack navigation, we can add animation attributes to action like below in xml
<action
android:id="#+id/action_fragment1_to_fragment2"
app:destination="#id/fragment2"
app:enterAnim="#anim/slide_in_right"
app:exitAnim="#anim/slide_out_left"
app:popEnterAnim="#anim/slide_in_left"
app:popExitAnim="#anim/slide_out_right"/>
To make it pragmatically
NavOptions navOptions = new NavOptions.Builder()
.setEnterAnim(R.anim.slide_in_right)
.setExitAnim(R.anim.slide_out_left)
.setPopEnterAnim(R.anim.slide_in_left)
.setPopExitAnim(R.anim.slide_out_right)
.build();
But in my case I have so many fragments in the project and it would be a tedious task to define animation over every single actions,
Is there anyway we can define animation for every action at once and it will apply transition animation to every actions?
Thanks in advance!

Related

NavigationController does not open new fragment if it is already associated with bottom navigation

I have a fragment in bottom navigation when try to launch new fragment with same id using navigation controller instead of launching new fragment it redirects me to bottom navigation tab.
here is my code
<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/home_navigation"
app:startDestination="#id/splashFragment">
<fragment
android:id="#+id/baseTabsFragment"
android:name="com.abc.abc.fragment.BaseTabsFragment"
android:label="BaseTabsFragment"
tools:layout="#layout/fragment_common_tabs">
<action
android:id="#+id/action_to_baseFragment"
app:destination="#id/baseTabsFragment"
app:launchSingleTop="false" />
</fragment>
</navigation>
And code to navigate.
findNavController().navigate(R.id.action_to_baseFragment)
Here is a link for more details on this
https://issuetracker.google.com/issues/262076827
Update: I want to avoid the code duplication. I will have same fragments with same actions but different id's looking for a better way to do it.
If i understand correctly, you want to navigate to the same fragment and fragment does not refresh.
If you use navigation component in visual interface you need to pull an arrow from your baseFragment onto baseFragment again, with this you will see an arrow like self pointed. If you don't use visual just paste below code and it will be created.
<action
android:id="#+id/action_to_BaseFragment"
app:destination="#id/baseTabsFragment"
app:popUpTo="#id/baseTabsFragment"
app:popUpToInclusive="true" />
We are using this way because if we want system to navigate, it needs different location then previous, as long as we using same fragment we need to pop the old one.
It happened due to bottom menu. In this case you need to call programmatically to click on that bottom button.
Replace
findNavController().navigate(R.id.action_to_baseFragment)
to
navController.navigate(
R.id.base_graph, null,
NavOptions.Builder().setPopUpTo(navController.graph.startDestinationId, true).build()
)

Bottom navigation bar malfunctions when navigating from a fragment

I'm using the bottom navigation bar with the navigation component
To make the two components work together I called:
bottomNavigationView.setupWithNavController(navController)
Everything works as expected except when I navigate from inside a fragment instead of the bottom navigation bar
"View all" opens the same fragment as "Reports" from the bottom navigation bar
binding.viewAllScansTv.setOnClickListener {
val action = MainFragmentDirections.actionMainFragmentToReportsFragment()
navController.navigate(action)
}
After clicking on "View all", the fragment is opened, the "Reports" button gets selected, however, navigating back "Home" does not work anymore
How can I fix this weird behavior?
The nav graph:
<navigation app:startDestination="#id/mainFragment">
<fragment
android:id="#+id/mainFragment"
android:name="com.package.name.ui.main.MainFragment"
android:label="MainFragment">
<action android:id="#+id/action_mainFragment_to_reportsFragment"
app:destination="#id/reportsFragment" />
</fragment>
</navigation>
The bottom navigation menu:
<menu>
<item
android:id="#+id/mainFragment"
android:title="Home"/>
<item
android:id="#+id/reportsFragment"
android:title="Reports"/>
<item
android:id="#+id/settingsFragment"
android:title="My account"/>
</menu>
As #ianhanniballake mentioned in a comment, a similar question was posted here
What I ended up doing was replacing
val action = MainFragmentDirections.actionMainFragmentToReportsFragment()
navController.navigate(action)
with
val item = mainBottomNavigationView.menu.findItem(R.id.reportsFragment)
NavigationUI.onNavDestinationSelected(item, navController)
So basically I used the NavigationUI API to navigate so that it correctly tracks the back stack. The same NavigationUI API is being used by the BottomNavigationView internally
Setting a click listener on any view should have the same effect as if the user taps the corresponding item in the bottom navigation. So you need to call setSelectedItemId() on the BottomNavigationView.
val mainBottomNav =
activity?.findViewById(R.id.homeBottomNavigation)
mainBottomNav?.selectedItemId = R.id.baseHomeFragment
Your current answer is fine but if you need to pass arguments it wont work, So use this
In the Navigation XML add these lines to the action
app:launchSingleTop="true"
app:popUpTo="#+id/main_navigation"
app:popUpToInclusive="true"
And make sure app:popUpTo="#+id/main_navigation" has the same id as your navigation xml
So the final action should look like:
<action
android:id="#+id/action_cameraFragment_to_searchFragment"
app:destination="#id/searchFragment"
app:launchSingleTop="true"
app:popUpTo="#+id/main_navigation"
app:popUpToInclusive="true"/>
And Navigate normally using the action
val action = CameraFragmentDirections.actionCameraFragmentToSearchFragment()
findNavController().navigate(action)

Add Transition File in Navigation Graph of Android Application

I want to add an explode transition in my next fragment using the latest Navigation pattern "Navigation Graph".How to add a transition XML file(#transition/fade or #transition/slide or #transiton/explode) into Navigation Graph of android app.
You will probably want to define the desired transition in your navigation graph like this:
<fragment
// here your fragment is defined
<action
android:id="#+id/your_action_id"
app:destination="#id/yourDestinationFragment"
app:enterAnim="#anim/fade_in"
app:exitAnim="#anim/fade_out"
app:popEnterAnim="#anim/fade_in"
app:popExitAnim="#anim/fade_out" />
</fragment>
Note that you can define different animations for entering and leaving a fragment.
The animations you define will go into the /res/anim folder. You might have to create it if you don't find it.

Navigation architecture: How to manage proper navigation without using clearTask as it is deprecated

While using navigation architecture as from here , here clearTask is deprecated.
My scenario is this: There are 2 screens Login and Registration, both have links to each other. So you can go to Registration from Login and also Login from Registration. But on back Press App should be closed.
It could simply be done by just adding clearTask to both actions as below.
<?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/nv_auth_phase"
app:startDestination="#id/fragment_login">
<fragment
android:id="#+id/fragment_login"
android:name="com.jobhook.ui.auth.login.LoginFragment"
android:label="LoginFragment"
tools:layout="#layout/fragment_login">
<action
android:id="#+id/nv_action_login_to_registration"
app:clearTask="true"
app:destination="#id/fragment_registration" />
</fragment>
<fragment
android:id="#+id/fragment_registration"
android:name="com.jobhook.ui.auth.registration.RegistrationFragment"
android:label="RegistrationFragment"
tools:layout="#layout/fragment_registration">
<action
android:id="#+id/nv_action_registration_to_login"
app:clearTask="true"
app:destination="#id/fragment_login" />
</fragment>
</navigation>
But as it was deprecated I have tried other solution like adding popUpTo -> navigation graph's Id, making launchSingleTop to true in both actions. Nothing seems to work in my scenario.
I have checked this question also but didn't get a solution.
You need to use in your action next code
app:popUpTo="#+id/fragment_login"
app:popUpToInclusive="true"
Set your NavHostFragment defaultNavHost value false,
<fragment
android:name="androidx.navigation.fragment.NavHostFragment"
app:defaultNavHost="false"
app:navGraph="#navigation/nav_graph"
... />
The app:defaultNavHost="true" attribute ensures that your NavHostFragment intercepts the system Back button. Note that only one NavHost can be the default. If you have multiple hosts in the same layout (two-pane layouts, for example), be sure to specify only one default NavHost.
Simple and effective solution:
fun signOut(activity: Activity) = activity.finish()

How to add animation to changing fragments using Navigation Component?

How to add animation to changing fragments using Navigation Architecture Component?
In the Navigation Component documentation(https://developer.android.com/topic/libraries/architecture/navigation/navigation-implementing) in the section: Create a transition between destinations (it's near the end of the document) you have it explained in detail.
You can either add them using the editor by selecting the arrow of the desired transition and then selecting the animations in the Animations section of the Attributes tab.
Or by referencing the animations in the xml file like in the example:
<fragment
android:id="#+id/specifyAmountFragment"
android:name="com.example.buybuddy.buybuddy.SpecifyAmountFragment"
android:label="fragment_specify_amount"
tools:layout="#layout/fragment_specify_amount">
<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>
You can use regular anim resources for this animations
If you want to add animation through programmatically, use NavOptions (here).
NavOptions.Builder navBuilder = new NavOptions.Builder();
navBuilder.setEnterAnim(R.anim.slide_left).setExitAnim(R.anim.slide_right).setPopEnterAnim(R.anim.slide_left).setPopExitAnim(R.anim.slide_right);
//Inside Activity
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment);
navController.navigate(R.id.destinationFragmentId,null,navBuilder.build());
//Inside Fragment
NavHostFragment.findNavController(YoutFragment.this)
.navigate(R.id.destinationFragmentId, null, navBuilder.build());

Categories

Resources