Share Data Between Fragments Used ViewModel Example

It’s very common in the Android application that two or more Fragments in an Activity need to communicate with each other. Let see a common case of master-detail fragments, where you have a fragment in which the user selects an item from a list and another fragment that displays the contents of the selected item. In this tutorial, we are using a ViewModel class as an interface between Fragments to sharing data.

Share data between fragments used ViewModel examples

What are Fragments :

Android Fragment represents a behavior or a portion of user interface in an Activity (or in FragmentActivity). You can use multiple fragments in a single activity to build a multi-pane UI and can reuse a fragment in multiple activities.

ViewModel :

The ViewModel class is designed to store and manage UI-related data in a lifecycle-conscious way. Here we are using the ViewModel class as an interface between Fragments to sharing data.

Consider we have 2 fragments Sender and Receiver and Suppose you need to share data between Sender and Receiver.

For this, you have to create a ViewModel class and implements methods in Sender pass the data to the Receiver, where receiver have an observer to see change and update UI accordingly.

Let’s start building basic: How to share data Between two fragments

Step 1. Create an android project in the android studio (Android First Program in Android Studio)
Step 2. Create 2 fragments in activity_main.xml

add following code :

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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="in.eyehunt.commFragmentsViewModel.MainActivity">

    <fragment
        android:id="@+id/frg_Receiver"
        android:name="in.eyehunt.commFragmentsViewModel.ReceiverFragment"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_marginBottom="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        app:layout_constraintBottom_toTopOf="@+id/frg_Sender"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.5"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

    </fragment>

    <fragment
        android:id="@+id/frg_Sender"
        android:name="in.eyehunt.commFragmentsViewModel.SenderFragment"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_marginBottom="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginStart="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/frg_Receiver">

    </fragment>

</android.support.constraint.ConstraintLayout>
Step 3. Create new class SharedViewModel and extend View Model

Initialize variable “message” for sharing data and Generate Getter and setter.

package in.eyehunt.ShareFragmentsViewModel;

import android.arch.lifecycle.MutableLiveData;
import android.arch.lifecycle.ViewModel;

public class SharedViewModel extends ViewModel {
    private final MutableLiveData message = new MutableLiveData();

    public void setMessage(String msg){
        message.setValue(msg);
    }

    public MutableLiveData getMessage() {
        return message;
    }
}
Step 4. Create a layout and activity file for sender fragment with a button to send a message

Copy paste code must add color code in res/values/colors.xml before its throw error

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="colorPrimary">#000000</color>
    <color name="colorPrimaryDark">#000000</color>
    <color name="colorAccent">#ffffff</color>
    <color name="colorSen">#009688</color>
    <color name="colorRec">#3f51b5</color>
    <color name="White">#ffffff</color>
</resources>
Then sender layout file
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/colorSen"
    tools:context="in.eyehunt.ShareFragmentsViewModel.SenderFragment">

    <Button
        android:id="@+id/btn_sender"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:layout_gravity="center"
        android:gravity="center"
        android:text="Send Hello" />
</RelativeLayout>
Create an activity class for Sender

Note: when you are creating sender file that time also can generate layout file for the same fragment.

Create an instance of SharedViewModel model and button.setOnClickListener to send data

package in.eyehunt.ShareFragmentsViewModel;

import android.arch.lifecycle.ViewModelProviders;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;

public class SenderFragment extends Fragment {
    private SharedViewModel model;

    public SenderFragment() {
        // Required empty public constructor
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_sender, container, false);
        model = ViewModelProviders.of(getActivity()).get(SharedViewModel.class);

        Button button = (Button) view.findViewById(R.id.btn_sender);
        // on click button
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                model.setMessage("Hello Fragment i am Sender - ViewModel");
            }
        });
        return view;
    }
}
Step 6. Create a layout and activity  file for the receiver

Add TextView in Fragments to show shared data

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/colorRec"
    tools:context="in.eyehunt.ShareFragmentsViewModel.ReceiverFragment">

    <TextView
        android:id="@+id/tv_receiver"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:gravity="center"
        android:text="Receiver"
        android:textColor="@color/White"
        android:textSize="18sp"/>

</RelativeLayout>
Create an activity class for Receiver

get the result in ViewModel object observer and show in TextView.

package in.eyehunt.ShareFragmentsViewModel;


import android.arch.lifecycle.Observer;
import android.arch.lifecycle.ViewModelProviders;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

public class ReceiverFragment extends Fragment {

    TextView tv_msg;

    public ReceiverFragment() {
        // Required empty public constructor
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_receiver, container, false);

        final SharedViewModel model = ViewModelProviders.of(getActivity()).get(SharedViewModel.class);
        tv_msg = (TextView) view.findViewById(R.id.tv_receiver);

        model.getMessage().observe(this, new Observer() {
            @Override
            public void onChanged(@Nullable Object o) {
                tv_msg.setText(o.toString());
            }
        });
        return view;
    }
}
Output Screenshot: Before
Pass data between fragments used ViewModel example

After click button “SEND HELLO”

How to share data between fragments used ViewModel example

Download Link and Source code Share data between fragments used ViewModel example

https://github.com/EyeHunts/ShareFragmentsViewModel

Code in Kotin 

https://github.com/EyeHunts/ShareFragmentsViewModelK

Note : This example (Project) is developed in Android Studio 3.0.1 ,tested on Android 7.1.1 ( Android Nougat), compile SDK version API 26: Android 8.0 (Oreo)

MinSdkVersion=”15″

TargetSdkVersion=”26″

Coding in JAVA

Bonus: For share data between fragment using interface check this tutorial: Basic Communication between two fragments (Pass data)


4 thoughts on “Share Data Between Fragments Used ViewModel Example

  1. Hello, can you help me achieve the same result in Kotlin?
    Specifically on the part of the receiver, because I think I’ve got everything else already.

    1. Check tutoiral, we updated kotlin source code…
      class ReceiverFragment : Fragment() {

      internal lateinit var tv_msg: TextView

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

      val model = ViewModelProviders.of(activity!!).get(SharedViewModel::class.java)
      tv_msg = view.findViewById(R.id.tv_receiver) as TextView

      model.message.observe(this, object : Observer {
      override fun onChanged(o: Any?) {
      tv_msg.text = o!!.toString()
      }
      })
      return view
      }
      }

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.