Fragment communication in android application

In the last couple of days I've changed the communication model between the fragments and the main activity, so I decided to write a short article about this, using plain simpe Java, not Kotlin.

First, some dependencies in the gradle:

dependencies {
implementation 'androidx.appcompat:appcompat:1.0.2'
implementation 'com.google.android.material:material:1.0.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.lifecycle:lifecycle-extensions:2.0.0'
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
}

In the XML layout of the Fragment, a View to be modified according with an activity's variable (in this case a TextView):

 ..
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:minHeight="?actionBarSize"
android:padding="@dimen/appbar_padding"
android:text="@string/app_name"
android:textAppearance="@style/TextAppearance.Widget.AppCompat.Toolbar.Title"
 ..

In main package a subclass of ViewModel named ValuesViewModel is created. In this class, a MutableLiveData instance is used and collects the input from a fragment or activity and shows the data to other fragments. Final code looks like below for one variable "mName" to be monitorized:


package com.fragmentcommunicationexample.ui.main;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import androidx.lifecycle.ViewModel;
public class ValuesViewModel extends ViewModel {
  /**
   * Live Data Instance
   */
  private MutableLiveData mName = new MutableLiveData<>();
  public void setName(String name) {
    mName.setValue(name);
  }
  public LiveData getName() {
    return mName;
  }
}

Next, in the main activity onCreate() method the ViewModel is initialized:


..
ValuesViewModel mViewModel;
..
// init ViewModel
mViewModel = ViewModelProviders.of(this).get(ValuesViewModel.class);

After initializing ViewModel we’ll set the data like this


mViewModel.setName(value.to.be.set.toString());

Now, whenever the value of mName is changed from the main activity, the ViewModel holds it's value.

To use or display this value stored in the ViewModel into a fragment, we need to initialize the variable in the onCreate method of the fragment and its owner:

def send_message(pipe, pid, counter):
..
pageViewModel = ViewModelProviders.of(requireActivity()).get(ValuesViewModel.class);
..

And to display the new value acquired, we need to use the get method in the onViewCreated of the fragment:


pageViewModel.getName().observe(requireActivity(), new Observer() {
@Override
        public void onChanged(@Nullable String s) {
        	title.setText(s + "º");
        }
});

That's all.

In this article, the communication between Fragments & Activity was shown, using the shared ViewModel.