前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >开源框架之[-Picasso-]应用篇

开源框架之[-Picasso-]应用篇

作者头像
张风捷特烈
发布2019-03-04 10:46:50
6080
发布2019-03-04 10:46:50
举报

零、前言

Picasso是一个图片加载的框架,内部依赖了OkHttp,OkHttp内部依赖了okio 依赖:implementation 'com.squareup.picasso:picasso:2.71828' 本篇讲一下Picasso的用法,下一篇分析一下Picasso的源码

picasso.png


一、Picasso的缓存相关
代码语言:javascript
复制
 Picasso.get().setIndicatorsEnabled(true);
 |--标记处图片加载的位置
    |--红色,网络加载
    |--绿色,内存加载
    |--蓝色,磁盘加载 

1.点击时进行网络加载

可见是红色,网络加载

代码语言:javascript
复制
String url = "http://192.168.43.60:8080/imgs/HXqqASHJETSlV**c.jpg";
imageView.setOnClickListener(v -> {
    Picasso.get().load(url)
            .into(imageView);
});

网络加载.png


2.再次点击加载网络图片

可见是绿色,内存加载。这时并未去请求网络加载图片,直接用内存中的缓存图片

内存加载.png


3.退出再进来加载网络图片

可见是蓝色,即从磁盘读取的本地文件

磁盘加载.png

从缓存来看标准的DiskLruCache

代码语言:javascript
复制
|---文件名:键的md5值
|---XXXXX.0 文件:请求信息
|---XXXXX.1 文件:响应数据(这里即是图片)
|---journal 文件:使用日志
|---文件大小: 从服务器端的资源来看,并未压缩

缓存.png

服务器端.png


5.小结一下:

内存缓存-->本地磁盘缓存-->网络缓存(即资源)

三级缓存.png


二、缓存策略
1.做个试验

貌似完美无缺,但是...图片的更新是个问题 现在将服务端的图片更新一下:发现现在客户端是无法更新的 也就是缓存会妨碍获取更新后的图片,必须清除缓存才能更新,所以凡事有利必有弊

更新图片.png

客户端更新图片.png


2.网络策略:NetworkPolicy与内存策略MemoryPolicy

比如下拉刷新的时候可以直接越过内存和磁盘,请求网络 因为User的动作的目的性明确,普通情况可以使用缓存,你也可以视情况自己定制

定制缓存策略.png

