Search code examples
kotlinandroid-architecture-componentsandroid-navigationandroid-navigation-graph

How To Make Destination of Android Navigation Component Inflated in Different Destinations Not Be Edited as If They Were Shared Instances?


SCENARIO:

I use BottomNavigationView component on my app setup with Android Navigation Component. It's a Social Network app with Home, Feed, Challenges, Map and Profile as main destinations of the app. There are 2 destinations (destination_feed and destination_profile) that use a third destination (navigation_graph_posts) inside them. The picture below shows more or less the scenario:

Android Navigation Component Scenario

PROBLEM:

When I access destination_profile (which shows only posts of logged in user) and go back to destination_feed, the posts shown on destination_feed (that previously were all posts) now only show the same posts shown on destination_profile. It looks like the changes I do on posts from profile_destination are reflected on the posts from feed_destination.

I think that the problem is that by default, Android Navigation Component inflate navgraph destinations with option launchSingleTop as TRUE but I couldn't find how to change it to FALSE because the destination_posts is the StartDestination of Posts_navigation_graph and Posts_navigation_graph is programmatically inflated inside destination_feed and destination_profile. Below the code I am using (reduced to the parts that matters):

feed_navigation.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/feed_navigation"
    app:startDestination="@id/destination_feed">

    <fragment
        android:id="@+id/destination_feed"
        android:name="com.jonathan.maxplore.screen.feed.view.FeedFragment"
        android:label="@string/fragment_label_feed"
        tools:layout="@layout/fragment_feed">
        <argument
            android:name="showBottomNavigation"
            android:defaultValue="true" />
    </fragment>
</navigation>

profile_navigation.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/profile_navigation"
    app:startDestination="@id/destination_profile">

    <fragment
        android:id="@+id/destination_profile"
        android:name="com.jonathan.maxplore.screen.profile.view.ProfileFragment"
        android:label="@string/fragment_label_profile"
        tools:layout="@layout/fragment_profile">
        <argument
            android:name="showBottomNavigation"
            android:defaultValue="true" />
    </fragment>
</navigation>

posts_navigation.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/posts_navigation"
    app:startDestination="@id/destination_posts">

    <fragment
        android:id="@+id/destination_posts"
        android:name="com.jonathan.maxplore.screen.posts.view.PostsFragment"
        android:label="@string/fragment_label_posts"
        tools:layout="@layout/fragment_posts">
        <argument
            android:name="showAppBar"
            android:defaultValue="true" />

        <argument
            android:name="mode"
            app:argType="com.jonathan.maxplore.util.PostsMode"/>

        <argument
            android:name="identifier"
            android:defaultValue="0L"
            app:argType="long"/>
    </fragment>
</navigation>

fragment_feed.xml

<androidx.fragment.app.FragmentContainerView
            android:id="@+id/fragment_feed_content"
            android:name="androidx.navigation.fragment.NavHostFragment"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_behavior="@string/appbar_scrolling_view_behavior"
            app:defaultNavHost="true"/>

fragment_profile.xml

<androidx.fragment.app.FragmentContainerView
            android:id="@+id/fragment_profile_content"
            android:name="androidx.navigation.fragment.NavHostFragment"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_behavior="@string/appbar_scrolling_view_behavior"
            app:defaultNavHost="true"/>

FeedFragment.kt

val extras = arguments
    extras?.putSerializable(ConstantsUtil.Extras.EXTRA_POSTS_MODE, PostsMode.GLOBAL)
    extras?.putBoolean(ConstantsUtil.Extras.EXTRA_BOTTOM_NAVIGATION_ACCESS, true)

    val navHostFragment = (childFragmentManager.findFragmentById(R.id.fragment_feed_content) as NavHostFragment)
    val navGraph = navHostFragment.navController.navInflater.inflate(R.navigation.posts_navigation)
    navHostFragment.navController.setGraph(navGraph, extras)

ProfileFragment.KT

val extras = arguments
    extras?.putSerializable(ConstantsUtil.Extras.EXTRA_POSTS_MODE, PostsMode.MINE)
    extras?.putBoolean(ConstantsUtil.Extras.EXTRA_BOTTOM_NAVIGATION_ACCESS, true)

val navHostFragment = (childFragmentManager.findFragmentById(R.id.fragment_profile_content) as NavHostFragment)
    val navGraph = navHostFragment.navController.navInflater.inflate(R.navigation.posts_navigation)
    navHostFragment.navController.setGraph(navGraph, extras)

Any suggestion on how to fix it or even what else could be happening so I can further investigate it is very much appreciated! Thank you in advance guys!


Solution

  • I found the issue. The problem wasn't related to Android Navigation Component. I Also use Paging 3 and when I refresh the Posts fragment I delete all posts and add the first page of posts that I receive from backend. The problem was that when opening User Profile, I was refreshing the posts and that was making all posts to be deleted and only added the user posts into local database. Then when going back to Feed screen, the only posts in the database at that point are the ones from the selected user.

    Problem fixed. Thank you all.