最近封装了个 fresco 的组件库:dfresco,就顺便来讲讲。

背景

fresco 图片库很强大,我们项目中就是使用的 fresco,但有一点就是,不怎么好使用,略麻烦。不同项目中,多多少少都需要对 fresco 进行一层封装才能在 ui 里快速使用。

这就导致了,不同项目都根据自己的业务需求场景来进行封装,每次有新项目,复制粘贴时又得解决好多业务耦合的错误,麻烦,是真的麻烦~

而且,首次接触 fresco,接入上手的成本相比其他图片库,如 glide,成本都要大很多。

举个例子,假如你有这么个需求:加载一张网络上的 gif 图片,为了防止内存占用过多,需要设置分辨率压缩,最后显示到圆形控件上,同时,需要设置占位图,错误图,拉伸方式等。

那么此时,你的代码可能就是这样的:

imagedecodeoptions imagedecodeoptions = imagedecodeoptions.newbuilder()

.setdecodepreviewframe(true).build();

imagerequestbuilder builder = imagerequestbuilder.newbuilderwithsource(muri)

.setprogressiverenderingenabled(true)

.setimagedecodeoptions(imagedecodeoptions);

if (mwidth > 0 && mheight > 0) {

builder.setresizeoptions(new resizeoptions(mwidth, mheight));

}

imagerequest request = builder.build();

abstractdraweecontroller controller = fresco.newdraweecontrollerbuilder()

.setimagerequest(request)

.setcontrollerlistener(listener)

.setoldcontroller(draweeview.getcontroller())

.setautoplayanimations(true).build();

draweeview.setcontroller(controller);

同时,你可能还需要在 xml 中对 simpledrawwview 控件进行占位图等等的配置:

android:id="@+id/sdv_fresco"

android:layout_width="500dp"

android:layout_height="500dp"

fresco:actualimagescaletype="centercrop"

fresco:fadeduration="3000"

fresco:failureimage="@mipmap/ic_launcher"

fresco:failureimagescaletype="centercrop"

fresco:placeholderimage="@mipmap/ic_launcher"

fresco:placeholderimagescaletype="centercrop"

fresco:progressbarautorotateinterval="1000"

fresco:progressbarimage="@drawable/ani_rotate"

fresco:progressbarimagescaletype="centercrop"

fresco:retryimage="@mipmap/ic_launcher"

fresco:retryimagescaletype="centercrop"

fresco:backgroundimage="@mipmap/ic_launcher"

fresco:overlayimage="@mipmap/ic_launcher"

fresco:pressedstateoverlayimage="@mipmap/ic_launcher"

fresco:roundascircle="false"

fresco:roundingborderwidth="2dip"

fresco:roundingbordercolor="@color/colorprimary"/>

如果忘记了某个自定义属性名是什么的时候,还得到网上搜索下资料,是吧。

小结一下,使用 fresco,你的接入学习成本至少需要知道 fresco 的如下信息:

simpledraweeview 的自定义属性

imagerequestbuilder 用法及大概用途

abstractdraweecontroller 用法及大概用途

genericdraweehierarchy 用法及大概用途

如果涉及到一些网络下载监听,缓存之类的,那么你还要了解:

imagepipeline 用法及大概用途

总之,fresco 强大是强大,但使用起来不方便,不得不封装一层。

既然要封装,那么就直接借鉴 glide 的使用思想来进行封装好了,如果有使用过 glide 的应该很清楚,要实现以上功能,全程一个调用链即可。

二次封装

封装要达到的目的有两点:

使用简洁、方便

其他人接入直接上手的成本尽可能少,最好不用去看文档,去看源码

第一点可以参考 glide 的使用方式来设计,那么第二点我的想法是借助 androidstudio 的代码提示功能来实现。

比如,你只需知道,组件的入口是 dfresco 即可,其他都通过 androidstudio 来给你提示,如:

当你在 androidstudio 上输入 dfresco. 后,界面上会弹出你可用 api,这些就是我开放给你的入口,我将这个使用过程划分成几个步骤,每个步骤能做什么,该做什么,我都给你规定好了,你参照着提示,直接从方法命名上就能够知道该如何使用了,androidstudio 会一步步引导你。

这里就两个入口,一个是用来初始化 fresco 的:

init(context)

这个内部封装了一些默认的初始化配置,比如内存大小配置,内部日志配置等等。

init(context, imagepipelineconfig)

这个是开放给你的自定义配置,如果你不想使用默认的配置的话。

source(string url) :加载网络上的图片

source(file localfile) :加载磁盘上的图片

source(context context, int resid) :加载 res 内的 drawable 资源图片

source(uri uri) :通用的加载方式

我将常用的几种图片来源单独封装出来使用,方便。

当调用了 source() 后就进入了第二个步骤,这个步骤中,我将图片相关的配置设计到另外一个步骤中去,否则连同图片配置的 api 也都在这里的话,会搞得蛮乱的,可能让使用者到这里后不清楚该调用哪些接口了。