代码语言:javascript
复制
public enum NetworkPolicy {
NO_CACHE(1 << 0),//跳过检查磁盘缓存,强制通过网络加载
NO_STORE(1 << 1),//不将结果存储到磁盘缓存
OFFLINE(1 << 2);//强制使用磁盘缓存,跳过网络

public enum MemoryPolicy {
NO_CACHE(1 << 0),//处理请求时跳过内存缓存查找
NO_STORE(1 << 1);//不将最终结果存储到内存缓存中。
  用于一次性请求,以避免从缓存中删除其他图片缓存。

单击三级缓存,长按请求网络

代码语言:javascript
复制
String url = "http://192.168.43.60:8080/imgs/HXqqASHJETSlV**c.jpg";
imageView.setOnClickListener(v -> {
    Picasso.get()
            .load(url)
            .into(imageView);
});

imageView.setOnLongClickListener(v -> {
    Picasso.get()
            .load(url)
            .networkPolicy(NetworkPolicy.NO_CACHE)//跳过磁盘缓存
            .memoryPolicy(MemoryPolicy.NO_CACHE) //跳过内存缓存
            .into(imageView);
    return true;
});

三、Picasso的图片变换
代码语言:javascript
复制
ImageView:300dp*300dp
资源图片:3600px*2400px

测试图.png


1.对比一下点击前后的变化

这个是使用Picasso

点击前后.png

直接BitmapFactory.decodeFile

BitmapFactory.decodeFile.png

可见基本上差不多,说明Picasso在加载大图是,默认情况下并未优化


2.resize方法和resizeDimen

resize方法可以对大图进行优化,但本地缓存的大小依然是原图大小 两者本质上一样resizeDimen是使用dimens的尺寸资源,可以dp

resize.png

重置尺寸.png


3.fit和centerCrop

注意centerCrop有个一参的入参:Gravity.XXX来控制裁剪的位置(默认中心裁剪) centerCrop必须调用resize才行,fit调用后,deferred = true; 在into方法中会触发resize 另外fit不能和resize共存

代码语言:javascript
复制
java.lang.IllegalStateException: Center crop requires calling resize with positive width and height.

fit.png


4..transform

总得来说,就是针对Bitmap做一些操作,可参见Bitmap专题,再把新的Bitmap返回出去 下面给出三个简单的操作,灰度,模糊,路径裁剪

变化.png

代码语言:javascript
复制
---->[灰度操作]------------
public class GrayTransformation implements Transformation {
    @Override
    public Bitmap transform(Bitmap source) {
        Bitmap bmpGrayScale = Bitmap.createBitmap(
                source.getWidth(), source.getHeight(), Bitmap.Config.RGB_565);
        Canvas c = new Canvas(bmpGrayScale);
        Paint paint = new Paint();
        ColorMatrix cm = new ColorMatrix();
        cm.setSaturation(0);
        paint.setColorFilter(new ColorMatrixColorFilter(cm));
        c.drawBitmap(source, 0, 0, paint);
        if (source != bmpGrayScale) {
            source.recycle();
        }
        return bmpGrayScale;
    }
    @Override
    public String key() {
        return "BlurTransformation";
    }
}

---->[模糊操作]------------
public class BlurTransformation implements Transformation {
    private Context mContext;
    private int mRadius;

    public BlurTransformation(Context context, int radius) {
        mContext = context;
        mRadius = radius;
    }

    @Override
    public Bitmap transform(Bitmap source) {
        RenderScript rs = RenderScript.create(mContext);
        Bitmap blurredBitmap = source.copy(Bitmap.Config.ARGB_8888, true);
        Allocation input = Allocation.createFromBitmap(rs, blurredBitmap,
                Allocation.MipmapControl.MIPMAP_FULL, Allocation.USAGE_SHARED);
        Allocation output = Allocation.createTyped(rs, input.getType());
        ScriptIntrinsicBlur script = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));
        script.setInput(input);
        script.setRadius(mRadius);
        script.forEach(output);
        output.copyTo(blurredBitmap);
        source.recycle();
        return blurredBitmap;
    }

    @Override
    public String key() {
        return "BlurTransformation";
    }
}

---->[星星裁剪类]------------
/**
 * 作者:张风捷特烈<br/>
 * 时间:2018/8/30 0030:21:44<br/>
 * 邮箱:1981462002@qq.com<br/>
 * 说明:星星裁剪类
 */
