Kotlin之Glide的自定义BitmapTransformation

引言


上一篇中利用RecyclerView已经实现了将控件复用以达到减少性能和内存消耗的目的,这一篇中将进一步优化界面的显示。

我项目中采用的图片加载框架是Glide,优点什么的网上很多人都在讨论,这里说一下我为什么选用Glide而不是Picasso、Fresco等。

1、图片的加载请求和与之相关Context的生命周期是相关联的,
这一点对于此项目是有很大优势的,可以减少不必要的性能消耗。由于项目的界面主结构是由fragment组成的,且各fragment都要加载大量的图片,当fragment切换时生命周期变化会触发Glide自动的将请求进行暂停和恢复操作,从而节约流量和内存,并且防止内存泄露。

2、图片加载后的展示效果,相信很多知道Glide的人都有见过Glide加载图片时渐显的酷炫动画效果,这一点主要体现在用户的感官上。

主要原因是以上两点,由于Glide默认设置已经有了内存缓存和磁盘缓存策略,如果不是硬性需要可使用默认。

说了这么多本文主要讲的要来了“图片处理”,如何自定义BitmapTransformation

正文


先看看对比图

别人家的界面

我的界面

是不是给人一种生硬的感觉,图片都是有棱有角的不是很顺滑,还好官方给出了处理办法BitmapTransformation

BitmapTransformation是一个抽象类,需要实现的方法如下

//toTransform为源
protected abstract Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight);
/**
 * Created by mr.lin on 2018/1/14.
 * 圆角图片转换
 */
class GlideRoundTransform(context: Context, private var radius: Int) : BitmapTransformation(context) {

    override fun transform(pool: BitmapPool, toTransform: Bitmap, outWidth: Int, outHeight: Int): Bitmap? {

        return roundCrop(pool, toTransform)

    }

    private fun roundCrop(pool: BitmapPool, source: Bitmap): Bitmap {
        var result = pool.get(source.width, source.height, Bitmap.Config.ARGB_8888)
        if (result == null) {
            result = Bitmap.createBitmap(source.width, source.height, Bitmap.Config.ARGB_8888)
        }
        //这时result只是一张指定了大小的空图,如果要求不高的话可以更改ARGB_8888以减少内存消耗
        val canvas = Canvas(result)
        val paint = Paint()
        paint.shader = BitmapShader(source, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP)
        paint.isAntiAlias = true
        val rectF = RectF(0f, 0f, source.width.toFloat(), source.height.toFloat())
        canvas.drawRoundRect(rectF, radius.toFloat(), radius.toFloat(), paint)
        //操作其实很简单就是画了一个圆角矩形
        return result
    }
    //用于标示BitmapTransformation,接口Transformation<T> 有解释用以标示唯一对象的key
    override fun getId(): String {
        return this.javaClass.name
    }

}

过程并不是一帆风顺的

这是过程图

这是最终图

同一张图片发现问题了吗?过程图中的图片被裁剪了。。。。。

由于我在布局的时候对ImageView的宽高进行了指明,导致加载大图的时候会以左上角坐标进行裁剪,当改变ImageView宽高为wrap_content时才显示正常。

/**
 * Created by mr.lin on 2018/1/15.
 * 圆形图片转换
 */
class GlideCircleTransform(context: Context?) : BitmapTransformation(context) {

    override fun transform(pool: BitmapPool, toTransform: Bitmap, outWidth: Int, outHeight: Int): Bitmap {
        return circleCrop(pool, toTransform)
    }

    private fun circleCrop(pool: BitmapPool, source: Bitmap): Bitmap {

        val size = Math.min(source.width, source.height)
        val x = (source.width - size) / 2
        val y = (source.height - size) / 2

        val squared = Bitmap.createBitmap(source, x, y, size, size)

        var result = pool.get(size, size, Bitmap.Config.ARGB_8888)
        if (result == null) {
            result = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888)
        }

        val canvas = Canvas(result)
        val paint = Paint()
        paint.shader = BitmapShader(squared, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP)
        paint.isAntiAlias = true
        val r = size / 2f
        canvas.drawCircle(r, r, r, paint)
        return result
    }

    override fun getId(): String {
        return this.javaClass.name
    }
}

当然所有的图片加载都要封装到一起,以免以后更换图片加载框架

/**
 * Created by mr.lin on 2018/1/14.
 * glide工具
 */
class GlideUtils {

    companion object {

        fun loadImage(context: Context, url: String, iv: ImageView) {
            Glide.with(context)
                    .load(url)
                    .into(iv)
        }

        fun loadRoundImage(context: Context, url: String, iv: ImageView, radius: Int) {
            Glide.with(context)
                    .load(url)
                    .transform(GlideRoundTransform(context, CommonUtils.dpTopx(radius.toFloat())))
                    .into(iv)
        }

        fun loadCircleImage(context: Context, url: String, iv: ImageView) {
            Glide.with(context)
                    .load(url)
                    .transform(GlideCircleTransform(context))
                    .into(iv)
        }

    }

}

猜你喜欢

转载自blog.csdn.net/s1991721/article/details/79070013