所以,我会把控每个步骤的 api,尽量让每个步骤的 api 做的事都比较相近,比如这里:

intotarget(simpledraweeview) 加载图片显示到控件上

intotarget(simpledraweeview,controllerlistener) 加载图片显示到控件上,允许监听这个过程

intotarget(basebitmapdatasubscriber) 只加载图片到内存中,以 bitmap 形式存在

我的需求场景大概就是直接加载图片显示到控件上,或者有时候只是需要将图片加载到内存中,但不用显示到某个控件上,反而要取得图片的 bitmap 对象,所以我将这些都封装起来了。

resize(int width, int height)

这个实际上就是对 fresco 中的 resizeoptions 的一层封装而已,简化使用,不至于像以前那么麻烦。

enterimageconfig()

如果你都使用默认配置的话,那么是不用再去调用那些各种配置的接口的,所以我才将图片配置封装到另外一个步骤中,这个步骤你可进,可不进,如果有需求,那么通过这个方法进入图片配置步骤:

这里的配置项很多,也是因为这个原因,所以才不想让这些接口跟上一个步骤放一起,不然很容易让使用者懵掉。而进入了图片配置这个步骤后,这里提供的 api 其实就是对 genericdraweehierarchy 的用途进行了一层封装,或者说对 simpledraweeview 的自定义属性进行了一层封装。

如果你不熟悉,没关系,其实就是一些常用的功能,如设置控件为圆形、圆角、边框,设置占位图、失败图、进度图、图片拉伸方式、淡入淡出动画时长等等。

这样封装的目的在于,你可以通过一条调用链的形式就设置完所有的配置,就像 glide 的使用一样,而不用再去 new 很多 fresco 的类,再去拼接。

进入图片配置步骤只是一个可选的步骤,进来之后当然就要出去,所以当完成了你的配置后,需要调用:finishimageconfig(),如:

这样就完成了图片配置,将流程切回主线了,就可以继续根据你的需要设置图片显示的目标了。

当然,为了防止再次进入图片配置步骤这样造成之前的配置项失效的场景,我借鉴了 fresco 的 init 处理方法,即,如果一次使用过程中,重复进入图片配置步骤,那么程序会抛异常来提醒你不能这么做。

以上,就是 dfresco 组件的封装思想,欢迎指点一下哈~

另外,参考了 glide 的一些处理,当你的 intotarget 是传入了 simpledraweeview 控件时,dfresco 内部会自动根据控件的大小对图片进行一次分辨率压缩,降低图片占用内存,当然,如果你有手动调用了 resize(),那么以你的为主。

使用示例

compile 'com.dasu.image:fresco:0.0.1'

使用之前,需先初始化,建议在 application 中进行:

dfresco.init(this);

//加载 res 中的 drawable 图片到 simpledraweeview 控件上(默认支持 gif 图,并且会自动根据控件宽高进行分辨率压缩,降低内存占用

dfresco.source(mcontext, r.drawable.weixin).intotarget(msimpledraweeview);

//加载磁盘中的图片,手动设置分辨率的压缩,并获取 bitmap 对象,监听回调,手动显示到 imageview 控件上

dfresco.source(new file("/mnt/sdcard/weixin.jpg"))

.resize(500, 500)

.intotarget(new basebitmapdatasubscriber() {

@override

protected void onnewresultimpl(bitmap bitmap) {

log.w("!!!!!!", "bitmap:bytecount = " + bitmap.getbytecount() + ":::bitmap:allocationbytecount = " + bitmap.getallocationbytecount());

log.w("!!!!!!", "width:" + bitmap.getwidth() + ":::height:" + bitmap.getheight());

mimageview.setimagebitmap(bitmap);

}

@override

protected void onfailureimpl(datasource> datasource) {

log.e("!!!!!!", "onfailureimpl");

}

});

//加载网络图片,进行各种配置,如缩放方式,占位图,圆形,圆角,动画时长等等,最后自动显示到 simpledraweeview 控件上

dfresco.source("https://upload-images.jianshu.io/upload_images/1924341-9e528ee638e837a5.png")

.enterimageconfig() //进入配置步骤

.allfitxy() //所有图片,包括占位图等等的拉伸方式

.animfade(3000) //淡入淡出动画时长

.placeholderscaletype(scalingutils.scaletype.center_inside) //设置占位图的拉伸方式,后面设置的会覆盖前面的

.actualscaletype(scalingutils.scaletype.center)

// .asround(50) //设置圆角,(圆角和圆形不能同时设置)

.ascircle() //设置控件显示为圆形控件

.roundbordercolor(color.red) //设置圆角或圆形的边框颜色

.roundborderwidth(20) //设置圆角或圆形的边框宽度

.failure(r.drawable.timg) //设置失败图

.progressbar(r.drawable.aaaa) //设置加载进度图

.retry(r.drawable.weixin) //设置重试时的图

.placeholder(r.drawable.image) //设置占位图

.finishimageconfig() //退出配置步骤

.intotarget(msimpledraweeview);