public class StarTransformation implements Transformation {
    private int num;
    private boolean mOutline;
    public StarTransformation(int num,boolean outline) {
        this.num = num;
        mOutline = outline;
    }
    @Override
    public Bitmap transform(Bitmap source) {
        int size = Math.min(source.getWidth(), source.getHeight());
        int x = (source.getWidth() - size) / 2;
        int y = (source.getHeight() - size) / 2;
        Bitmap squaredBitmap = Bitmap.createBitmap(source, x, y, size, size);
        if (squaredBitmap != source) {
            source.recycle();
        }
        int strokeWidth = (int) (size / 120f);
        Bitmap bitmap = Bitmap.createBitmap(size, size, source.getConfig());
        Canvas canvas = new Canvas(bitmap);
        Paint avatarPaint = new Paint();
        BitmapShader shader = new BitmapShader(squaredBitmap, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAM
        avatarPaint.setShader(shader);
        Paint outlinePaint = new Paint();
        outlinePaint.setColor(Color.WHITE);
        outlinePaint.setStyle(Paint.Style.STROKE);
        outlinePaint.setStrokeWidth(strokeWidth);
        outlinePaint.setAntiAlias(true);
        Path starPath = nStarPath(num, size / 2, size / 2 * 0.8f);
        canvas.drawPath(starPath, avatarPaint);
        if (mOutline) {
            canvas.drawPath(starPath, outlinePaint);
        }
        squaredBitmap.recycle();
        return bitmap;
    }
    private Path nStarPath(int num, float R, float r) {
        Path path = new Path();
        float perDeg = 360 / num;
        float degA = perDeg / 2 / 2;
        float degB = 360 / (num - 1) / 2 - degA / 2 + degA;
        float dx = R * cos(degA);
        float dy = R;
        path.moveTo(cos(degA) * R + dx, -sin(degA) * R + dy);
        for (int i = 0; i <= num; i++) {
            path.lineTo(cos(degA + perDeg * i) * R + dx, -sin(degA + perDeg * i) * R + dy);
            path.lineTo(cos(degB + perDeg * i) * r + dx, -sin(degB + perDeg * i) * r + dy);
        }
        path.close();
        return path;
    }
    private float sin(float deg) {
        return (float) Math.sin(deg / 180 * Math.PI);
    }
    private float cos(float deg) {
        return (float) Math.cos(deg / 180 * Math.PI);
    }
    @Override
    public String key() {
        return "StarTransformation";
    }
}

四、常规使用
1.其他设置

旋转.png

代码语言:javascript
复制
.placeholder(R.mipmap.icon_default)//默认占位图
.error(R.mipmap.error)//错误显示图
.rotate(90)//旋转90度
.noFade()//取消渐变---默认有渐变

2.加载的形式

说是四种,核心都差不多,就是找资源而已

四种加载方式.png

代码语言:javascript
复制
String url = "http://192.168.10.104:8080/imgs/HXqqASHJETSlV**c.jpg";
File file = new File(getCacheDir(), "/picasso-cache/200ca0eb49c069b127236c34582a5c10.1");
Uri uri = Uri.parse("file:///android_asset/wy.jpg");
Picasso.get()
//          .load(url)//加载url
//          .load(R.mipmap.icon_default)//加载资源文件
//          .load(file)//加载文件
        .load(uri)//assets文件---Uri形式

3.自己可以完成一下下面的效果

Picasso的基本用法也就这么多,明天进源码里去看看


后记:捷文规范
1.本文成长记录及勘误表

项目源码

日期

附录

V0.1--

2018-2-11

发布名:开源框架之[-Picasso-]应用篇 捷文链接:https://cloud.tencent.com/developer/article/1397785

2.更多关于我

笔名

QQ

微信

张风捷特烈

1981462002

zdl1994328

我的github:https://github.com/toly1994328 我的简书:https://www.jianshu.com/u/e4e52c116681 我的掘金:https://juejin.im/user/5b42c0656fb9a04fe727eb37 个人网站:http://www.toly1994.com

3.声明

1----本文由张风捷特烈原创,转载请注明 2----欢迎广大编程爱好者共同交流 3----个人能力有限,如有不正之处欢迎大家批评指证,必定虚心改正 4----看到这里,我在此感谢你的喜欢与支持

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019.02.11 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 零、前言
  • 一、Picasso的缓存相关
    • 1.点击时进行网络加载
      • 2.再次点击加载网络图片
        • 3.退出再进来加载网络图片
          • 5.小结一下:
          • 二、缓存策略
            • 1.做个试验
              • 2.网络策略:NetworkPolicy与内存策略MemoryPolicy
                • 三、Picasso的图片变换
                  • 1.对比一下点击前后的变化
                    • 2.resize方法和resizeDimen
                      • 3.fit和centerCrop
                        • 4..transform
                        • 四、常规使用
                          • 1.其他设置
                            • 2.加载的形式
                              • 3.自己可以完成一下下面的效果
                              • 后记:捷文规范
                                • 1.本文成长记录及勘误表
                                  • 2.更多关于我
                                    • 3.声明
                                    领券
                                    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档