Android – How To Communicate Between Fragments Using SharedViewModel ?

Hello Readers, CoolMonkTechie heartily welcomes you in this article.

In this article, we will learn how we can use the ViewModel in our application to communicate between various fragments in our application. We say it as SharedViewModel. Communication between Activities or Fragments in Android is a very common thing. Almost every application has some communication between various activities or fragments.

Using SharedViewModel, we can communicate between fragments.

A famous quote about learning is :

“Live as if you were to die tomorrow. Learn as if you were to live forever.”

So Let’s begin.

Data sharing between Fragments

we can communicate between fragments using SharedViewModel. If we consider two fragments, both the fragments can access the ViewModel through their activity.

In this example, one fragment updates the data within the ViewModel which is shared between both the fragments and another fragment observes the changes on that data. We need to add the dependencies required for ViewModel, LiveData in the example.

First, we will create a class SharedViewModel.

class SharedViewModel : ViewModel() {
    val message = MutableLiveData<String>()

    fun sendMessage(text: String) {
        message.value = text
    }
}

Now, we are going to create two Fragments:

  • MessageReceiverFragment: This Fragment is going to receive the message which will be sent by MessageSenderFragment. It will have a TextView which will show the received message.
  • MessageSenderFragment: This Fragment is going to send the message which will be received by MessageReceiverFragment. It will have a Button to send the message.

MessageReceiverFragment class:

class MessageReceiverFragment : Fragment() {

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return inflater.inflate(R.layout.fragment_receiver, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        val model = ViewModelProvider(requireActivity()).get(SharedViewModel::class.java)
        model.message.observe(viewLifecycleOwner, Observer {
            textViewReceiver.text = it
        })
    }
}

fragment_receiver layout:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.appcompat.widget.AppCompatTextView
        android:id="@+id/textViewReceiver"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Send Your Message"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

MessageSenderFragment class:

class MessageSenderFragment : Fragment() {
    lateinit var model: SharedViewModel

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return inflater.inflate(R.layout.fragment_sender, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        model = ViewModelProvider(requireActivity()).get(SharedViewModel::class.java)
        button.setOnClickListener { model.sendMessage("MindOrks") }
    }
}

fragment_sender layout:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.appcompat.widget.AppCompatButton
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Send Your Message"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

Now, let’s update the activity_main.xml.

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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">

    <fragment
        android:id="@+id/receiverFragment"
        android:name="com.mindorks.sharedviewmodelsample.MessageReceiverFragment"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginBottom="8dp"
        app:layout_constraintBottom_toTopOf="@+id/senderFragment"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <fragment
        android:id="@+id/senderFragment"
        android:name="com.mindorks.sharedviewmodelsample.MessageSenderFragment"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginBottom="8dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/receiverFragment" />


</androidx.constraintlayout.widget.ConstraintLayout>

Our MainActivity Class:

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }
}

Now, we are ready to run the app, see if it is working as expected. It should work.

Let’s discuss how it is working:

  • Here, we have created an activity that consists of two fragments. The same activity is the host for both the fragment.
  • In both the fragment, we have created the object of SharedViewModel which is the same object as we are using the same single activity as an owner. This is the reason it is shared. Notice that we have used the requireActivity().
  • In the MessageSenderFragment, we are sending the message on button click, which sets the value of message - LiveData in the SharedViewModel.
  • Then, in the MessageReceiverFragment, we are observing the change in the message - LiveData, and whenever the message is coming, we are updating the data in textView.

This is how it works.

That’s all about in this article.

Conclusion

In this article, we learned about Shared ViewModel in Android to communicate with other fragments. In the last, we saw one example of fragment communication using Shared ViewModel

Thanks for reading ! I hope you enjoyed and learned about Shared ViewModel in Android to communicate with other fragments. Reading is one thing, but the only way to master it is to do it yourself.

Please follow and subscribe us on this blog and and support us in any way possible. Also like and share the article with others for spread valuable knowledge.

If you have any comments, questions, or think I missed something, feel free to leave them below in the comment box.

Thanks again Reading. HAPPY READING !! ???

Exit mobile version