Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Example of type-safe Fragment result contract extensions
import android.os.Bundle
import androidx.core.os.bundleOf
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.FragmentResultListener
import androidx.lifecycle.LifecycleOwner
interface FragmentResultContract<T> {
fun toBundle(result: T): Bundle
fun fromBundle(bundle: Bundle): T
}
/**
* Works with any value you can put in a Bundle: String?, Parcelable, Integer, Boolean, ...
*/
abstract class SingleValueFragmentResultContract<T> : FragmentResultContract<T> {
override fun toBundle(result: T) = bundleOf(RESULT_KEY to result)
@Suppress("UNCHECKED_CAST")
override fun fromBundle(bundle: Bundle): T = bundle.get(RESULT_KEY) as T
companion object {
private const val RESULT_KEY = "result"
}
}
fun <T> FragmentManager.setFragmentResult(contract: FragmentResultContract<T>, result: T) {
setFragmentResult(contract::class.java.name, contract.toBundle(result))
}
inline fun <T> FragmentManager.setFragmentResultListener(contract: FragmentResultContract<T>,
lifecycleOwner: LifecycleOwner,
crossinline resultListener: (T) -> Unit) {
setFragmentResultListener(contract::class.java.name, lifecycleOwner, FragmentResultListener { _, result ->
resultListener(contract.fromBundle(result))
})
}
class ConsumerFragment : Fragment() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
parentFragmentManager.setFragmentResultListener(ProducerFragment.ResultContract, this) { result ->
println(result)
}
}
}
class ProducerFragment : Fragment() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
parentFragmentManager.setFragmentResult(ResultContract, "Hello World")
}
object ResultContract : SingleValueFragmentResultContract<String?>()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment