My viewpager consists of 2 fragments which are displayed correctly and working fine.
From viewpager's fragment I want to move to another fragment via navigation graph
This is my graph
<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/offer_nav_graph"
app:startDestination="#id/offersFragment">
<fragment
android:id="#+id/offersFragment"
android:name="com.octave.offers.OffersFragment"
android:label="offers_fragment"
tools:layout="#layout/offers_fragment" />
<fragment
android:id="#+id/availableOfferDetailFragment"
android:name="com.octave.offers.available.AvailableOfferDetailFragment"
android:label="fragment_available_offer_detail"
tools:layout="#layout/fragment_available_offer_detail" />
<fragment
android:id="#+id/availableOffersFragment"
android:name="com.octave.offers.available.AvailableOffersFragment"
android:label="fragment_available_offers"
tools:layout="#layout/fragment_available_offers" >
<action
android:id="#+id/action_availableOffersFragment_to_availableOfferDetailFragment"
app:destination="#id/availableOfferDetailFragment" >
<argument
android:name="offerId"
app:argType="integer"
android:defaultValue="-1" />
</action>
</fragment>
</navigation>
Offers fragment - has view pager
Available offer fragment - one of the fragment on view pager
Available offer detail fragment - i want to navigate
On button click I am calling this
AvailableOffersFragmentDirections.actionAvailableOffersFragmentToAvailableOfferDetailFragment(offerId)
The exception
Navigation action/destination com.octave.staging:id/action_availableOffersFragment_to_availableOfferDetailFragment cannot be found from the current destination Destination(com.octave.staging:id/homeFragment) label=HomeFragment class=com.octave.home.HomeFragment
What is wrong over here?
button exists on availableOffersFragment. I want to navigate from
availableOffersFragment to availableOfferDetailFragment.
offersFragment has the viewpager with 2 tabs having their own fragment
availableOffersFragment and secondFragemnt
So, now you need to navigate from availableOffersFragment which is a tab (page fragment) in the ViewPager; but this is not possible because those tabs don't affect the back stack. You can check out the questions discussed in here and also this one.
But what you can do instead is to add an action from offersFragment (which holds the ViewPager) to availableOfferDetailFragment as following:
Remove the tab fragments from the navGraph (availableOffersFragment and secondFragemnt).
Create an action in the navGraph from offersFragment to availableOfferDetailFragment
<fragment
android:id="#+id/offersFragment"
android:name="com.octave.offers.OffersFragment"
android:label="offers_fragment"
tools:layout="#layout/offers_fragment">
<action
android:id="#+id/action_offersFragment_to_availableOfferDetailFragment"
app:destination="#id/availableOfferDetailFragment" >
<argument
android:name="offerId"
app:argType="integer"
android:defaultValue="-1" />
</action>
</fragment>
When the button is clicked use parentFragment to access the offersFragment from the availableOffersFragment tab when the button is clicked. For instance:
Create a method in offersFragment:
goToDetailsFragment(offerId: Int) {
// perfrom the navaigation
OffersFragmentDirections.actionOffersFragmentToAvailableOfferDetailFragment(offerId)
}
And in availableOffersFragment
btn.setOnClickListener {
(parentFragment as offersFragment).goToDetailsFragment(offerId)
}
Check using:
btn.setOnClickListener {
Navigation.findNavController(it).navigate(R.id.availableOfferDetailFragment)
}
Related
How can I back from the second fragment to the first fragment using Navigation Component?
navigation_main.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/main_navigation"
app:startDestination="#id/firstFragment">
<fragment
android:id="#+id/firstFragment"
android:name="com.test.ttt.FirstFragment"
tools:layout="#layout/fragment_first">
<action
android:id="#+id/action_firstFragment_to_secondFragment"
app:destination="#id/secondFragment"
app:popUpTo="#id/firstFragment"
app:popUpToInclusive="true"/>
</fragment>
<fragment
android:id="#+id/secondFragment"
android:name="com.test.ttt.SecondFragment"
tools:layout="#layout/fragment_second" />
</navigation>
FirstFragment.java
public class FirstFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
Navigation.findNavController(container).navigate(FirstFragmentDirections.actionFirstFragmentToSecondFragment());
return inflater.inflate(R.layout.fragment_first, container, false);
}
}
I want when I press the back button in the second fragment, It must back to the first fragment but currently, When I press the back button in the second fragment it is leaving the app.
How can I solve this problem?
The reason you are being exited from the app is because while navigating to the second fragment, you are removing the first fragment from your stack. The properties app:popUpTo and app:popUpToInclusive are typically used when you want to remove some fragments from your backstack while navigating. A simple use case for this would be when navigating from Login/SignUp Fragment to Home/Main Fragment. In this case you would not want the user to be able to press back and go back to login/signup screens. Here is where the two properties would help.
TL;DR - Remove the app:popUpTo and app:popUpToInclusive properties from your action
Change
<action
android:id="#+id/action_firstFragment_to_secondFragment"
app:destination="#id/secondFragment"
app:popUpTo="#id/firstFragment"
app:popUpToInclusive="true"/>
to
<action
android:id="#+id/action_firstFragment_to_secondFragment"
app:destination="#id/secondFragment"/>
I need to exclude Fragment from back stack.
I know there are many questions here regarding this issue, but I cousin't find an answer to my issue.
Let's say I have Fragment A and Fragment B. Fragment A is move to Fragment B and Fragment B open another Activity. What I need is when I click back from that Activity go back to Fragment A.
Below is my XML of the graph:
<fragment
android:id="#+id/nav_liabilities_fragment"
android:name="liabilities.liabilities_list_fragment.view.LiabilitiesListFragment"
android:label="LiabilitiesListFragment"
tools:layout="#layout/fragment_liabilities_list">
<action
android:id="#+id/action_nav_liabilities_fragment_to_nav_missing_liability_details_fragment"
app:destination="#id/nav_missing_liability_details_fragment"
app:popUpTo="#+id/nav_liabilities_fragment"
app:popUpToInclusive="false"
/>
</fragment>
<fragment
android:id="#+id/nav_missing_liability_details_fragment"
android:name="ui.flow.lobby.liabilities.missing_liability_details.view.MissingDetailsLiabilityFragment"
android:label="MissingDetailsLiabilityFragment"
tools:layout="#layout/fragment_missing_details_liability">
<argument
android:name="extra_data"
app:argType="android.repository.network.model.response.liabilities.LiabilityModel" />
</fragment>
</navigation>
Newbie on Navigation Component. I'm trying to achieve this but I don't know how:
I have 3 fragments:
FragmentA → FragmentList → FragmentAdd
If I try to go from FragmentMain to FragmentList but list is empty it should go directly to FragmentAdd (its not really directly since I'm checking the list on FragmentList but for the user it should look like it). If I'm on FragmentAdd and I go back (by either pressing back button or back on the toolbar) it should go back to FragmentMain (since FragmentList is still empty) but if I add something it should go back to FragmentList.
I've tried with
<fragment
android:id="#+id/fragmentMain" >
<action android:id="#+id/action_fragmentMain_to_fragmentList
app:destination="#id/fragmentList"
app:popUpTo="#id/fragmentMain"
app:popUpToInclusive="true"/>
</fragment>
The thing is that if I press back on FragmentAdd it will go to FragmentList, check that the list is still empty and go back to FragmentAdd. And if I pop FragmentList and then add something It will go to FragmentMain and not the list.
The difference with Conditional back navigation with Android Navigation Component is that I can add stuff to FragmentList from FragmentAdd
Any suggestion please?
Use app:popUpTo="#id/FragmentList" and app:popUpToInclusive="true" in action action_fragmentList_to_fragmentAdd
<fragment
android:id="#+id/fragmentMain" >
<action android:id="#+id/action_fragmentMain_to_fragmentList
app:destination="#id/fragmentList"/>
</fragment>
<fragment
android:id="#+id/fragmentList" >
<action android:id="#+id/action_fragmentList_to_fragmentAdd
app:destination="#id/fragmentAdd"
app:popUpTo="#id/fragmentList"
app:popUpToInclusive="true"/>
</fragment>
<fragment
android:id="#+id/fragmentAdd" >
</fragment>
I am using one nav_graph and I have a scenario like I have fragment1 and going to other fragment which is a sub nav graph and it has a couple of
fragments(fragment3 and fragment4) and start destination is fragment3 and from fragment3 I am going to fragment4 and fragment4 has "DONE" button.
Here is the scenario:
I am calling this sub nav graph from fragment1 and from fragment4 I want to redirect to it is parent i.e fragment1
I am calling this sub nav graph from fragment2 and from fragment4 I want to redirect to it is parent i.e fragment2
This is how I am handling the done button click event inside fragment4:
findNavController().currentDestination?.parent?.startDestination?.let {
findNavController().popBackStack(it, true)
}
But it is not redirecting to parent it is redirecting to the subgraph stat destination i.e fragment3
Here is how my nav_graph is looking:
Here are two fragments:
<fragment
android:id="#+id/fragment1"
android:name="fragment1"
android:label="fragment1">
<action
android:id="#+id/action_fragment1_to_sub_graph"
app:destination="#id/sub_graph_id" />
</fragment>
<fragment
android:id="#+id/fragment2"
android:name="fragment2"
android:label="fragment2">
<action
android:id="#+id/action_fragment2_to_sub_graph"
app:destination="#id/sub_graph_id" />
</fragment>
Here is my sub nav graph:
<navigation
android:id="#+id/sub_graph_id"
app:startDestination="#id/fragment3">
<fragment
android:id="#+id/fragment3"
android:name="fragment3"
android:label="fragment3">
<action
android:id="#+id/action_fragment3_to_fragment4"
app:destination="#id/fragment4" />
</fragment>
<fragment
android:id="#+id/fragment4"
android:name="fragment4"
android:label="fragment4"/>
</navigation>
What am I missing? How should I achieve this?
I have a graph defined using XML and I added a DialogFragment as one of the Fragment in my NavGraph. when I call NavController.navigate with resId and bundle on that nav controller I don't see any Dialog being displayed. Is there any way I can use DialogFragment instead of standard Fragment?
<fragment
android:id="#+id/noLoginDialog"
android:name="com.ram.view.NoLoginDialog"
android:label="NoLoginDialog">
<argument
android:name="argTitle"
android:defaultValue="null"
app:type="string"/>
<argument
android:name="argBody"
android:defaultValue="null"
app:type="string"/>
<argument
android:name="argButton"
android:defaultValue="null"
app:type="string"/>
</fragment>
and my action is defined as below
<container_fragment
android:id="#+id/homeFragment"
android:name="com.ram.home.HomeFragment"
android:label="HomeFragment">
<action
android:id="#+id/action_homeFragment_to_noAuthAlertDialog"
app:destination="#id/noLoginDialog"/>
</container_fragment>
My other actions with activity and fragments works just fine.
hum, Navigation Library will never open an Fragment as Dialog, it just replace the first (home destination) to other destination in your NavHostFragment.
Google said:
A destination is any place you can navigate to in your app. While
destinations are usually Fragments representing specific screens..
Please provide more information, like your navigation code (java/kotlin).
Take a read on this official Google post to understand more about Navigation:
https://developer.android.com/topic/libraries/architecture/navigation/navigation-implementing
Yes you can call up DialogFragment from navigation, you will just have to explicitly tell the navigation that you are going to use dialog
<dialog
android:id="#+id/simCancelFinish"
android:name="mk.telekom.kiosk.ui.dialogs.SimCancelFinish"
android:label="SimCancelFinish" >
<action
android:id="#+id/action_simCancelFinish_to_stornoSimFragment"
app:destination="#id/stornoSimFragment"
app:popUpTo="#id/stornoSimFragment"
app:popUpToInclusive="true" />
</dialog>