Fragment to Fragment Communication in Android using Shared ViewModel

您所在的位置:网站首页 viewmodelprovidersof Fragment to Fragment Communication in Android using Shared ViewModel

Fragment to Fragment Communication in Android using Shared ViewModel

2023-04-04 14:31| 来源: 网络整理| 查看: 265

If there are two or more fragments in an activity, they need to communicate and share the data between them. The traditional way of sharing the data between the two fragments is implementing the callback using an interface that is cumbersome and may throw exceptions. But the modern way of doing that is using shared ViewModel. So in this article, it’s been demonstrated how the shared ViewModel can be used to communicate between the fragments. Have a look at the following image to get an overview of the discussion.

Fragment to Fragment Communication in Android using Shared ViewModel

Note: This discussion is implemented in Kotlin programming language.

Prerequisites

Fragment Lifecycle in AndroidViewModel in Android Architecture ComponentsSteps to implement the communication between fragments

Step 1: Create an empty activity project

Create an empty activity Android Studio project, and select Kotlin as the programming language. Refer to Android | How to Create/Start a New Project in Android Studio?.

Step 2: Adding required dependencies

The dependencies include the ViewModel and the LiveData. So, in the app level Gradle file add the following dependencies and sync the project.

// lifecycle_version and architecture versions may varydef lifecycle_version = “2.3.1”

def arch_version = “2.1.0”

// ViewModel

implementation “androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycle_version”

// LiveData

implementation “androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version”

// Lifecycles only (without ViewModel or LiveData)

implementation “androidx.lifecycle:lifecycle-runtime-ktx:$lifecycle_version”

// architecture Lifecycle extensions

implementation “androidx.lifecycle:lifecycle-extensions:$arch_version”

Step 3: Working with activity_main.xml file

The main layout of the application contains the two FrameLayouts which hold the two fragments. To implement the same invoke the following code inside the activity_main.xml file.

XML

                                

Step 4: Implementing Shared ViewModel

In the SharedViewModel.kt file there are there is one MutableLiveData of CharSequence for setting the data for EditTexts. Two functions setData and getData for updating that mutable live data as soon as the data inside the EditTexts changes.

Fragment to Fragment Communication in Android using Shared ViewModel

To implement the same invoke the following code.

Kotlin

