Android中BottomSheetDialogFragment跳转另一个的报错解决
问题分析
报错的核心原因是:action_conversationFragment_to_messageReadDialogFragment这个导航动作是定义在ConversationFragment节点下的,而当前代码是在MessageChoicesFragment中调用该动作——导航控制器在当前页面的导航节点下找不到对应的跳转规则,因此抛出IllegalArgumentException。
解决方案
推荐两种符合Navigation规范的解决方式:
方式一:在导航图中添加跨对话框的跳转动作
1. 修改导航图配置
在messageChoicesFragment的<dialog>节点下,新增直接跳转到messageReadDialogFragment的action,并配置回退栈清理规则:
<?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/chat_room_nav_menu" app:startDestination="@id/conversationFragment"> <fragment android:id="@+id/conversationFragment" android:name="com.example.ui.fragments.chatroom.ConversationFragment" android:label="conversation_fragment" tools:layout="@layout/conversation_fragment" > <action android:id="@+id/action_conversationFragment_to_messageChoicesFragment" app:destination="@id/messageChoicesFragment" /> <action android:id="@+id/action_conversationFragment_to_messageReadDialogFragment" app:destination="@id/messageReadDialogFragment" /> </fragment> <dialog android:id="@+id/messageReadDialogFragment" android:name="com.example.ui.dialogs.chatroom.MessageReadDialogFragment" android:label="MessageReadDialogFragment" tools:layout="@layout/message_read_panel"/> <dialog android:id="@+id/messageChoicesFragment" android:name="com.example.ui.dialogs.chatroom.MessageChoicesFragment" android:label="fragment_message_choices" tools:layout="@layout/fragment_message_choices" > <!-- 新增的跳转动作 --> <action android:id="@+id/action_messageChoicesFragment_to_messageReadDialogFragment" app:destination="@id/messageReadDialogFragment" <!-- 清理回退栈中的当前对话框 --> app:popUpTo="@id/messageChoicesFragment" app:popUpToInclusive="true"/> </dialog> </navigation>
app:popUpTo="@id/messageChoicesFragment":导航到目标页面时,回退栈中该节点之前的内容会被弹出app:popUpToInclusive="true":将当前的messageChoicesFragment本身也从回退栈中移除,确保返回时直接回到ConversationFragment
2. 修改点击事件代码
调用新增的action即可,无需手动关闭对话框(Navigation会自动处理):
binding.readFromLayout.setOnClickListener { findNavController().navigate(R.id.action_messageChoicesFragment_to_messageReadDialogFragment) }
方式二:直接操作回退栈+导航到目标页面
如果不想修改导航图,可直接通过代码弹出当前对话框,再打开新对话框:
binding.readFromLayout.setOnClickListener { findNavController().run { popBackStack() // 弹出当前的MessageChoicesFragment navigate(R.id.messageReadDialogFragment) // 打开新的对话框 } }
这种方式适合简单场景,但如果需要传递参数,推荐使用方式一(可在导航图中配置参数规则,更易维护)。
注意事项
- 无需手动调用
dialog?.dismiss(),Navigation会自动管理BottomSheetDialogFragment的生命周期,手动关闭可能导致导航栈与实际页面状态不一致。
内容的提问来源于stack exchange,提问作者james04
相关产品推荐
相关产品推荐

