使用 Navigation - Kotlin 从工具栏菜单项单击的片段之间传递数据
Passing data between fragments from toolbar menu item click using Navigation - Kotlin
我已经使用导航架构组件设置了我的应用程序。从一个片段导航到下一个片段工作正常。但是,我无法尝试在该导航流程中传递数据。
按照 Navigation codelab app 的结构,我使用下面的代码在单击菜单项时从一个片段导航到另一个片段:
MainActivity.kt
override fun onOptionsItemSelected(item: MenuItem): Boolean {
return NavigationUI.onNavDestinationSelected(item,
Navigation.findNavController(this, R.id.nav_host_fragment))
|| super.onOptionsItemSelected(item)
}
我尝试通过如下修改代码来将包传递到这里。 Android Studio 未检测到任何错误,但当我尝试执行该菜单项单击时,我的应用程序崩溃了。请注意,我将 R.id.menu_edit
作为 findNavController
中的参数传递,否则我会收到“没有为参数 'viewId' 传递任何值”构建错误 - 但我认为您通常会在不传递任何内容的情况下调用它.
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item?.itemId) {
R.id.menu_song_edit -> {
val songBundle = Bundle()
songBundle.putString("titleArg", song_title.toString())
this.findNavController(R.id.menu_song_edit).navigate(R.id.goto_songedit, songBundle) // *** this is line 96 where it crashes per the log ***
return true
}
else -> return NavigationUI.onNavDestinationSelected(item,
Navigation.findNavController(this, R.id.nav_host_fragment))
|| super.onOptionsItemSelected(item)
}
}
从下面的崩溃记录。找不到 NavController?
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.projects.arise.mytestapp, PID: 1162
java.lang.IllegalStateException: Activity com.projects.arise.mytestapp.MainActivity@58f00cb does not have a NavController set on 2131230836
at androidx.navigation.Navigation.findNavController(Navigation.java:60)
at androidx.navigation.ActivityKt.findNavController(Activity.kt:30)
at com.projects.arise.mytestapp.MainActivity.onOptionsItemSelected(MainActivity.kt:96)
at android.app.Activity.onMenuItemSelected(Activity.java:3204)
at android.support.v4.app.FragmentActivity.onMenuItemSelected(FragmentActivity.java:407)
at android.support.v7.app.AppCompatActivity.onMenuItemSelected(AppCompatActivity.java:195)
at android.support.v7.view.WindowCallbackWrapper.onMenuItemSelected(WindowCallbackWrapper.java:108)
at android.support.v7.view.WindowCallbackWrapper.onMenuItemSelected(WindowCallbackWrapper.java:108)
at android.support.v7.app.ToolbarActionBar.onMenuItemClick(ToolbarActionBar.java:63)
at android.support.v7.widget.Toolbar.onMenuItemClick(Toolbar.java:203)
at android.support.v7.widget.ActionMenuView$MenuBuilderCallback.onMenuItemSelected(ActionMenuView.java:780)
at android.support.v7.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:822)
at android.support.v7.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:171)
at android.support.v7.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:973)
at android.support.v7.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:963)
at android.support.v7.widget.ActionMenuView.invokeItem(ActionMenuView.java:624)
at android.support.v7.view.menu.ActionMenuItemView.onClick(ActionMenuItemView.java:150)
at android.view.View.performClick(View.java:5610)
at android.view.View$PerformClick.run(View.java:22265)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756) Disconnected from the target VM, address: 'localhost:8610', transport: 'socket'
然后我尝试在传递数据的片段中覆盖 onOptionsItemSelected
,但这似乎没有任何效果。我猜那是因为它已经被上面 MainActivity.kt 中的相同方法拦截了。
我在数据发送片段中的代码如下。资源ID'goto_detailsedit'指的是导航nav_graph.xml文件中action
的ID。
override fun onOptionsItemSelected(item: MenuItem?): Boolean {
when (item?.itemId) {
R.id.menu_edit -> {
val songBundle = Bundle()
songBundle.putString("nameArg", first_name.text.toString())
this.findNavController().navigate(R.id.goto_songedit, songBundle)
return true
}
else -> return super.onOptionsItemSelected(item)
}
}
有人可以帮我解决上面 MainActivity.kt 代码中的菜鸟语法错误吗?
2018 年 7 月 2 日更新
再次浏览 documentation 我发现语法应该如下 - 我需要引用一个视图:
view.findNavController().navigate(R.id.confirmationAction, bundle)
我已经在 onCreate
中设置了主 activity 中的工具栏,方法是调用:
val toolbar = findViewById<Toolbar>(R.id.toolbar)
setSupportActionBar(toolbar)
所以我尝试通过将 this
替换为 toolbar
来引用工具栏:
toolbar.findNavController().navigate(R.id.goto_songedit, songBundle)
Android Studio 代码编辑器现在很满意,但我的应用程序仍然崩溃。日志指出 NavController 尚未设置:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.projects.arise.mytestapp, PID: 2670
java.lang.IllegalStateException: View android.support.v7.widget.Toolbar{d03bbdd V.E...... ........ 0,0-1080,147 #7f0800e0 app:id/toolbar} does not have a NavController set
at androidx.navigation.Navigation.findNavController(Navigation.java:83)
at androidx.navigation.ViewKt.findNavController(View.kt:28)
at com.projects.arise.mytestapp.MainActivity.onOptionsItemSelected(MainActivity.kt:96)
...
有什么我想念的吗?或者这可能是导航的错误?
你应该使用 'NavHostFragment.findNavController()':
override fun onOptionsItemSelected(item: MenuItem?): Boolean {
when (item?.itemId) {
R.id.menu_edit -> {
val songBundle = Bundle()
songBundle.putString("nameArg", first_name.text.toString())
NavHostFragment.findNavController(nav_host_fragment).navigate(R.id.goto_songedit, songBundle)
return true
}
else -> return super.onOptionsItemSelected(item)
}
}
完美解决方案:
//-------------------/To send Data/--------------------
val bundle = Bundle()
bundle.putString("data","Hello World!")
Navigation.findNavController(view).navigate(R.id.action_firstFragment_to_secondFragment,bundle)
//--------------------/To get data/----------------------------------
val string = arguments!!.getString("data")
Toast.makeText(context,string,Toast.LENGTH_SHORT).show()
我已经使用导航架构组件设置了我的应用程序。从一个片段导航到下一个片段工作正常。但是,我无法尝试在该导航流程中传递数据。
按照 Navigation codelab app 的结构,我使用下面的代码在单击菜单项时从一个片段导航到另一个片段:
MainActivity.kt
override fun onOptionsItemSelected(item: MenuItem): Boolean {
return NavigationUI.onNavDestinationSelected(item,
Navigation.findNavController(this, R.id.nav_host_fragment))
|| super.onOptionsItemSelected(item)
}
我尝试通过如下修改代码来将包传递到这里。 Android Studio 未检测到任何错误,但当我尝试执行该菜单项单击时,我的应用程序崩溃了。请注意,我将 R.id.menu_edit
作为 findNavController
中的参数传递,否则我会收到“没有为参数 'viewId' 传递任何值”构建错误 - 但我认为您通常会在不传递任何内容的情况下调用它.
override fun onOptionsItemSelected(item: MenuItem): Boolean {
when (item?.itemId) {
R.id.menu_song_edit -> {
val songBundle = Bundle()
songBundle.putString("titleArg", song_title.toString())
this.findNavController(R.id.menu_song_edit).navigate(R.id.goto_songedit, songBundle) // *** this is line 96 where it crashes per the log ***
return true
}
else -> return NavigationUI.onNavDestinationSelected(item,
Navigation.findNavController(this, R.id.nav_host_fragment))
|| super.onOptionsItemSelected(item)
}
}
从下面的崩溃记录。找不到 NavController?
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.projects.arise.mytestapp, PID: 1162
java.lang.IllegalStateException: Activity com.projects.arise.mytestapp.MainActivity@58f00cb does not have a NavController set on 2131230836
at androidx.navigation.Navigation.findNavController(Navigation.java:60)
at androidx.navigation.ActivityKt.findNavController(Activity.kt:30)
at com.projects.arise.mytestapp.MainActivity.onOptionsItemSelected(MainActivity.kt:96)
at android.app.Activity.onMenuItemSelected(Activity.java:3204)
at android.support.v4.app.FragmentActivity.onMenuItemSelected(FragmentActivity.java:407)
at android.support.v7.app.AppCompatActivity.onMenuItemSelected(AppCompatActivity.java:195)
at android.support.v7.view.WindowCallbackWrapper.onMenuItemSelected(WindowCallbackWrapper.java:108)
at android.support.v7.view.WindowCallbackWrapper.onMenuItemSelected(WindowCallbackWrapper.java:108)
at android.support.v7.app.ToolbarActionBar.onMenuItemClick(ToolbarActionBar.java:63)
at android.support.v7.widget.Toolbar.onMenuItemClick(Toolbar.java:203)
at android.support.v7.widget.ActionMenuView$MenuBuilderCallback.onMenuItemSelected(ActionMenuView.java:780)
at android.support.v7.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:822)
at android.support.v7.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:171)
at android.support.v7.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:973)
at android.support.v7.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:963)
at android.support.v7.widget.ActionMenuView.invokeItem(ActionMenuView.java:624)
at android.support.v7.view.menu.ActionMenuItemView.onClick(ActionMenuItemView.java:150)
at android.view.View.performClick(View.java:5610)
at android.view.View$PerformClick.run(View.java:22265)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756) Disconnected from the target VM, address: 'localhost:8610', transport: 'socket'
然后我尝试在传递数据的片段中覆盖 onOptionsItemSelected
,但这似乎没有任何效果。我猜那是因为它已经被上面 MainActivity.kt 中的相同方法拦截了。
我在数据发送片段中的代码如下。资源ID'goto_detailsedit'指的是导航nav_graph.xml文件中action
的ID。
override fun onOptionsItemSelected(item: MenuItem?): Boolean {
when (item?.itemId) {
R.id.menu_edit -> {
val songBundle = Bundle()
songBundle.putString("nameArg", first_name.text.toString())
this.findNavController().navigate(R.id.goto_songedit, songBundle)
return true
}
else -> return super.onOptionsItemSelected(item)
}
}
有人可以帮我解决上面 MainActivity.kt 代码中的菜鸟语法错误吗?
2018 年 7 月 2 日更新
再次浏览 documentation 我发现语法应该如下 - 我需要引用一个视图:
view.findNavController().navigate(R.id.confirmationAction, bundle)
我已经在 onCreate
中设置了主 activity 中的工具栏,方法是调用:
val toolbar = findViewById<Toolbar>(R.id.toolbar)
setSupportActionBar(toolbar)
所以我尝试通过将 this
替换为 toolbar
来引用工具栏:
toolbar.findNavController().navigate(R.id.goto_songedit, songBundle)
Android Studio 代码编辑器现在很满意,但我的应用程序仍然崩溃。日志指出 NavController 尚未设置:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.projects.arise.mytestapp, PID: 2670
java.lang.IllegalStateException: View android.support.v7.widget.Toolbar{d03bbdd V.E...... ........ 0,0-1080,147 #7f0800e0 app:id/toolbar} does not have a NavController set
at androidx.navigation.Navigation.findNavController(Navigation.java:83)
at androidx.navigation.ViewKt.findNavController(View.kt:28)
at com.projects.arise.mytestapp.MainActivity.onOptionsItemSelected(MainActivity.kt:96)
...
有什么我想念的吗?或者这可能是导航的错误?
你应该使用 'NavHostFragment.findNavController()':
override fun onOptionsItemSelected(item: MenuItem?): Boolean {
when (item?.itemId) {
R.id.menu_edit -> {
val songBundle = Bundle()
songBundle.putString("nameArg", first_name.text.toString())
NavHostFragment.findNavController(nav_host_fragment).navigate(R.id.goto_songedit, songBundle)
return true
}
else -> return super.onOptionsItemSelected(item)
}
}
完美解决方案:
//-------------------/To send Data/--------------------
val bundle = Bundle()
bundle.putString("data","Hello World!")
Navigation.findNavController(view).navigate(R.id.action_firstFragment_to_secondFragment,bundle)
//--------------------/To get data/----------------------------------
val string = arguments!!.getString("data")
Toast.makeText(context,string,Toast.LENGTH_SHORT).show()