Kotlin should write the series like this:

SharedPreferences with Kotlin should be written like this

This is how it should be packaged with Kotlin.

More coil,

In this article, I have completed the initial implementation of gilde using extension functions and Kotlin selectable parameters. However, when implementing the callback interface with selectable parameters, the interface implementation class will make the code become very ugly. So how to optimize? Let’s take a look at the final implementation

// URL
imageView.load("https://www.example.com/image.jpg")
// Resource
imageView.load(R.drawable.image)
// callback and progress monitoring
imageView.load("https://www.example.com/image.jpg") {
    placeHolderResId = R.drawable.placeholder
    transformation = arrayOf(GrayscaleTransformation())
    progressListener { isComplete, percentage, bytesRead, totalBytes ->
        // Load progress
    }
    requestListener {
        onSuccess {
        }
        onFail {
        }
    }
}

Copy the code

Optimize the callback for DSL

1. The interface has only one callback function that can be directly abbreviated using lamBA expressions

view.setOnClickListener { view ->
    //TODO
}
// Only one callback argument can be omitted
view.setOnClickListener {
    //TODO
}
Copy the code

2, the interface contains multiple callback functions, will use the object expression to implement

requestListener = object : OnImageListener {
    override fun onSuccess(drawable: Drawable?).{}override fun onFail(msg: String?).{}},Copy the code

So how to make multiple callbacks more Kotlin-style:

requestListener {
    onSuccess {//TODO}
    onFail {//TODO}
}
Copy the code

ImageExt calls dSLify

  • Modify the load callback
class OnImageListener {
    internal var onFailAction: ((String?) -> Unit)? = null
    internal var onSuccessAction: ((Drawable?) -> Unit)? = null

    fun onFail(action: (String?). ->Unit) {
        onFailAction = action
    }

    fun onSuccess(action: (Drawable?). ->Unit) {
        onSuccessAction = action
    }
}

/*** load listener */
var requestListener: OnImageListener? = null
    private set
fun requestListener(listener: OnImageListener. () - >Unit) {
    requestListener = OnImageListener().also(listener)
}
/ / use
requestListener {
    onSuccess {//TODO}
    onFail {//TODO}
}
Copy the code
  • Change progress load, alias using TypeAlias
// The original interface form
interface OnProgressListener {
    fun onProgress(isComplete: Boolean, percentage: Int, bytesRead: Long, totalBytes: Long)
}

Since there is only one method that can be used directly as a shorthand for a callback using lamba expressions, the default prompt is to use the object method. Once again, to optimize
// Alias a function to make it easier to call and write
typealias OnProgressListener = ((isComplete: Boolean, percentage: Int, bytesRead: Long, totalBytes: Long) - >Unit)?

/*** Network progress listener */
var onProgressListener: OnProgressListener = null
    private set
fun progressListener(listener: OnProgressListener) {
    this.onProgressListener = listener
}
/ / use
progressListener { isComplete, percentage, bytesRead, totalBytes ->
    // Load progress
}
Copy the code
  • Provides DSL authoring
/ * * / * * imitation of coil
fun ImageView.load(load: Any? , options: (ImageOptions. () - >Unit)? = null) {
    val imageOptions = ImageOptions().also {
        it.res = load
        it.imageView = this} GlideImageLoader.loadImage(options? .let { imageOptions.also(options) } ? : imageOptions) }// This is just a few lines compared to the extra long code for optional arguments
/ / use
iv.load("https://www.test.png")
// holder
iv.load("https://www.test.png"){
    placeHolderResId = R.color.black
}
// holder
iv.load("https://www.test.png"){
    placeHolderResId = R.color.black
    transformation = arrayOf(GrayscaleTransformation(), CircleWithBorderTransformation(borderWidth = 0, borderColor = 0))
    progressListener { isComplete, percentage, bytesRead, totalBytes ->
        // Load progress
    }
    requestListener {
        onSuccess {}
        onFail {}
    }
}
Copy the code

conclusion

Reference: How to make your callbacks more Kotlin style

Project open source address: github.com/forJrking/I…

Cons: Glide uses annotation configuration due to adding progress callbacks, if you need custom configuration you need to pull project changes and compile them yourself