I need reload fragment after this process
Go from Fragment A to Fragment B and go from Fragment B to Fragment C, then do the registration process, and after the registration is correct, popBackStack Fragment A and my Fragment A will be reloaded.
My main problem is that Fragment A is not reloaded
Please help me
you can use navigation component library for solve this problem!
this will be your nav_graph.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/nav_graph"
app:startDestination="#id/AFragment">
<fragment
android:id="#+id/AFragment"
android:name="ir.inbo.navigationComponenetBug.AFragment"
android:label="AFragment"
tools:layout="#layout/fragment_a">
<argument
android:name="someLong"
app:argType="long" />
<action
android:id="#+id/action_AFragment_to_BFragment"
app:destination="#id/BFragment" />
</fragment>
<fragment
android:id="#+id/BFragment"
android:name="ir.inbo.navigationComponenetBug.BFragment"
android:label="BFragment"
tools:layout="#layout/fragment_b">
<argument
android:name="someLong"
app:argType="long" />
<action
android:id="#+id/action_BFragment_to_CFragment"
app:destination="#id/CFragment" />
</fragment>
<fragment
android:id="#+id/CFragment"
android:name="ir.inbo.navigationComponenetBug.CFragment"
android:label="CFragment"
tools:layout="#layout/fragment_c" >
<argument
android:name="someLong"
app:argType="long" />
<action
android:id="#+id/action_CFragment_to_AFragment"
app:destination="#id/AFragment"
app:popUpTo="#id/AFragment"
app:popUpToInclusive="true" />
</fragment>
</navigation>
and in AFragment you must move your logic to onViewCreated or onCreateView because of the fragment life cycle when you navigate from AFragment to Bfragment, Afragment's view will be destroyed and when you come back to Afragment from Cfragment, onViewCreated and onViewCreate will be called
and this is google example for your exact use case
Related
My app flow A fragment to B fragment :
A -> B(findNavController().navigate(R.id.action_AFragment_to_BFragment))
When I press back arrow from B fragment :
A fragment not resume from resume state but it was restarted(findNavController().popBackStack())
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/nav_graph"
app:startDestination="#id/AFragment">
<fragment
android:id="#+id/AFragment"
android:name=".AFragment"
android:label="#string/a_fragment_label"
tools:layout="#layout/fragment_a">
<action
android:id="#+id/action_AFragment_to_BFragment"
app:popUpToSaveState="true"
app:destination="#id/BFragment" />
</fragment>
<fragment
android:id="#+id/BFragment"
android:name=".BFragment"
android:label="#string/b_fragment_label"
tools:layout="#layout/fragment_b">
<action
android:id="#+id/action_BFragment_to_AFragment"
app:popUpToSaveState="true"
app:destination="#id/AFragment"
app:popUpTo="#+id/AFragment"
app:popUpToInclusive="false"/>
</fragment>
</navigation>
I am using navigation architecture component in my application.
Suppose I have fragment A as start destination.
I have push fragment B and Fragment C via navigation controller.
My navigation back stack is A-> B-> C.
Then I navigate to Fragment A with below action
<action
android:id="#+id/fragment_A_type"
app:destination="#id/fragment_a"
app:popUpTo="#id/fragment_a"
app:popUpToInclusive="true" />
Now My navigation back stack should be A.
But if check
parentFragmentManager.fragments back stack is
A->A
Also the swipeBackDismiss of activity is not working.
my navigation.xml file
<?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/nav_graph">
<fragment
android:id="#+id/FirstFragment"
android:name="com.example.wearexample1.FirstFragment"
android:label="#string/first_fragment_label"
tools:layout="#layout/fragment_first">
<action
android:id="#+id/action_FirstFragment_to_SecondFragment"
app:destination="#id/SecondFragment" />
</fragment>
<fragment
android:id="#+id/SecondFragment"
android:name="com.example.wearexample1.SecondFragment"
android:label="#string/second_fragment_label"
tools:layout="#layout/fragment_second">
</fragment>
<action
android:id="#+id/action_global_activity_type"
app:destination="#id/FirstFragment"
app:popUpTo="#id/FirstFragment"
app:popUpToInclusive="true" />
</navigation>
I've met a problem with the back stack while starting the app from a deep link (via notification).
The general idea is that I have 3 fragments (A, B, C). The A screen works as splash screen, so I've put a popUpTo and popUpToInclusive to the action, so I can never see back to it again. My deep link destination is fragment C. To achieve the proper back stack I've merged B and C into nested navigation. Unfortunately, when I press Back button in fragment B the app is showing fragment A. My guess this is because the action from A to B with popUpTo was never called when the app was started from the deep link itself. My question is: how to avoid going back from B to A in this particular scenario?
Thanks in advance! I attach the sample 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/nav_graph"
app:startDestination="#id/splashFragment">
<fragment
android:id="#+id/A"
android:name="A"
android:label="A" >
<action
android:id="#+id/action_A_to_B"
app:destination="#id/B"
app:popUpTo="#id/A"
app:popUpToInclusive="true" />
</fragment>
<navigation android:id="#+id/nested_nav"
app:startDestination="#id/B">
<fragment
android:id="#+id/B"
android:name="B"
android:label="B">
<action
android:id="#+id/action_B_to_C"
app:destination="#id/C" />
</fragment>
<fragment
android:id="#+id/C"
android:name="C"
android:label="C">
</fragment>
</navigation>
</navigation>
And my DeepLinkBuilder (nothing special, same as the docs)
NavDeepLinkBuilder(requireContext())
.setGraph(R.navigation.nav_graph)
.setDestination(R.id.userProfileFragment)
.createPendingIntent()
.send()
You have set the navGraph that contain the splash screen as the default startDestination which lead to show it when you press back button from the nested navGraph , I think the easiest solution is to do the following :
First edit you nav file to have only one navigation like :
<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/nav_graph"
app:startDestination="#id/splashFragment">
<fragment
android:id="#+id/A"
android:name="A"
android:label="A" >
<action
android:id="#+id/action_A_to_B"
app:destination="#id/B"
app:popUpTo="#id/A"
app:popUpToInclusive="true" />
</fragment>
<fragment
android:id="#+id/B"
android:name="B"
android:label="B">
<action
android:id="#+id/action_B_to_C"
app:destination="#id/C" />
</fragment>
<fragment
android:id="#+id/C"
android:name="C"
android:label="C">
</fragment>
</navigation>
Secondly set a listener to navController to listen when a destination change occur , like this :
yourNavController.setOnDestinationChangedListener(this);
override onDestinationChangedListener() method and check if the fragment which about to get showed is A , then finish the app like :
#override
public void onDestinationChanged(NavController controller, NavDestination destination, Bundle arguments){
if(destination.getId()==R.id.splashFragmentId){
finish();
}
}
I am using Navigation Component to build my application. I would like to implement SingleTask launch mode in the fragment navigation how can I achieve it?
For more clarity, I will detail my problem.
I have a HomeFragement(Lets Fragment A) and from that I have defined actions to the inner screens
Fragment A > Fragment B > Fragment C > Fragment D
I have a BaseFragment which extends all the above fragments in which I have implemented back click and its action using findNavController().popBackStack()
In Fragment D when the user clicks the back button as expected, it is navigating back to Fragment C. My problem comes when I have called an action whose destination fragment is Fragment A. I am calling this action on a successful event in Fragment D, that action also works well. But when the user press the back button from Fragment A it goes to Fragment C, the next back click goes to Fragment B, then the next back click to FRagment A. I should destroy Fragment B and Fragment C on the successful event called in Fragment D and should resume Fragment A.
I know this flow can be achieved by using launch mode as SingleTask of the first screen(Fragment A) if it is an Activity instead of Fragment.
My navigation graph XML file
<?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/app_navigation"
app:startDestination="#id/fragmentA">
<fragment
android:id="#+id/fragmentA"
android:name="FragmentA"
tools:layout="#layout/fragment_a">
<action
android:id="#+id/action_FragmentA_to_FragmentB"
app:destination="#id/dashboardFragment"
app:launchSingleTop="true"
app:popUpTo="#+id/main_nav_graph"
app:popUpToInclusive="true" />
</fragment>
<fragment
android:id="#+id/fragmentB"
android:name="FragmentB"
tools:layout="#layout/fragment_b">
<action
android:id="#+id/action_FragmentB_to_FragmentC"
app:destination="#id/dashboardFragment"
app:launchSingleTop="true"
app:popUpTo="#+id/main_nav_graph"
app:popUpToInclusive="true" />
</fragment>
<fragment
android:id="#+id/fragmentC"
android:name="FragmentC"
tools:layout="#layout/fragment_c">
<action
android:id="#+id/action_fragemntC_to_fragementA"
app:launchSingleTop="true"
app:popUpToInclusive="true"
app:destination="#id/deliveriesFragment" />
</fragment>
</navigation>
But when the user press the back button from Fragment A it goes to Fragment C, the next back click goes to Fragment B, then the next back click to FRagment A.
If I understand correctly, your Fragment A is the start destination, like a main page, and you want the behavior of "whenever I come back to Fragment A, the next back button I click should exit the app", right?
If so, try to add action from any Fragment to Fragment A and set:
app:popUpTo="#id/fragmentA"
app:popUpToInclusive="true" />
It should look like this:
Demo: https://youtu.be/LNyk_FEkZoA
Posting my working solution, the full navigation script which includes the answer of #Sam Chen
<?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/app_navigation"
app:startDestination="#id/fragmentA">
<fragment
android:id="#+id/fragmentA"
android:name="FragmentA"
tools:layout="#layout/fragment_a">
<action
android:id="#+id/action_FragmentA_to_FragmentB"
app:destination="#id/dashboardFragment"
app:launchSingleTop="true"
app:popUpTo="#+id/main_nav_graph"
app:popUpToInclusive="true" />
</fragment>
<fragment
android:id="#+id/fragmentB"
android:name="FragmentB"
tools:layout="#layout/fragment_b">
<action
android:id="#+id/action_FragmentB_to_FragmentC"
app:destination="#id/dashboardFragment"
app:launchSingleTop="true"
app:popUpTo="#+id/main_nav_graph"
app:popUpToInclusive="true" />
</fragment>
<fragment
android:id="#+id/fragmentC"
android:name="FragmentC"
tools:layout="#layout/fragment_c">
<action
android:id="#+id/action_fragemntC_to_fragementA"
app:popUpToInclusive="true"
app:popUpTo="#id/fragmentA" />
</fragment>
</navigation>
I have an activity (main) with three fragments (first, second and third). I included the 3 fragments in my activity (activity_main.xml) by using <include layout="#layout/content_main"/>.
The content_main.xml is using FragmentContainerView with id = nav_host_fragment. And this is my nav_graph.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/nav_graph"
app:startDestination="#id/FirstFragment">
<fragment
android:id="#+id/FirstFragment"
android:name="com.example.makegroups.FirstFragment"
android:label="#string/first_fragment_label"
tools:layout="#layout/fragment_first">
<action
android:id="#+id/action_FirstFragment_to_SecondFragment"
app:destination="#id/SecondFragment" />
</fragment>
<fragment
android:id="#+id/SecondFragment"
android:name="com.example.makegroups.SecondFragment"
android:label="#string/second_fragment_label"
tools:layout="#layout/fragment_second">
<action
android:id="#+id/action_SecondFragment_to_FirstFragment"
app:destination="#id/FirstFragment" />
<action
android:id="#+id/action_SecondFragment_to_ThirdFragment"
app:destination="#id/ThirdFragment" />
</fragment>
<fragment
android:id="#+id/ThirdFragment"
android:name="com.example.makegroups.ThirdFragment"
android:label="#string/third_fragment_label"
tools:layout="#layout/fragment_third">
<action
android:id="#+id/action_ThirdFragment_to_FirstFragment"
app:destination="#id/FirstFragment" />
</fragment>
</navigation>
I have a floatingactionbuttonin my activity (first fragmentstarts first) and when I click on it, I open the third fragment.
On the third fragment I have a button (next) to navigate to the first fragment, and when I click on it, I am back to first fragment using:
Fragment frg = new FirstFragment();
FragmentManager fm = requireActivity().getSupportFragmentManager();
Now (while I am in the first fragment), I click on the button next(another button to navigate to the second fragment), then the app crashes. I found this error:
java.lang.IllegalStateException: View androidx.constraintlayout.widget.ConstraintLayout{c9572fa V.E...... ........ 0,0-1440,2112} does not have a NavController set
Why I am getting this error? -I tried these suggestions here, without success.
I am using Java.
EDIT:
Read the last comment with #Zain to know why I got the error.
Bu using Navigation Architecture components, The NavController is the responsible for fragment transaction and managing the back stack instead of the Support FragmentManager.
So, instead of making tranditional framgnet transactions with FragmentManager
You can move from ThridFragment to the first one by:
Navigation.findNavController(requireView()).navigate(R.id.action_ThirdFragment_to_FirstFragment);
Where action_ThirdFragment_to_FirstFragment is the id of the action you defined in the navigation graph to move from ThridFragment to FirstFragment
UPDATE:
As discussed from comments, besides replacing FragmentManager by NavController in all actions; there is another issue:
Missing of action_FirstFragment_to_ThirdFragment action from the navigation graph.
navController = Navigation.findNavController(activity, R.id.nav_host_fragment)
when using the Navigation Component you should not handle the transactions yourself, instead you define the actions between each fragment and then access those directly like this
override fun onCreate(){
val navController = this.findNavController()
button.setOnClickListener{
navController.navigate(R.id.action_FirstFragment_to_SecondFragment, null)
}
}
and your nav_graph should be like this
<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/nav_graph"
app:startDestination="#id/FirstFragment">
<fragment
android:id="#+id/FirstFragment"
android:name="com.example.makegroups.FirstFragment"
android:label="#string/first_fragment_label"
tools:layout="#layout/fragment_first">
<action
android:id="#+id/action_FirstFragment_to_SecondFragment"
app:destination="#id/SecondFragment" />
</fragment>
<fragment
android:id="#+id/SecondFragment"
android:name="com.example.makegroups.SecondFragment"
android:label="#string/second_fragment_label"
tools:layout="#layout/fragment_second">
<action
android:id="#+id/action_SecondFragment_to_FirstFragment"
app:destination="#id/FirstFragment" />
<action
android:id="#+id/action_SecondFragment_to_ThirdFragment"
app:destination="#id/ThirdFragment" />
</fragment>
<fragment
android:id="#+id/ThirdFragment"
android:name="com.example.makegroups.ThirdFragment"
android:label="#string/third_fragment_label"
tools:layout="#layout/fragment_third">
<action
android:id="#+id/action_ThirdFragment_to_FirstFragment"
app:destination="#id/FirstFragment" />
</fragment>
val navController = Navigation.findNavController(requireActivity(), R.id.fragment_container)
navigate.navigate(R.id.fragment)