1

I have an ChatRoomActivity with a NavHostFragment. Default fragment is ConversatioFragment which can open a MessageChoicesFragment which is a BottomSheetDialogFragment. There we have 3 choices 1) Copy message 2) Read from 3) Delete message.

If i click the 2) Read from (where i can see what recipients have read the message) i want to close the MessageChoicesFragment and open the MessageReadDialogFragment BottomSheetFragment.

So the desired flow that i want is this
ChatRoomActivity {
ConversationFragment --onClick--> MessageChoicesFragment --onClick-->
MessageReadDialogFragment
}

With more details. The navGraph of the ChatRoomActivity is the following

<?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" />
</navigation>

When user longPress on a message i open the MessageChoicesFragment

override fun onRowLongClicked() {     
   findNavController().navigate(R.id.action_conversationFragment_to_messageChoicesFragment)
}

The MessageChoicesFragment has 3 buttons. When i press the "Read from" button i want to close the MessageChoicesFragment and open the MessageReadDialogFragment

binding.readFromLayout.setOnClickListener {     
 findNavController().navigate(R.id.action_conversationFragment_to_messageReadDialogFragment)
 dialog?.dismiss()
}

However, this does not work since the current destination cannot find the action from another destination to "somewhere"

java.lang.IllegalArgumentException: Navigation action/destination com.example:id/action_conversationFragment_to_messageReadDialogFragment cannot be found from the current destination Destination(com.example:id/messageChoicesFragment) label=fragment_message_choices

So how can i solve that?

james04
  • 1,580
  • 2
  • 20
  • 46
  • You navigated via the action `action_conversationFragment_to_messageChoicesFragment`, so yeah, you are on `messageChoicesFragment`, just like the error message tells you. Why is your `MessagesChoicesFragment` trying to use the action `action_conversationFragment_to_messageReadDialogFragment` that is tied to only the `ConversationFragment` instead of an action attached to the `MessagesChoicesFragment` destination? – ianhanniballake Sep 22 '22 at 21:33
  • I know it is wrong. However i want the MessageReadDialog to be opened from ConversationFragment and not from MessageChoicesDialog because in the second case i will have 2 Dialogs one above the other... How can i prevent that? – james04 Sep 22 '22 at 21:47
  • 1
    Did you read the [documentation around popping a destination as part of a `navigate` call](https://developer.android.com/guide/navigation/navigation-navigate#pop)? – ianhanniballake Sep 22 '22 at 21:54
  • Wow....seems that this is what i want!! Let me try it...! – james04 Sep 22 '22 at 21:56

1 Answers1

0

Or you can use delegation function. Invoke your openReadFromBottomSHeet() function at your bottomSheetDialogFragment. And it will trigger your function at ConversatioFragment. Then, dismiss your previous bottomsheet and open new one for an option ReadFrom.

ConversationFragment{
     
     lateinit var messageChoicesDialogFragmentObj:     MessageChoicesDialogFragment()

     override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        messageChoicesDialogFragmentObj.onReadFromClick = {
            messageChoicesDialogFragmentObj.dismiss()
            openReadFrom()
        }
    }

    fun openMessageChoicesFragment(){
        // opens MessageChoicesDialogFragment
        messageChoicesDialogFragmentObj = MessageChoicesDialogFragment()
        messageChoicesDialogFragmentObj.show(childFragmentManager, "")
    }
    fun openReadFrom(){
        // opens ReadFromBottomSheetDialogFragment
    }
}

MessageChoicesDialogFragment{
    
    private val onReadFromClick: () -> Unit,

    fun onReadFromButtonClicked(){
          onReadFromClick.invoke()
    }
}

something like that. Sorry, I could not write all codes. This is just for your understanding. Delegations are very helpful. I hope it will help your.