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>
最初のエラーに関しては、コードに基づいて、ユーザーがドロワーから「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
}
2)向きの変更時にクラッシュが発生した場合。アクティビティアップグレードナビゲーションバージョンモジュールで以下を2.2.0以降に使用します
implementation "androidx.navigation:navigation-fragment-ktx:2.2.0"
implementation "androidx.navigation:navigation-ui-ktx:2.2.0"