import androidx.lifecycle.MutableLiveDataimport androidx.lifecycle.ViewModel  class SharedViewModel : ViewModel() {      // Mutable LiveData which observed by LiveData       // and updated to EditTexts when it is changed.    private val mutableLiveData: MutableLiveData = MutableLiveData()      // function to set the changed      // data from the EditTexts    fun setData(input: CharSequence) {        mutableLiveData.value = input    }      // function to get the changed data from the EditTexts    fun getData(): MutableLiveData = mutableLiveData}

Step 5: Creating 2 Fragments

Create two Fragments with their own layouts naming Fragment1.kt and Fragment2.kt.For each of the fragment’s layouts, it contains one EditText to get the data to send for fragment 2 and one button, when clicked it shares the data to another fragment.To implement the layout for Fragment 1, invoke the following code inside the fragment_1.xml fileXML

                              

To implement the layout for Fragment 2, invoke the following code inside the fragment_2.xml file.

XML

                              

Step 6: Creating instances of shared view model inside the Fragment.kt files

There is a need to create the instance of the ViewModel of the type ShareViewModel when the Activity is created.So one needs to override the onActivityCreated() method inside each of the Fragments.This is so because when we see the lifecycle of the fragments the views are created and updated after the onCreateView() is called and onAcrivityCreated() callback is called after the onCreateView() is executed. So the LiveData can keep track of UI elements for which elements they have updated. Have a look at the following chart for the activity lifecycle of the fragment.

Fragment to Fragment Communication in Android using Shared ViewModel

To implement the same in both fragments invoke the, following code inside Fragment1.kt.

Kotlin

import android.os.Bundleimport android.text.Editableimport androidx.fragment.app.Fragmentimport android.view.LayoutInflaterimport android.view.Viewimport android.view.ViewGroupimport android.widget.Buttonimport android.widget.EditTextimport androidx.lifecycle.Observerimport androidx.lifecycle.ViewModelProviders  class Fragment1 : Fragment() {      private var sharedViewModelInstance: SharedViewModel? = null      private var editTextFromFragment1: EditText? = null      override fun onCreateView(            inflater: LayoutInflater, container: ViewGroup?,            savedInstanceState: Bundle?    ): View? {        val view: View = inflater.inflate(R.layout.fragment_1, container, false)          val sendDataButton: Button = view.findViewById(R.id.send_button_fragment_1)        editTextFromFragment1 = view.findViewById(R.id.edit_text_from_fragment_1)          // as soon as the button is clicked           // send the data to ViewModel        // and the Live data will take care of          // updating the data inside another Fragment        sendDataButton.setOnClickListener {            sharedViewModelInstance?.setData(editTextFromFragment1!!.text)        }          return view    }      override fun onActivityCreated(savedInstanceState: Bundle?) {        super.onActivityCreated(savedInstanceState)          // create instances of the shared view model           // when the activity is created        sharedViewModelInstance = ViewModelProviders.of(activity!!).get(SharedViewModel::class.java)          // observe the data inside the view model that           // is mutable live of type CharSequence and           // set the data for edit text        sharedViewModelInstance!!.getData().observe(viewLifecycleOwner, Observer {            editTextFromFragment1!!.text = it as Editable?        })    }}

And same goes with the Fragment2.kt file, invoke the following code.

Kotlin

import android.os.Bundleimport android.text.Editableimport androidx.fragment.app.Fragmentimport android.view.LayoutInflaterimport android.view.Viewimport android.view.ViewGroupimport android.widget.Buttonimport android.widget.EditTextimport androidx.lifecycle.Observerimport androidx.lifecycle.ViewModelProviders  class Fragment2 : Fragment() {      private var sharedViewModelInstance: SharedViewModel? = null      private var editTextFromFragment2: EditText? = null      override fun onCreateView(            inflater: LayoutInflater, container: ViewGroup?,            savedInstanceState: Bundle?    ): View? {        val view: View = inflater.inflate(R.layout.fragment_2, container, false)          val sendDataButton: Button = view.findViewById(R.id.send_button_fragment_2)        editTextFromFragment2 = view.findViewById(R.id.edit_text_from_fragment_2)          // as soon as the button is clicked           // send the data to ViewModel        // and the Live data will take care of           // updating the data inside another Fragment        sendDataButton.setOnClickListener {            sharedViewModelInstance?.setData(editTextFromFragment2!!.text)        }          return view    }      override fun onActivityCreated(savedInstanceState: Bundle?) {        super.onActivityCreated(savedInstanceState)          // create instances of the shared view model          // when the activity is created        sharedViewModelInstance = ViewModelProviders.of(activity!!).get(SharedViewModel::class.java)          // observe the data inside the view model that is mutable           // live of type CharSequence and set the data for edit text        sharedViewModelInstance!!.getData().observe(viewLifecycleOwner, Observer {            editTextFromFragment2!!.text = it as Editable?        })    }}

Step 7: Populate the fragment holders using MainActivity.kt file

Inside the MainActivity.kt file, one needs to populate the fragment holders from the activity_main.xml, with both fragments. To implement the same invoke the following code inside the MainActivity.kt file.

Kotlin

import android.os.Bundleimport androidx.appcompat.app.AppCompatActivityimport androidx.fragment.app.FragmentTransaction  class MainActivity : AppCompatActivity() {    override fun onCreate(savedInstanceState: Bundle?) {        super.onCreate(savedInstanceState)        setContentView(R.layout.activity_main)          val fragmentTransaction: FragmentTransaction = supportFragmentManager.beginTransaction()        fragmentTransaction.apply {            add(R.id.fragment_1_holder, Fragment1())            add(R.id.fragment_2_holder, Fragment2())            commit()        }    }}

Output:

https://media.geeksforgeeks.org/wp-content/uploads/20210521185034/Untitled.mp4My Personal Notes arrow_drop_up


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3