3

I'm new at navigation graph and I have a simple movie application that contains a BottomNavigationView with 2 tabs or 2 icons , the first icon or first tab contains 2 Fragments the first one is FeedFragment and I navigate from it to DetailsFragment and I put these 2 Fragment in nested graph . The second tab for FavoritFragment .

Below my code in 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/my_nav"
    app:startDestination="@id/homeNavigation">


    <fragment
        android:id="@+id/favoritesFragment"
        android:name="com.tito.movieapps.ui.fragments.FavoritesFragment"
        android:label="@string/favorites"
        tools:layout="@layout/fragment_favorites" >

        <action
            android:id="@+id/action_favoritesFragment_to_homeNavigation"
            app:destination="@id/detailsFragment" />
    </fragment>
    <navigation
        android:id="@+id/homeNavigation"
        android:label="Home nested graph"
        app:startDestination="@id/feedFragment">
        <fragment
            android:id="@+id/feedFragment"
            android:name="com.tito.movieapps.ui.fragments.FeedFragment"
            android:label="@string/feed_page"
            tools:layout="@layout/fragment_feed">
            <action
                android:id="@+id/action_feedFragment_to_detailsFragment"
                app:destination="@id/detailsFragment" />

        </fragment>
        <fragment
            android:id="@+id/detailsFragment"
            android:name="com.tito.movieapps.ui.fragments.DetailsFragment"
            android:label="Details"
            tools:layout="@layout/fragment_details">
            <argument
                android:name="movieItem"
                app:argType="com.tito.domain.entites.MovieModelItem" />
        </fragment>
    </navigation>

</navigation>

I can navigate from FeedFragment to DetailsFragment and I pass a Parcelable object . I want to navigate from FavoriteFragment to DetailsFragment (in the nested navigationGraph) and when I write the below code in FavoriteFragment

lifecycleScope.launchWhenStarted {
            detailsViewModel.getSavedMovie().collectLatest { movies->
               if(movies.isNotEmpty()) {
                   favoritesAdapter = FavoritesAdapter(object : FavoritesAdapter.OnItemClick{
                       override fun onItemClick(movieModelItem: MovieModelItem) {

                           val id = FavoritesFragmentDirections.actionFavoritesFragmentToHomeNavigation(movieModelItem)

                            findNavController().navigate(id)
                       }
                   })
                   binding.movieRec.adapter = favoritesAdapter
                   favoritesAdapter.differ.submitList(movies)
               }else{
                   Toast.makeText(requireActivity(),"No data",Toast.LENGTH_LONG).show()
               }
            }
        }

And run the app , I can't run it I get the below error

e: D:\MovieApps\app\src\main\java\com\tito\movieapps\ui\fragments\FavoritesFragment.kt: (48, 105): Too many arguments for public final fun actionFavoritesFragmentToHomeNavigation(): NavDirections defined in com.tito.movieapps.ui.fragments.FavoritesFragmentDirections.Companion

I can't fix this error so please help me

Ahmed Elsayed
  • 231
  • 3
  • 23
  • https://stackoverflow.com/q/59196327/6576302 – C.F.G Jul 15 '23 at 11:44
  • I already added the second navigation graph in the ``nav_graph.xml`` . And when I make an action from Favorite to the Home graph , it navigate to the Home no the Details screen – Ahmed Elsayed Jul 15 '23 at 12:41
  • try to not pass any data, and test that without "movieModelItem". And see what will happen. – C.F.G Jul 15 '23 at 12:52
  • I changed the action to make it navigate to the homeGraph and in navigated to the FeedFragment which is the start destination of the homeGrapgh , but I need to navigate to Favorite Fragment which is the the second destination in the homeGraph , and when I change the action and make the destination to FavoriteFragment, it needs to pass to it the argument which is in the FavoritFragment . – Ahmed Elsayed Jul 15 '23 at 15:19

2 Answers2

0

I am not aware of full code of your project, so, I just can suggest a trick (that is a non-standard and temporary solution).

Add an Boolean argument e.g. shouldIGo and an Nullable variable movieItemData into your homeNavigation. My trick goes like this, if someone entered into this homeNavigation with ShouldIGo == true (and of course in this case movieItemData must be Non-null and attached to the direction) then automatically navigate to DetailsFragment with that extra data.

<navigation
    android:id="@+id/homeNavigation"
    android:label="Home nested graph"
    app:startDestination="@id/feedFragment">
    <fragment
        android:id="@+id/feedFragment"
        android:name="com.tito.movieapps.ui.fragments.FeedFragment"
        android:label="@string/feed_page"
        tools:layout="@layout/fragment_feed">
        <action
            android:id="@+id/action_feedFragment_to_detailsFragment"
            app:destination="@id/detailsFragment" />

        <argument <!-- this has been added -->
            android:name="movieItemData"
            app:argType="com.tito.domain.entites.MovieModelItem"
            android:defaultValue="@null"
            app:nullable="true"/>
        <argument <!-- this has been added -->
            android:name="shouldIGo"
            app:argType="boolean"
            android:defaultValue="false"/>

    </fragment>
    <fragment
        android:id="@+id/detailsFragment"
        android:name="com.tito.movieapps.ui.fragments.DetailsFragment"
        android:label="Details"
        tools:layout="@layout/fragment_details">
        <argument
            android:name="movieItem"
            app:argType="com.tito.domain.entites.MovieModelItem" />
    </fragment>
