Android1/17/2020

How to Send Data Between Two Fragments in Android

Fragments are reusable UI components commonly used in modern Android applications.

Many Android applications require communication between fragments for:

  • Form updates
  • Search filters
  • Chat interfaces
  • Dashboard synchronization
  • Master-detail layouts

Since fragments should remain modular and reusable, direct fragment-to-fragment communication is not recommended.

Instead, communication usually happens through:

  • Activity interfaces
  • Shared ViewModel
  • Fragment Result API

In this tutorial, we will learn how to send data between two fragments using interfaces and the hosting Activity.


What We Will Build

In this Android example:

  • Fragment A sends text to Fragment B
  • Fragment B sends text to Fragment A
  • Activity acts as communication bridge
  • Fragments remain reusable and modular

How Fragment Communication Works

The workflow is:

  1. User enters text in Fragment A
  2. Fragment A sends data to Activity using interface
  3. Activity forwards data to Fragment B
  4. Fragment B updates UI

The same process works in reverse direction.


Step 1 — Create activity_main.xml

Create the main Activity layout:


<?xml version="1.0" encoding="utf-8"?>

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <FrameLayout
        android:id="@+id/containerA"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

    <FrameLayout
        android:id="@+id/containerB"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

</LinearLayout>

Step 2 — Create MainActivity.java


package com.example.fragmentcommunication;

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;

public class MainActivity
        extends AppCompatActivity
        implements FragmentA.FragmentAListener,
                   FragmentB.FragmentBListener {

    private FragmentA fragmentA;

    private FragmentB fragmentB;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        fragmentA = new FragmentA();

        fragmentB = new FragmentB();

        getSupportFragmentManager()
                .beginTransaction()
                .replace(
                        R.id.containerA,
                        fragmentA
                )
                .replace(
                        R.id.containerB,
                        fragmentB
                )
                .commit();
    }

    @Override
    public void onInputASent(CharSequence input) {

        fragmentB.updateEditText(input);
    }

    @Override
    public void onInputBSent(CharSequence input) {

        fragmentA.updateEditText(input);
    }
}

Step 3 — Create FragmentA.java


package com.example.fragmentcommunication;

import android.content.Context;
import android.os.Bundle;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;

public class FragmentA extends Fragment {

    private FragmentAListener listener;

    private EditText editText;

    public interface FragmentAListener {

        void onInputASent(CharSequence input);
    }

    @Nullable
    @Override
    public View onCreateView(
            @NonNull LayoutInflater inflater,
            @Nullable ViewGroup container,
            @Nullable Bundle savedInstanceState
    ) {

        View view = inflater.inflate(
                R.layout.fragment_a,
                container,
                false
        );

        editText =
                view.findViewById(R.id.editText);

        Button button =
                view.findViewById(R.id.buttonOk);

        button.setOnClickListener(
                new View.OnClickListener() {

                    @Override
                    public void onClick(View v) {

                        listener.onInputASent(
                                editText.getText()
                        );
                    }
                });

        return view;
    }

    public void updateEditText(
            CharSequence newText
    ) {

        editText.setText(newText);
    }

    @Override
    public void onAttach(
            @NonNull Context context
    ) {

        super.onAttach(context);

        if (context instanceof FragmentAListener) {

            listener =
                    (FragmentAListener) context;

        } else {

            throw new RuntimeException(
                    context.toString()
                            + " must implement FragmentAListener"
            );
        }
    }
}

Step 4 — Create FragmentB.java


package com.example.fragmentcommunication;

import android.content.Context;
import android.os.Bundle;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;

public class FragmentB extends Fragment {

    private FragmentBListener listener;

    private EditText editText;

    public interface FragmentBListener {

        void onInputBSent(CharSequence input);
    }

    @Nullable
    @Override
    public View onCreateView(
            @NonNull LayoutInflater inflater,
            @Nullable ViewGroup container,
            @Nullable Bundle savedInstanceState
    ) {

        View view = inflater.inflate(
                R.layout.fragment_b,
                container,
                false
        );

        editText =
                view.findViewById(R.id.editText);

        Button button =
                view.findViewById(R.id.buttonOk);

        button.setOnClickListener(
                new View.OnClickListener() {

                    @Override
                    public void onClick(View v) {

                        listener.onInputBSent(
                                editText.getText()
                        );
                    }
                });

        return view;
    }

    public void updateEditText(
            CharSequence newText
    ) {

        editText.setText(newText);
    }

    @Override
    public void onAttach(
            @NonNull Context context
    ) {

        super.onAttach(context);

        if (context instanceof FragmentBListener) {

            listener =
                    (FragmentBListener) context;

        } else {

            throw new RuntimeException(
                    context.toString()
                            + " must implement FragmentBListener"
            );
        }
    }
}

Step 5 — Create fragment_a.xml


<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:padding="16dp"
    android:background="#A5D6A7">

    <EditText
        android:id="@+id/editText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

    <Button
        android:id="@+id/buttonOk"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Send"/>

</LinearLayout>

Step 6 — Create fragment_b.xml


<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:padding="16dp"
    android:background="#90CAF9">

    <EditText
        android:id="@+id/editText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

    <Button
        android:id="@+id/buttonOk"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Send"/>

</LinearLayout>

Why Interfaces Are Used

Interfaces help:

  • Reduce tight coupling
  • Improve modularity
  • Make fragments reusable
  • Separate responsibilities cleanly

Common Mistakes Developers Make

1. Direct Fragment References

Direct fragment communication creates tightly coupled code.


2. Forgetting Interface Implementation

Activity must implement fragment listener interfaces.


3. Updating Views Before Initialization

Always ensure fragment views are initialized before updating UI.


Modern Android Alternatives

Modern Android development usually prefers:

  • Shared ViewModel
  • LiveData
  • StateFlow
  • Fragment Result API
  • Jetpack Compose state management

Shared ViewModel vs Interface Communication

Interface Communication Shared ViewModel
Good for simple communication Better for scalable apps
Activity acts as bridge Lifecycle-aware state sharing
More manual implementation Cleaner architecture

FAQ

Can fragments communicate directly?

Technically yes, but it is not recommended because it increases coupling.

What is the modern recommended approach?

Shared ViewModel with LiveData or StateFlow is the modern recommended solution.

Why use fragments instead of multiple activities?

Fragments provide better UI flexibility and reusable modular components.


Conclusion

Fragment communication is an important part of Android application architecture.

Using interfaces allows fragments to remain modular while communicating safely through the hosting Activity.

Modern Android applications should combine fragment communication with lifecycle-aware architecture patterns such as Shared ViewModel and StateFlow.


About the Author

Salil Jha is a Full Stack and Mobile Developer specializing in Android, React Native, fintech systems, scalable SaaS platforms, and developer tooling products.

CodeChain Dev — Build Modern Products. Solve Real Problems.

Deep Structural Diagnostics.

Mastering JSON is only the first step. Use our industrial-grade workbench to format, validate, and synthesize models for your production APIs.