使用导航在工具栏菜单项中的片段之间传递数据-Kotlin

Den*_*815 2 navigation parameter-passing android-fragments kotlin android-toolbar

我已经使用导航架构组件设置了我的应用。从一个片段导航到下一个片段可以正常工作。但是,我一直试图在该导航流中传递数据。

按照Navigation codelab应用程序的结构,我使用下面的代码在菜单项上单击从一个片段导航到另一个片段:

MainActivity.kt

override fun onOptionsItemSelected(item: MenuItem): Boolean {
    return NavigationUI.onNavDestinationSelected(item,
        Navigation.findNavController(this, R.id.nav_host_fragment))
        || super.onOptionsItemSelected(item)
}
Run Code Online (Sandbox Code Playgroud)

我尝试通过如下修改代码将包分发给这里。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)
    }
}
Run Code Online (Sandbox Code Playgroud)

从下面的崩溃日志。找不到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$2.onMenuItemClick(ToolbarActionBar.java:63)
        at android.support.v7.widget.Toolbar$1.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'
Run Code Online (Sandbox Code Playgroud)

然后,我尝试覆盖onOptionsItemSelected传递数据的片段,但似乎没有任何效果。我猜是因为上面的MainActivity.kt中的相同方法已经拦截了它。

我在数据发送片段中的代码如下。资源ID“ goto_detailsedit”是指action导航nav_graph.xml文件中ID的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)
    }
}
Run Code Online (Sandbox Code Playgroud)

有人可以帮我解决上面MainActivity.kt代码中的菜鸟语法错误吗?

更新2018年7月2日

再次浏览文档,我发现语法应如下所示-我需要引用一个视图:

view.findNavController().navigate(R.id.confirmationAction, bundle)
Run Code Online (Sandbox Code Playgroud)

我已经onCreate通过调用以下内容在主活动中设置了工具栏:

val toolbar = findViewById<Toolbar>(R.id.toolbar)
    setSupportActionBar(toolbar)
Run Code Online (Sandbox Code Playgroud)

因此,我尝试通过替换this为来引用工具栏toolbar

toolbar.findNavController().navigate(R.id.goto_songedit, songBundle)
Run Code Online (Sandbox Code Playgroud)

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)
        ...
Run Code Online (Sandbox Code Playgroud)

有什么我想念的吗?或者这可能是导航的错误?

Ale*_*lex 5

您应该使用“ 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) 
    } 
} 
Run Code Online (Sandbox Code Playgroud)