Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
184 views
in Technique[技术] by (71.8m points)

java - Android - Using Muiltiple Navigation Graphs Is Not Working

I'm using the Google's solution for the fragment state problem of the BottomNavigationView and navigation component, which is using multiple nav graphs along with this extension function: https://github.com/android/architecture-components-samples/blob/master/NavigationAdvancedSample/app/src/main/java/com/example/android/navigationadvancedsample/NavigationExtensions.kt

However, the problem is the initial navigation graph is totally different than the ones I've provided (its id is 2131230909 as you can see from the logs) I have no idea where it gets that id from. And because of that, selectedId if check (if (this.selectedItemId == graphId) ) is failing in the extension function and therefore it's never attaching the navHostFragment. Setting the selectedItem of the BottomNav is not working either: binding.bottomNavView.setSelectedItemId( R.navigation.game_list)



Here are my logs, let me know if you have any idea why this might be happening:

D/NavigationExtensionsKt: creating NavHostFragment with id: 2131623937
D/NavigationExtensionsKt: detaching NavHostFragment with id: 2131623937
D/NavigationExtensionsKt: creating NavHostFragment with id: 2131623936
D/NavigationExtensionsKt: detaching NavHostFragment with id: 2131623936
D/NavigationExtensionsKt: selectedItemId: 2131230909, firstFragmentTag: bottomNavigation#0, isOnFirstFragment: false

Game List Navigation Graph

<?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/game_list"
    app:startDestination="@id/gameListFragment">

    <fragment
        android:id="@+id/gameListFragment"
        android:name="com.developerkurt.gamedatabase.ui.GameListFragment"
        android:label="GameListFragment"
        tools:layout="@layout/game_list_fragment">
        <action
            android:id="@+id/action_gameListFragment_to_gameDetailsFragment"
            app:destination="@id/gameDetailsFragment" />
    </fragment>

    <fragment
        android:id="@+id/gameDetailsFragment"
        android:name="com.developerkurt.gamedatabase.ui.GameDetailsFragment"
        android:label="GameDetailsFragment"
        tools:layout="@layout/game_details_fragment_motion_scene_end">
        <argument
            android:name="id"
            app:argType="integer" />
        <argument
            android:name="isInFavorites"
            app:argType="boolean" />
    </fragment>
</navigation>

Favorite Games Navigation Graph

<?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/fav_games"
    app:startDestination="@id/favoriteGamesFragment">

    <fragment
        android:id="@+id/favoriteGamesFragment"
        android:name="com.developerkurt.gamedatabase.ui.FavoriteGamesFragment"
        android:label="FavoriteGamesFragment"
        tools:layout="@layout/favorite_games_fragment">
        <action
            android:id="@+id/action_favoriteGamesFragment_to_gameDetailsFragment"
            app:destination="@id/gameDetailsFragment" />
    </fragment>
    <fragment
        android:id="@+id/gameDetailsFragment"
        android:name="com.developerkurt.gamedatabase.ui.GameDetailsFragment"
        android:label="GameDetailsFragment"
        tools:layout="@layout/game_details_fragment_motion_scene_end">
        <argument
            android:name="id"
            app:argType="integer" />
        <argument
            android:name="isInFavorites"
            app:argType="boolean" />
    </fragment>
</navigation>

MainActivity

class MainActivity : AppCompatActivity()
{

    private lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?)
    {
        super.onCreate(savedInstanceState)

        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        if (savedInstanceState == null)
        {
            setupBottomNavigationBar()
        } // Else, need to wait for onRestoreInstanceState
    }


    override fun onRestoreInstanceState(savedInstanceState: Bundle)
    {
        super.onRestoreInstanceState(savedInstanceState)
        // Now that BottomNavigationBar has restored its instance state
        // and its selectedItemId, we can proceed with setting up the
        // BottomNavigationBar with Navigation
        setupBottomNavigationBar()
    }

    fun setupBottomNavigationBar()
    {
        binding.bottomNavView.visibility = View.VISIBLE

        val navGraphIds = listOf(R.navigation.game_list, R.navigation.fav_games)


        // Setup the bottom navigation view with a list of navigation graphs
        binding.bottomNavView.setupWithNavController(
                navGraphIds = navGraphIds,
                fragmentManager = supportFragmentManager,
                containerId = R.id.fragment_container,
                intent = intent)
        
    }
}

MainActivity Layout

  <?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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_activity"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".ui.MainActivity">
    
    <androidx.fragment.app.FragmentContainerView
        android:id="@+id/fragment_container"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="0dp"

        app:layout_constraintBottom_toTopOf="@+id/bottom_nav_view"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        />


    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/bottom_nav_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"

        app:layout_constraintBottom_toBottomOf="parent"
        app:menu="@menu/bottom_nav_menu" />


</androidx.constraintlayout.widget.ConstraintLayout>

BottomNavMenu

  <?xml version="1.0" encoding="utf-8"?>
    <menu xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/bottom_nav_menu">
    
        <item
            android:id="@+id/gameListFragment"
            android:icon="@drawable/ic_home"
            android:menuCategory="secondary"
            android:title="@string/home" />
        <item
            android:id="@+id/favoriteGamesFragment"
            android:icon="@drawable/ic_favorite"
            android:menuCategory="secondary"
            android:title="@string/favorites" />
</menu>
question from:https://stackoverflow.com/questions/65876857/android-using-muiltiple-navigation-graphs-is-not-working

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You're using the wrong IDs for your menu items - the NavigationExtensions is comparing your menu IDs to the android:id on the root <navigation> element and not the IDs of the start destinations of those graphs.

Therefore you should be using android:id="@+id/game_list" and android:id="@+id/fav_games" for your menu items to match the graph IDs.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...