In the relevant application framework guided by Android, a Resource class is used to represent the status and results of network requests.
// A generic class that contains data and status about loading this data. sealed class Resource<T>( val data: T? = null, val message: String? = null ) { class Success<T>(data: T) : Resource<T>(data) class Loading<T>(data: T? = null) : Resource<T>(data) class Error<T>(message: String, data: T? = null) : Resource<T>(data, message) }
In most cases, we use it in activity
private val testViewModel : TestViewModel by viewModels() private fun getUserInfo(uid: String) { (this, Observer { when () { -> TODO() -> TODO() -> TODO() } }) (uid) }
I feel so annoying to write too much like this. Every time I do it when(). Is there any more fun writing? For example?
private fun getUserInfo(uid: String) { (this, Observer { success { } error { } loading { } }) (uid) }
When I just need to deal with success, I can not write error/loading.
kotlin's type safety builder can do it, let's take a look at the official example
class HTML { fun body() { …… } } fun html(init: HTML.() -> Unit): HTML { val html = HTML() // Create a receiver object () // Pass the recipient object to the lambda return html } html { // The lambda with the receiver starts from this body() // Call a method of the receiver object}
Let’s analyze first, what we need is an object that implements the Observer interface.
So we first define a class to implement the Observer interface
class ResourceObserver<T: Any> : Observer<Resource<T>> { override fun onChanged(t: Resource<T>) { when(t) { is -> TODO() is -> TODO() is -> TODO() } } }
Implement a top-level function and return a ResourceObserver object
fun <T: Any> resourceObserver(init: ResourceObserver<T>.() -> Unit): ResourceObserver<T> { val observer = ResourceObserver<T>() () return observer }
Call this function to get the ResourceObserver object
resourceObserver { //Can call member functions in the object here}
So my implementation is
class ResourceObserver<T: Any> : Observer<Resource<T>> { private var success: (<T>.() -> Unit)? = null private var error: (.() -> Unit)? = null private var loading: (<T>.() -> Unit)? = null fun success(s: (<T>.() -> Unit)) { success = s } fun error(e: .() -> Unit) { error = e } fun loading(l: <T>.() -> Unit) { loading = l } override fun onChanged(t: Resource<T>) { when(t) { is -> success?.invoke(t) is -> error?.invoke(t) is -> loading?.invoke(t) } } }
Summarize
This is the article about the application record of Kotlin type safety builder. For more related content on Kotlin type safety builder, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!