web-dev-qa-db-ja.com

ナビゲーションドロワーでのナビゲーションアーキテクチャコンポーネントの使用

Navigation Architecture Component (NavHostFragment)を Navigation Drawer (widget.NavigationView)とともに使用しようとしています。次の2つのエラーのいずれかが発生します。

1)これは、ドロワーからアイテムを数回選択したときに発生する可能性があります。

Java.lang.IllegalArgumentException: navigation destination app.myDomain.navdrawertrials:id/action_rootFragment_to_settingsFragment is unknown to this NavController

2)これは、AFAICTの下の簡略化されたサンプルと同じ方法で設定された実際のコードベースから発生します。現在のナビゲーションノードが設定されないのはなぜですか?

Java.lang.IllegalStateException: no current navigation node

簡略化されたコード

主な活動

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.main_activity)

        setupToolbar()
        setupNavDrawer()
        setupNavigation()
    }


    private fun setupToolbar() {
        setSupportActionBar( toolbar )
    }

    private fun setupNavigation() {
        val navController = findNavController( R.id.nav_Host_fragment)

        setupActionBarWithNavController( navController, main_activity_drawer_layout )
    }

    private fun setupNavDrawer() {
        val toggle = ActionBarDrawerToggle(
                this,
                main_activity_drawer_layout,
                toolbar,
                R.string.navigation_drawer_open,
                R.string.navigation_drawer_close)

        main_activity_drawer_layout.addDrawerListener(toggle)
        toggle.syncState()


        nav_drawer.setNavigationItemSelectedListener {
            val navController = findNavController( R.id.nav_Host_fragment )

            when (it.itemId) {
                R.id.nav_drawer_root_menu_item     -> navController.navigate(R.id.rootFragment)
                R.id.nav_drawer_first_menu_item    -> navController.navigate(R.id.action_rootFragment_to_firstFragment)
                R.id.nav_drawer_settings_menu_item -> navController.navigate(R.id.action_rootFragment_to_settingsFragment)
            }

            main_activity_drawer_layout.closeDrawer(GravityCompat.START)

            true
        }
    }

    override fun onSupportNavigateUp() = findNavController(R.id.nav_Host_fragment).navigateUp()
}

main_activity.xml

<Android.support.v4.widget.DrawerLayout
    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_drawer_layout"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent">

    <include
        layout="@layout/main_activity_content"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent" />

    <Android.support.design.widget.NavigationView
        Android:id="@+id/nav_drawer"
        Android:layout_width="wrap_content"
        Android:layout_height="match_parent"
        Android:layout_gravity="start"
        Android:fitsSystemWindows="true"
        app:headerLayout="@layout/nav_drawer_header"
        app:menu="@menu/nav_drawer_menu" />

</Android.support.v4.widget.DrawerLayout>

nav_drawer_menu.xml

<menu xmlns:Android="http://schemas.Android.com/apk/res/Android">

    <item
        Android:id="@+id/nav_drawer_root_menu_item"
        Android:title="To Root" />
    <item
        Android:id="@+id/nav_drawer_first_menu_item"
        Android:title="To First" />
    <item
        Android:id="@+id/nav_drawer_settings_menu_item"
        Android:title="To Settings" />
</menu>

main_activity_content.xml

<Android.support.design.widget.CoordinatorLayout
    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:layout_width="match_parent"
    Android:layout_height="match_parent"
    tools:context=".MainActivity">

    <Android.support.design.widget.AppBarLayout
        Android:layout_width="match_parent"
        Android:layout_height="wrap_content"
        Android:theme="@style/AppTheme">

        <Android.support.v7.widget.Toolbar
            Android:id="@+id/toolbar"
            Android:layout_width="match_parent"
            Android:layout_height="?attr/actionBarSize"
            Android:background="?attr/colorPrimary" />

    </Android.support.design.widget.AppBarLayout>

    <fragment
        Android:id="@+id/nav_Host_fragment"
        Android:name="androidx.navigation.fragment.NavHostFragment"
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"
        app:navGraph="@navigation/nav_graph"
        app:defaultNavHost="true"
        />

    <Android.support.design.widget.FloatingActionButton
        Android:id="@+id/fab"
        Android:layout_width="wrap_content"
        Android:layout_height="wrap_content"
        Android:layout_gravity="bottom|end"
        Android:layout_margin="@dimen/fab_margin"
        app:srcCompat="@Android:drawable/ic_dialog_email" />

</Android.support.design.widget.CoordinatorLayout>

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

    <fragment
        Android:id="@+id/rootFragment"
        Android:name="app.anytune.navdrawertrials.RootFragment"
        Android:label="root_fragment"
        tools:layout="@layout/root_fragment" >
        <action
            Android:id="@+id/action_rootFragment_to_firstFragment"
            app:destination="@id/firstFragment" />
        <action
            Android:id="@+id/action_rootFragment_to_settingsFragment"
            app:destination="@id/settingsFragment" />
    </fragment>
    <fragment
        Android:id="@+id/firstFragment"
        Android:name="app.anytune.navdrawertrials.FirstFragment"
        Android:label="first_fragment"
        tools:layout="@layout/first_fragment" />
    <fragment
        Android:id="@+id/settingsFragment"
        Android:name="app.anytune.navdrawertrials.SettingsFragment"
        Android:label="settings_fragment"
        tools:layout="@layout/settings_fragment" />
</navigation>

root_fragment.xml(他のノードはラベルだけの同様の空のフラグメントです)

<FrameLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
    xmlns:tools="http://schemas.Android.com/tools"
    Android:layout_width="match_parent"
    Android:layout_height="match_parent"
    tools:context=".RootFragment">

    <TextView
        Android:layout_width="match_parent"
        Android:layout_height="match_parent"
        Android:text="Root Fragment" />

</FrameLayout>
5
Jim Leask

最初のエラーに関しては、コードに基づいて、ユーザーがドロワーから「first」または「settings」を選択すると、action_rootFragment_to_firstFragmentまたはaction_rootFragment_to_settingsFragmentアクションを使用して「first」または「settings」フラグメントに転送されます。ドロワーから「最初の」または「設定」を再度選択しようとすると、ナビゲーショングラフ内のfirstFragmentまたはsettingsFragment要素内にaction_rootFragment_to_firstFragmentまたはaction_rootFragment_to_settingsFragmentアクションがありません。

解決策は変更することです:

when (it.itemId) { 
            R.id.nav_drawer_root_menu_item     -> navController.navigate(R.id.rootFragment) 
            R.id.nav_drawer_first_menu_item    -> navController.navigate(R.id.action_rootFragment_to_firstFragment) 
            R.id.nav_drawer_settings_menu_item -> navController.navigate(R.id.action_rootFragment_to_settingsFragment) 
        } 

に:

   when (it.itemId) { 
            R.id.nav_drawer_root_menu_item     -> navController.navigate(R.id.rootFragment) 
            R.id.nav_drawer_first_menu_item    -> navController.navigate(R.id.firstFragment) 
            R.id.nav_drawer_settings_menu_item -> navController.navigate(R.id.settingsFragment) 
        } 

より良い解決策は、宛先をメニュー方式のUIコンポーネント(ケースドロワーの場合)に関連付け、メニュー項目IDを次のように宛先IDと同じに変更することです。

<item
    Android:id="@+id/rootFragment"
    Android:title="To Root" />
<item
    Android:id="@+id/firstFragment"
    Android:title="To First" />
<item
    Android:id="@+id/settingsFragment"
    Android:title="To Settings" />

と追加

 setupWithNavController(nav_view, navController )

あなたのメインアクティビティの中でではなく

nav_drawer.setNavigationItemSelectedListener {
        val navController = findNavController( R.id.nav_Host_fragment )

        when (it.itemId) {
            R.id.nav_drawer_root_menu_item     -> navController.navigate(R.id.rootFragment)
            R.id.nav_drawer_first_menu_item    -> navController.navigate(R.id.action_rootFragment_to_firstFragment)
            R.id.nav_drawer_settings_menu_item -> navController.navigate(R.id.action_rootFragment_to_settingsFragment)
        }

        main_activity_drawer_layout.closeDrawer(GravityCompat.START)

        true
    }
1
Alex

2)向きの変更時にクラッシュが発生した場合。アクティビティアップグレードナビゲーションバージョンモジュールで以下を2.2.0以降に使用します

implementation "androidx.navigation:navigation-fragment-ktx:2.2.0"
implementation "androidx.navigation:navigation-ui-ktx:2.2.0"
0
jeonghyeon kim