</navigation>

And in home fragment of homeNavigation, i.e. FeedFragment check that if shouldIGo is true or not. if it was true then navigate to detailsFragment.

private FeedFragmentArgs args;

...

onCreate ... 

args = FeedFragmentArgs.fromBundle(requireArguments());

if (args.shouldIGo == true) {
//navigate to detailsFragment with movieItemData data.
}
C.F.G
  • 817
  • 8
  • 16
  • What is the destination from the Favorite Fragment ? I made it HomeNavigation but it doesn't accept any params even I added the 2 argument in FeedFragment . Or should I make the destination to FeedFragment ? – Ahmed Elsayed Jul 15 '23 at 17:14
  • As you have defined it by `action_favoritesFragment_to_homeNavigation` the destination is home fragment of `homeNavigation`. – C.F.G Jul 15 '23 at 17:21
  • Do you know how to play with navgraph in android studio? every thing is in right side panel. arguments, directions, etc. – C.F.G Jul 15 '23 at 17:26
  • Yes I have added the 2 argument in FeedFragment and I have added an action from FavoriteFragment to HomeNavigation like the below code `` `` But I can't add parameters in the action – Ahmed Elsayed Jul 15 '23 at 17:31
  • Parameters that I have defined is for `homeNavigation`. If someone (A) want to enter in `homeNavigation` he (A) must show his boolean key to allow to enter. this is like a lock and key. lock is in destination always and key is in hand of who wants to enter. – C.F.G Jul 15 '23 at 17:39
  • So If you want to use my trick, and travel from `favorites` to `homeNavigation`, in codes (not in graph) you should pass that boolean. – C.F.G Jul 15 '23 at 17:43
  • Could you edit your answer and show me how the action will be in Favorite Fragment ? – Ahmed Elsayed Jul 15 '23 at 17:45
  • What you commented in above is ok. nothing else is needed in NavGraph. – C.F.G Jul 15 '23 at 17:47
  • But it doesn't need an arguments when I use the action in FavoritFragment ``val id = FavoritesFragmentDirections.actionFavoritesFragmentToHomeNavigation3() findNavController().navigate(id)`` – Ahmed Elsayed Jul 15 '23 at 17:57
  • Android studio will help you if it needs any argument, in this case it needs. Add a dot at the end of `FavoritesFragmentDirections.actionFavoritesFragmentToHomeNavigation3()` and see what it needs? – C.F.G Jul 15 '23 at 18:10
  • I should pass the arguments in the action not after it , it will not accept params cause the destination is HomeNavigation not FeedFragment – Ahmed Elsayed Jul 15 '23 at 18:16
  • In java, if there are two arguments then it should pass after parenthesis. But I am not sure, – C.F.G Jul 15 '23 at 18:18
  • I solved it , see my answer and thank you for your help – Ahmed Elsayed Jul 15 '23 at 21:23
0

I found the solution , thanks to Chat OpenAI

If I want to navigate from a fragment to another destination in another navigation graph we should do the following

1- Navigate from the destination(Favorite Fragment) to the other navigation graph (Home Navigation Graph)

 <fragment
        android:id="@+id/favoritesFragment"
        android:name="com.tito.movieapps.ui.fragments.FavoritesFragment"
        android:label="@string/favorites"
        tools:layout="@layout/fragment_favorites" >
        <action
            android:id="@+id/action_favoritesFragment_to_homeNavigation4"
            app:destination="@id/homeNavigation" />

Then we make an action from the start destination (FeedFragment) in the Home Navigation Graph graph to the DetailsFragment like the code below

<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/my_nav"
    app:startDestination="@id/homeNavigation">


    <fragment
        android:id="@+id/favoritesFragment"
        android:name="com.tito.movieapps.ui.fragments.FavoritesFragment"
        android:label="@string/favorites"
        tools:layout="@layout/fragment_favorites" >
        <action
            android:id="@+id/action_favoritesFragment_to_homeNavigation4"
            app:destination="@id/homeNavigation" />
    </fragment>
    <navigation
        android:id="@+id/homeNavigation"
        android:label="Home nested graph"
        app:startDestination="@id/feedFragment">
        <fragment
            android:id="@+id/feedFragment"
            android:name="com.tito.movieapps.ui.fragments.FeedFragment"
            android:label="@string/feed_page"
            tools:layout="@layout/fragment_feed">
            <action
                android:id="@+id/action_feedFragment_to_detailsFragment"
                app:destination="@id/detailsFragment" />

        </fragment>
        <fragment
            android:id="@+id/detailsFragment"
            android:name="com.tito.movieapps.ui.fragments.DetailsFragment"
            android:label="Details"
            tools:layout="@layout/fragment_details">
            <argument
                android:name="movieItem"
                app:argType="com.tito.domain.entites.MovieModelItem" />
        </fragment>
    </navigation>

</navigation>

Then in the FavoriteFragment in OnItemClick

  val id  = FavoritesFragmentDirections.actionFavoritesFragmentToHomeNavigation4()
                               findNavController().navigate(id)
                               val args = DetailsFragmentArgs(movieModelItem)
                               findNavController().navigate(R.id.action_feedFragment_to_detailsFragment,args.toBundle())
Ahmed Elsayed
  • 231
  • 3
  • 23