大家好,我是 dasu,欢迎关注我的公众号(dasuandroidtv),如果你觉得本篇内容有帮助到你,可以转载但记得要关注,要标明原文哦,谢谢支持~

Android基于Glide的二次封装,借鉴Glide思想二次封装Fresco相关推荐

  1. Android基于环信SDK开发IM即时聊天(二)

    声明1:北京时间现在是2019/6/10,评论里的问题我看到了,这几天我找时间看看源代码问题出在哪,在此感谢大家的监督 声明2:此Demo我是在5.1测试机上测试通过,感谢WTQ_DOMIAN的评论, ...

  2. Android基于环信SDK开发IM即时聊天(一)

    2016-09-02更新:可以看一下最新的这篇文章和源码,Android基于环信SDK开发IM即时聊天(二) 目前市面上我了解的做第三方即时聊天SDK的有两家:环信.融云,这里我使用环信SDK来完成即 ...

  3. Android基于XMPP Smack openfire 开发的聊天室

    公司刚好让做即时通讯模块,服务器使用openfire,偶然看到有位仁兄的帖子,拷贝过来细细研究,感谢此仁兄的无私,期待此仁兄的下次更新 转自http://blog.csdn.net/lnb333666 ...

  4. Android 基于Zxing的扫码功能实现(二)

    本篇文章已授权微信公众号 guolin_blog (郭霖)独家发布 引言 本篇博文是基于 Android 二维码的扫码功能实现(一) 文章写的,建议阅读这篇文章之前,先看看上篇文章.还有建议阅读本文的 ...

  5. Android基于Glide(4.6.1)加载gif实践

    1.Glide是什么? Glide是一个面向Android的快速高效的开源媒体管理和图像加载框架,它将媒体解码.内存和磁盘缓存以及资源池封装到一个简单易用的接口中: Glide支持获取.解码和显示视频 ...

  6. Android 基于google Zxing实现二维码 条形码扫描,仿微信二维码扫描效果

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! 转载请注 ...

  7. Android 基于google Zxing实现二维码、条形码扫描,仿微信二维码扫描效果

    转载请注明出处:http://blog.csdn.net/xiaanming/article/details/10163203 了解二维码这个东西还是从微信中,当时微信推出二维码扫描功能,自己感觉挺新 ...

  8. Android 基于Zxing的二维码扫描优化

    最近公司项目App中要集成二维码扫描来适应在户外工作的时候,对码头集装箱等上面贴的A4纸张打印的二维码进行识别, 一般App二维码集成后,能扫出来就不管了,但是我们在集成成功后,根据用户反馈,在户外的 ...

  9. Android基于Google Zxing实现二维码/条形码扫描、生成二维码/条形码

     二维码/条形码生成器 二维码/条形码扫描器 一.二维码与条形码工作原理 目前的很多应用上都有扫码功能,当时微信推出二维码扫码功能时,觉得imagine,通过一张简单的图片就能扫描添加还有,还有分 ...

最新文章

  1. 字典怎么增加元素_python3基础之字典
  2. SDN,这一年都经历了什么
  3. c语言cin n1 n2,牛客等级之题N1 追债之旅 - N2 Rinne Loves Study(8.6场)
  4. 600 imp oracle_oracle数据库的导入导出(imp和exp)
  5. php中的类 对象的方法的区别,php中类和对象的区别是什么
  6. spring注解开发:容器中注册组件方式
  7. Nacos服务端流程图
  8. 贪心: Array Splitting(数列分段)(洛谷CF1175D)
  9. 如何在xp中添加打印机
  10. matlab层次分析法程序购置设备,[转载]MATLAB实现层次分析程序
  11. c语言 int a 5,在C语言中,有如下的写法:int a = 5; int *pa; pa = (a + 1);
  12. Java开发环境系列:你真的会用eclipse吗?
  13. 「测绘知识」高等级道路竖曲线的精确计算方法
  14. nod32升级问题解决(20080530)
  15. linux设备i2c优先级,Linux设备之I2C
  16. 对话职业经理人阿朱:程序员转型期的职业选择
  17. BLE4.0广播连接过程的底层剖析
  18. 向量个数,向量维数,向量空间维数
  19. 当公司倒闭时,你在干什么?
  20. 智能学习 | MATLAB实现基于HS和谐搜索的时间序列未来多步预测

热门文章

  1. angular 字符串转换成数字_Python成为专业人士笔记–String字符串方法
  2. MySQL索引优化讲解
  3. Linux创建sqlite数据库文件,SQLite数据库的创建与附加
  4. LightGBM常用模板
  5. canvas绘制竖排的数字_大佬教你用Python Tkinter实现数字猜谜小游戏
  6. mysql varchar json_谈谈 MySQL 的 JSON 数据类型
  7. idea修改完jdbc文件后没有更新_JDBC+MySQL入门案例
  8. 算法提高 陶陶摘苹果(java)
  9. java中复制图片_如何在Java中实现复制图片
  10. mysql5.7.11源码安装,mysql 5.7.11 源码安装