Communicating between Fragments in Android Development


In Android development, fragments are often used to divide the UI into smaller, more manageable pieces. Sometimes, there is a need for fragments to communicate with each other. Since fragments are often isolated in their own lifecycle, they cannot directly access or modify the UI of another fragment. However, Android provides several ways to allow fragments to interact with each other, such as using ViewModel, Bundle, or Activity as a medium for communication.

1. Why Communicate Between Fragments?

In many cases, you may have fragments that need to exchange data. For example, when you select an item in a list displayed in one fragment, you might want to show more detailed information in another fragment. This is where fragment communication becomes essential.

2. Communication Through Activity

One of the simplest ways to communicate between fragments is by using the host Activity as an intermediary. The activity can hold references to both fragments and pass data between them.

Example 1: Using Activity as a Communication Channel

In this example, we will pass data from FirstFragment to SecondFragment through the hosting activity.

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

            if (savedInstanceState == null) {
                val fragment = FirstFragment()
                supportFragmentManager.beginTransaction()
                    .replace(R.id.fragment_container, fragment)
                    .commit()
            }
        }

        // This method is called when data is passed from FirstFragment
        override fun onDataPass(data: String) {
            val secondFragment = SecondFragment()

            // Pass the data to SecondFragment
            val bundle = Bundle()
            bundle.putString("data_key", data)
            secondFragment.arguments = bundle

            // Replace with SecondFragment
            supportFragmentManager.beginTransaction()
                .replace(R.id.fragment_container, secondFragment)
                .commit()
        }
    }
        

In this code:

  • The MainActivity implements the FirstFragment.OnDataPass interface to receive data from FirstFragment.
  • When the data is passed, it is sent to SecondFragment using a Bundle.
  • Then, SecondFragment receives the data and displays it.

FirstFragment Example

    class FirstFragment : Fragment() {

        interface OnDataPass {
            fun onDataPass(data: String)
        }

        private var dataPasser: OnDataPass? = null

        override fun onAttach(context: Context) {
            super.onAttach(context)
            dataPasser = context as OnDataPass
        }

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

            val button = view.findViewById

In this code:

  • FirstFragment defines an interface OnDataPass that the activity must implement.
  • The fragment calls dataPasser?.onDataPass() to send data to the activity.

SecondFragment Example

    class SecondFragment : Fragment() {

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

            val data = arguments?.getString("data_key")
            val textView = view.findViewById(R.id.textView)
            textView.text = data

            return view
        }
    }
        

In this code:

  • SecondFragment receives the data passed through the Bundle and displays it in a TextView.

3. Using ViewModel for Communication

Another way to communicate between fragments is by using a ViewModel. ViewModels allow you to store and manage UI-related data in a lifecycle-conscious way, which can be shared across multiple fragments within the same activity.

Example 2: Using ViewModel for Communication

In this example, we will use a SharedViewModel to pass data between two fragments.

    class SharedViewModel : ViewModel() {
        val selectedData = MutableLiveData()
    }

    class FirstFragment : Fragment() {

        private lateinit var sharedViewModel: SharedViewModel

        override fun onCreateView(
            inflater: LayoutInflater, container: ViewGroup?,
            savedInstanceState: Bundle?
        ): View? {
            val view = inflater.inflate(R.layout.fragment_first, container, false)
            sharedViewModel = ViewModelProvider(requireActivity()).get(SharedViewModel::class.java)

            val button = view.findViewById

In this code:

  • The SharedViewModel is shared between the two fragments using ViewModelProvider(requireActivity()).
  • FirstFragment updates the selectedData LiveData in the ViewModel.
  • SecondFragment observes the LiveData and updates the UI when the data changes.

4. Conclusion

Communicating between fragments is a common scenario in Android development. While it can be done using the activity as a communication medium, using a ViewModel to share data across fragments is a more robust and lifecycle-aware approach. Choose the method that best fits the complexity of your app and the number of fragments involved.





Advertisement