Created
May 19, 2020 20:55
-
-
Save cbeyls/429e9714bdb199e0c9f6748b5f1373af to your computer and use it in GitHub Desktop.
Example of type-safe Fragment result contract extensions
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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