Skip to content

Instantly share code, notes, and snippets.

@halilozercan
Last active October 6, 2020 22:44
Show Gist options
  • Save halilozercan/c9f97ad817bd4de168e5f597a6fcfe00 to your computer and use it in GitHub Desktop.
Save halilozercan/c9f97ad817bd4de168e5f597a6fcfe00 to your computer and use it in GitHub Desktop.
/**
* This interface marks the class for use of `Rizalt` library.
*/
interface Rizalt<P: Parcelable>
/**
* Creates a unique request key for given Fragment class. Key can be left empty
* to create a default instance.
*/
fun <T, P: Parcelable> KClass<T>.getRequestKeyNameFor(key: String): String where T: Fragment, T: Rizalt<P> {
return "${this.simpleName}_${key}_REQUEST_KEY"
}
/**
* Adds the request key in arguments for given Fragment. When this fragment calls
* [setFragmentRizalt], it will simply use the given request key.
*/
inline fun <reified T, P: Parcelable> T.addRizaltKey(key: String): T where T: Fragment, T: Rizalt<P> {
arguments?.putString(RIZALT_REQUEST_KEY, T::class.getRequestKeyNameFor(key))
return this
}
/**
* Creates a unique result key for the given Fragment class.
* `Rizalt` API assumes that each Fragment has single result which is [Parcelable].
* This result is put in a Bundle with the generated key from this method and easily
* read by `rizalt listener`s.
*/
inline fun <T, reified P: Parcelable> KClass<T>.getResultKeyNameFor(): String where T: Fragment, T: Rizalt<P> {
return "${this.simpleName}_${P::class.simpleName}_RESULT_KEY"
}
/**
* Set the result for this Fragment. Request Key is either read from arguments or
* assumed to be default, and result key is created by the default [getResultKeyNameFor] method.
*
* returns; if setting result operation was successful.
*/
inline fun <reified T, reified P: Parcelable> T.setFragmentRizalt(result: P) where T: Fragment, T: Rizalt<P> {
val key = arguments?.getString(RIZALT_REQUEST_KEY) ?: T::class.getRequestKeyNameFor("")
setFragmentResult(key, Bundle().apply {
putParcelable(T::class.getResultKeyNameFor(), result)
})
}
/**
* Register a rizalt listener in a fragment. This listens to child fragment manager.
*
* @param clazz: Fragment class that should be listened to for results.
* @param key: Optional key to differentiate between multiple results from the same Fragment type.
* @param callback: A listener to call when result is received.
*/
inline fun <HostFragment: Fragment, reified T, reified P: Parcelable> HostFragment.setFragmentRizaltListener(
clazz: KClass<T>,
key: String = "",
crossinline callback: (P) -> Unit
) where T: Fragment, T: Rizalt<P> {
childFragmentManager.setFragmentResultListener(
clazz.getRequestKeyNameFor(key),
this
) { _, bundle ->
bundle
.getParcelable<P>(clazz.getResultKeyNameFor())
?.let {
callback(it)
}
}
}
/**
* Register a rizalt listener in an Activity. This listens to support fragment manager.
*
* @param clazz: Fragment class that should be listened to for results.
* @param key: Optional key to differentiate between multiple results from the same Fragment type.
* @param callback: A listener to call when result is received.
*/
inline fun <A: AppCompatActivity, T, reified P: Parcelable> A.setFragmentRizaltListener(
clazz: KClass<T>,
key: String = "",
crossinline callback: (P) -> Unit
) where T: Fragment, T: Rizalt<P> {
supportFragmentManager.setFragmentResultListener(
clazz.getRequestKeyNameFor(key),
this
) { _, bundle ->
bundle
.getParcelable<P>(clazz.getResultKeyNameFor())
?.let {
callback(it)
}
}
}
const val RIZALT_REQUEST_KEY = "RIZALT_REQUEST_KEY"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment