android / architecture-components-samples

Samples for Android Architecture Components.
https://d.android.com/arch
Apache License 2.0
23.36k stars 8.28k forks source link

Navigating from from graph node to another not possible #1041

Open rekire opened 2 years ago

rekire commented 2 years ago

This Bug-Report is about the navigation components in Version 2.4.0-beta02.

I have a simple test app with a bottom navigation with two tabs and in total 4 fragments (two per tab).

I want to navigate from the first tab to a second fragment in the second tab. This is afik impossible with the NavigationDirections. You can decide yourself if this missing feature is a bug of if this is a feature request. I think that this mandatory feature and therefore a bug.

I'm getting this error message: "Navigation destination $dest referenced from action ${NavDestination.getDisplayName(context, resId)} cannot be found from the current destination $currentNode" (NavController.kt:1528ff)

Here is my simplified graph (full version is here):

<navigation app:startDestination="@id/tab_home">
    <navigation
        android:id="@+id/tab_home"
        app:startDestination="@id/frag_home">
        <fragment android:id="@+id/frag_home">
            <action
                android:id="@+id/switchTab"
                app:destination="@id/frag_book">
                <argument
                    android:name="name"
                    app:argType="string"/>
            </action>
        </fragment>
        <fragment android:id="@+id/frag_hint"/>
    </navigation>

    <navigation
        android:id="@+id/tab_books"
        app:startDestination="@id/frag_shelf">
        <fragment android:id="@+id/frag_shelf">
            <action
                android:id="@+id/open_book"
                app:destination="@id/frag_book">
                <argument
                    android:name="name"
                    app:argType="string"/>
            </action>
        </fragment>

        <fragment android:id="@+id/frag_book">
            <argument
                android:name="name"
                app:argType="string"/>
            <deepLink
                android:id="@+id/bookDeeplink"
                app:uri="navbug://shelf/{name}"/>
        </fragment>
    </navigation>
</navigation>

I'm trying this code:

// this crashes:
navigate(HomeFragmentDirections.switchTab("Let it crash..."))
// bad alternative:
findNavController().navigate(Uri.parse("navbug://shelf/works"))

The only way I see is to use deep links with the downside of missing type safety. In this sample this might work, but not if you pass parcelables.

I dove very deep into the code that know how I could fix this by using a private method of the library. The way I see is to choose the "node" of the method private fun navigate(node: NavDestination, args: Bundle?, navOptions: NavOptions?, navigatorExtras: Navigator.Extras?) yourself. In my case I could select the node with this simple code:

graph.findNode(R.id.tab_books, false)

Using the "normal" direction HomeFragmentDirections.switchTab("Sample"). Do you see any issues with a new method to choose the node yourself? So you can choose the tab/subgraph explicitly and the tab selection should work automatically.

rekire commented 2 years ago

I cannot stop thinking about it... What is about to search the full graph by default? That would not change the interface and is basically what I was expecting initially.

In that case all the roots should be searched and not only the current graph root.

kartik0198 commented 2 years ago

Were you able to find any solution?

rekire commented 2 years ago

No, there is no solution. I also asked this on the Issue Trackers. This is simply not intended. The only possible way are deeplinks.

After some discussions with coworkers I'm starting to think that linking from one tab to another is might be not really what the user wants. Google for example seems not to use bottom navigation as in their guides. They simply open a new activity which has some advantages if you think longer about it.

kartik0198 commented 2 years ago

Unfortunately, this is a required usecase for my application. I tried using deeplinks for navigation but then faced this issue that I reported on issue tracker. :(

rekire commented 2 years ago

To be honest that looks very similar to my first bug in this context: https://issuetracker.google.com/issues/210687967

I would guess that you are not using distinct graphs per tab. Check my sample project linked in that issue. I'm not very happy with the answer too.

I think you should not manually change the tab by code. I need to read the guides to find out if the Google Style guide suggests the same. As said the coworker told me that the Apple guidelines suggest not do to that at all. Instead you should use the equivalent of Dialog or a new Activity. However that is something from the Apple guidelines and as said I did not look for the suggestions from Google yet.