# 4.4 Sharing Data Between Fragments

To reuse fragments, build each as a completely self-contained component that defines its own layout and behavior. Once you have defined these reusable fragments, you can associate them with an activity and connect them with the application logic to realize the overall composite UI.

To properly react to user events, or to share state information, you often need to have channels of communication between an activity and its fragments or between two or more fragments. To keep fragments self-contained, you *should not* have fragments communicate directly with other fragments or with its host activity.

The `Fragment` library provides two options for communication: a shared [`ViewModel`](https://developer.android.com/topic/libraries/architecture/viewmodel) and the Fragment Result API. The recommended option depends on the use case. To share persistent data with any custom APIs, you should use a `ViewModel`. For a one-time result with data that can be placed in a [`Bundle`](https://developer.android.com/reference/android/os/Bundle), you should use the Fragment Result API. We'll introduce the Fragment Result API here!

## Pass results between fragments <a href="#pass-between-fragments" id="pass-between-fragments"></a>

First, add the dependency to your build.gradle:

```groovy
implementation 'androidx.fragment:fragment-ktx:1.5.0-beta01'
```

To pass data back to fragment A from fragment B, first set a result listener on fragment A, the fragment that receives the result. Call [`setFragmentResultListener()`](https://developer.android.com/reference/androidx/fragment/app/FragmentManager#setfragmentresultlistener) on fragment A's `FragmentManager`, as shown in the following example:

```kotlin
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    // Use the Kotlin extension in the fragment-ktx artifact
    setFragmentResultListener("requestKey") { requestKey, bundle ->
        // We use a String here, but any type that can be put in a Bundle is supported,
        // remember that putExtra from intents uses a Bundle underlying, so anything
        // you putExtra works here too!
        val result = bundle.getString("bundleKey")
        // Do something with the result
    }
}
```

In fragment B, the fragment producing the result, you must set the result on the same `FragmentManager` by using the same `requestKey`. You can do so by using the [`setFragmentResult()`](https://developer.android.com/reference/androidx/fragment/app/FragmentManager#setfragmentresult) API:

```kotlin
button.setOnClickListener {
    val result = "result"
    // Can also opt for an empty bundle e.g. bundleOf() with no arguments
    setFragmentResult("requestKey", 
        bundleOf("bundleKey" to result, "otherKeys" to otherResults, ...))
}
```

Fragment A then receives the result and executes the listener callback!

{% hint style="warning" %}
You can have only a single listener and result for a given key. If you call `setFragmentResult()` more than once for the same key the system replaces any pending results with your updated result. If you set a result without a corresponding listener to receive it, the result is stored in the `FragmentManager` until you set a listener with the same key.&#x20;
{% endhint %}

### Receiving results in Host Activity

To receive a fragment result in the host activity, set a result listener on the fragment manager using [`getSupportFragmentManager()`](https://developer.android.com/reference/androidx/fragment/app/FragmentActivity#getSupportFragmentManager\(\)). Very similar to the logic we added to our Fragment A.

```kotlin
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        supportFragmentManager
                .setFragmentResultListener("requestKey", this) { requestKey, bundle ->
            val result = bundle.getString("bundleKey")
            // Do something with the result
        }
    }
}
```

## Alternatives

Another option as stated previously are ViewModels (which require a little more overhead to setup) you can also opt for using Singletons, which are covered in [9.1.](https://android-course.cornellappdev.com/chapters/7.-persistent-storage/6.1-singletons)
