This is how Glide Kotlin should wrap the summary
Glide is an image loading library officially recommended by Google, Coil is the Kotlin-first Android image loading library, integrating Kotlin features, the most mainstream Android technology and trends. In this post, we are going to share how to use The Coil package with Kotlin.
Integration and API preview
-
allprojects { repositories { maven { url 'https://www.jitpack.io'}}}Copy the code
-
dependencies { implementation 'com. Making. ForJrking: ImageExt: hundreds' } Copy the code
-
// 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
-
Other extension functions and effects
iv_4.loadCircleImage(url1) iv_5.loadBorderImage(url1, borderWidth = 10, borderColor = Color.RED) iv_6.loadGrayImage(url1) iv_7.loadRoundCornerImage(url1, radius = 40, type = ImageOptions.CornerType.ALL) iv_8.loadBlurImage(url4) iv_9.loadResizeImage(url3, width = 400, height = 800) Copy the code
Encapsulate implementation
Firstly, the call method of the coil is in the form of the Kotlin extension function, adding a load(URL) function to the ImageView. Then, other placeholder configurations are set in DSL mode. How to learn and use DSL is discussed separately below.
The first step is to encapsulate the following function:
/** coil / /
fun ImageView.load(load: Any? , options: (ImageOptions. () - >Unit)? = null) {
ImageLoader.loadImage(ImageOptions(load).also(options))
}
Copy the code
Step 2 Encapsulates the configuration class:
/** * image load library configuration, encapsulate the original load configuration properties, conversion */
class ImageOptions {
/*** Load the original resource */
var res: Any? = null
/*** displays the container */
var imageView: ImageView? = null
/*** imageView exists context or fragment activity*/
var context: Any? = null
get() {
returnfield ? : imageView }/*** load placeholder resource ID. Placeholder 0 means no placeholder */
@DrawableRes
var placeHolderResId = 0. Omit animations, error diagrams, and other attributesvar centerCrop: Boolean = false
/*** Network progress listener */
var onProgressListener: OnProgressListener? = null
/*** load listener */
var requestListener: OnImageListener? = null. Omit enumerations like cache policy and priority}Copy the code
The third step strategy implementation, because to use OKHTTP interceptor to do progress monitoring, through annotations configuration glide’s network download.
/**Glide package */
object ImageLoader {
fun loadImage(options: ImageOptions) {
Preconditions.checkNotNull(options, "ImageConfigImpl is required")
val context = options.context
Preconditions.checkNotNull(context, "Context is required")
Preconditions.checkNotNull(options.imageView, "ImageView is required")
val requestsWith = glideRequests(context)
// By type
val glideRequest = when (options.res) {
is String -> requestsWith.load(options.res as String)
is Bitmap -> requestsWith.load(options.res as Bitmap)
is Drawable -> requestsWith.load(options.res as Drawable)
is Uri -> requestsWith.load(options.res as Uri)
is URL -> requestsWith.load(options.res as URL)
is File -> requestsWith.load(options.res as File)
is Int -> requestsWith.load(options.res as Int)
is ByteArray -> requestsWith.load(options.res as ByteArray)
else -> requestsWith.load(options.res)
}
glideRequest.apply {
// Error map.// Cache configuration, priority, thumbnail request.// Animation, Transformationinto(GlideImageViewTarget(options.imageView, options.res)) } options.onProgressListener? .let { ProgressManager.addListener(options.res.toString(), options.onProgressListener) } }private fun glideRequests(context: Any?).: GlideRequests {
return when (context) {
is Context -> IGlideModule.with(context)
is Activity -> IGlideModule.with(context)
is FragmentActivity -> IGlideModule.with(context)
is Fragment -> IGlideModule.with(context)
is android.app.Fragment -> IGlideModule.with(context)
is View -> IGlideModule.with(context)
else -> throw NullPointerException("not support")}}}Copy the code
Kotlin DSL
Writing a DSL can be easily understood and memorized with the following code (main reference: How to make your callbacks Kotlin)
class DSLTest{
// Common variables
var str:String? =null
// Function variable
var onSuccess: ((String?) -> Unit)? = null
// Call a function variable
fun onSuccessDo(a){... onSuccess.invoke("success $str")}}// Define the function to call
load(dslPar:(DSLTest.() -> Unit)? = null){
DSLTest().also(dslPar)
}
/ / use
load{
str = "ACC"
onSuccess{
//TODO}}Copy the code
Compared with traditional policy mode encapsulation
- Define the policy pattern base interface
/** image loading policy interface */
public interface BaseImageLoaderStrategy {
void loadImage(load Any,ImageOptions options);
}
Copy the code
- Implementation policy Interface
/*** Specific load strategy, Glide load framework */
public class GlideImageLoader implements BaseImageLoaderStrategy {
@Override
public void loadImage(Context context, ImageOptions options) {
Glide.with(context).apply(...).into(options.getImgView());
}
}
Copy the code
- Policy scheduler call
ImageLoader.loadImage(ImageOptions(imageView).apply{
.....
})
Copy the code
Policy mode usually encapsulates many interfaces to meet everyday needs. Due to Kotlin, we can encapsulate a method with very long arguments and call it with optional arguments, but Java can’t do anything except assign null to the optional arguments.
// Optional parameter Example
load(url:String,isCirle:Boolean = false, width:Int=0, height:Int = 0) {... }// Use the parameter name = value to use optional arguments
iv_8.load(url2, height = 800)
Copy the code
Comparison between policy encapsulation and extension function +DSL:
- Unified interface encapsulation, all with extensibility
- You can use the Kotlin feature without having to define a lot of interfaces
- Extension functions are more convenient and concise
- The way the DSL is written makes the code more understandable and kotlin-style
- A multimethod interface callback that allows you to select only individual methods
conclusion
- Finally, package and distribute the JitPack repository, project open source addresses and documentation for easy use in your project
ForJrking /ImageExt: Extension function set for loading image resources based on Glide packaging ImageView (github.com)
-
Because of the okHTTP-based download schedule management, glide @glidemodule configuration method is used. This may conflict with your project custom configuration, so we can only pull the code to modify, and rely on Module mode. Contact me if there is a better way to improve.
-
There are only a few common Android image loading libraries, and other libraries can be implemented by reference. Kotlin smells good!!