图片加载神器fresco----fresco的基本使用
2016-09-01 22:35
489 查看
写在前面
库的依赖配置
使用fresco来加载图片
1 在xml中配置SimpleDraweeView的属性
2 如何查找SimpleDraweeView控件中都有哪些可用的自定义属性
首先查看SimpleDraweeView的源码
其次分析fresco如何加载xml配置的属性
在module的gradle中加入库的依赖引用。
这样就可以使用fresco库来加载图片了,是不是很简单。
当然fresco库远不止这些,这是一个很强大的库,如要支持webP格式的图片,Gif图片。还可以引入如下的库:
webp格式图片,进一步的优化了图片资源的大小,加载的效率更高了,提升了app的性能。
为了迎合官方推广使用Android Studio,这里就不多介绍fresco在Eclipse中的使用,这里附上库的下载包:zip文件
注意事项:一般情况下这样就可以了,但是对于多进程的应用来说,不同的进程都会执行一次Application的onCreate方法,那就意味着在onCreate里的一些初始化操作会多次执行,多少对于应用的性能是有影响的。那对于多进程环境的应用可以有如下解决方案(伪代码,就是这么随意任性):
我们先加载一张网络图片,那就需要网络权限,在manifest中加入,别加入自己的Application:
fresco为我们提供了一个图片显示控件SimpleDraweeView,这个控件基本上能满足我们绝大多数的需求,使用也很简单:
因为要用到控件的自定义属性,所以需要引入自定义的命名空间fresco。
placeholderImage顾名思义,就是图片还在加载,下载的时候,等待期间显示的图片,可以是drawable图片也可以是color颜色。下面来加载一张网络图片:
是不是很简单,只要把图片的地址用Uri包装起来,设置给SimpleDraweeView,fresco就会帮你去显示占位符图片,下载,缓存,在图像不可见的时候及时的回收图片占用的内存。so easy~~
Uri包装不同的图片格式如下:
解释下属性的意思:
好了xml中的属性配置就介绍完了,相信有些小伙伴会有个疑问,我第一次使用SimpleDraweeView,怎么会知道它会有这么些自定义的属性可以使用呢!
很容易就找到了声明属性的属性集:R.styleable.SimpleDraweeView,接下来我们需要找到声明这个属性集合的values.xml,如下:
看这就找到了xml里面配置的所有属性,是不是很简单!细心的小伙伴会发现R.styleable.SimpleDraweeView下定义的属性就一个actualImageUri,其它的属性是定义在R.styleable.GenericDraweeHierarchy下的,不禁心想博主你特么在逗我么!我能说冤枉么(55555~~~),别急小伙伴们,下面就来分析问你解惑,fresco是在哪里为我们加载和解析了我们xml配置的那些属性呢。
可以看到属性的构建交给了GenericDraweeHierarchyInflater.inflateBuilder方法,继续跟踪下去:
继续跟踪updateBuilder方法:
终于找到梦寐以求的R.styleable.GenericDraweeHierarchy,然后是一个个去遍历获取每个属性的值,设置给GenericDraweeHierarchyBuilder构造器。调用触发是在SimpleDraweeView的构造器里的super(context, attrs),经过层层调用由updateBuilder完成了所有属性的加载和解析赋值。
文章有点长,感谢耐心看完!fresco基本的加载图片的使用就是这样。后面我会陆续写一些重构和优化项目时,使用fresco的一些特性,和Glide框架的对比,优缺点等等内容。希望此文能带给小伙伴们些许帮助。谢谢~
库的依赖配置
使用fresco来加载图片
1 在xml中配置SimpleDraweeView的属性
2 如何查找SimpleDraweeView控件中都有哪些可用的自定义属性
首先查看SimpleDraweeView的源码
其次分析fresco如何加载xml配置的属性
1. 写在前面
好久没写博客了,最近在对公司的项目进行重构和优化,针对图片加载框架的修改,原来使用的是Glide,现在改成Facebook的fresco来做对比。先介绍fresco的基本使用。2. 库的依赖配置
我这里用的IDE是Android Studio,对于库支持的使用配置比较简单,如下:在module的gradle中加入库的依赖引用。
dependencies { /************图片加载框架fresco库开始**************/ compile 'com.facebook.fresco:fresco:0.12.0' /************图片加载框架fresco库结束**************/ }
这样就可以使用fresco库来加载图片了,是不是很简单。
当然fresco库远不止这些,这是一个很强大的库,如要支持webP格式的图片,Gif图片。还可以引入如下的库:
dependencies { /************图片加载框架fresco库开始**************/ compile 'com.facebook.fresco:fresco:0.12.0' // 在API < 14的系统如也要支持 webP图片的话加入 compile 'com.facebook.fresco:animated-base-support:0.12.0' // 支持Gif图片,需加入 compile 'com.facebook.fresco:animated-gif:0.12.0' // 支持webP图片的动态图,需加入 compile 'com.facebook.fresco:animated-webp:0.12.0' // 支持webP图片的静态图,需加入 compile 'com.facebook.fresco:webpsupport:0.12.0' /************图片加载框架fresco库结束**************/ }
webp格式图片,进一步的优化了图片资源的大小,加载的效率更高了,提升了app的性能。
为了迎合官方推广使用Android Studio,这里就不多介绍fresco在Eclipse中的使用,这里附上库的下载包:zip文件
3. 使用fresco来加载图片
首先在加载图片前需要对框架做初始化的操作,通过调用Fresco.initialize方法一次就可以初始化。因为多次调用此方法是一样的,所以作为初始化的地方最好的位置就是 Application的onCreate里:public class MyApplication extends Application { @Override public void onCreate() { super.onCreate(); Fresco.initialize(this); } }
注意事项:一般情况下这样就可以了,但是对于多进程的应用来说,不同的进程都会执行一次Application的onCreate方法,那就意味着在onCreate里的一些初始化操作会多次执行,多少对于应用的性能是有影响的。那对于多进程环境的应用可以有如下解决方案(伪代码,就是这么随意任性):
public class MyApplication extends Application { @Override public void onCreate() { super.onCreate(); String curProcessName = 获取当前进程的名字 String needUseFrescoProcessName = 需要使用fresco组件库来加载图片的进程名字 if(curProcessName.equals(needUseFrescoProcessName)){ // 当前进程就是需要加载fresco组件的进程,才初始化组件 Fresco.initialize(this); // 同理其它的一些组件也是,如:第三方分享组件,统计组件,支付组件等等 } } }
我们先加载一张网络图片,那就需要网络权限,在manifest中加入,别加入自己的Application:
<manifest ... > <uses-permission android:name="android.permission.INTERNET" /> <application ... android:label="@string/app_name" android:name=".MyApplication" > ... </application> ... </manifest>
fresco为我们提供了一个图片显示控件SimpleDraweeView,这个控件基本上能满足我们绝大多数的需求,使用也很简单:
<com.facebook.drawee.view.SimpleDraweeView xmlns:fresco="http://schemas.android.com/apk/res-auto" android:id="@+id/sdv_head_image" android:layout_width="50dp" android:layout_height="50dp" fresco:placeholderImage="@drawable/ic_wait_image" />
因为要用到控件的自定义属性,所以需要引入自定义的命名空间fresco。
placeholderImage顾名思义,就是图片还在加载,下载的时候,等待期间显示的图片,可以是drawable图片也可以是color颜色。下面来加载一张网络图片:
SimpleDraweeView headImage = (SimpleDraweeView)findViewById(R.id.sdv_head_image); Uri headUri = Uri.parse("https://raw.githubusercontent.com/facebook/fresco/gh-pages/static/logo.png"); headImage.setUri(headUri);
是不是很简单,只要把图片的地址用Uri包装起来,设置给SimpleDraweeView,fresco就会帮你去显示占位符图片,下载,缓存,在图像不可见的时候及时的回收图片占用的内存。so easy~~
Uri包装不同的图片格式如下:
类型 | SCHEME | 示例 |
---|---|---|
远程图片 | http://, https:// | HttpURLConnection 或者参考 使用其他网络加载方案 |
本地文件 | file:// | FileInputStream |
Content provider | content:// | ContentResolver |
asset目录下的资源 | asset:// | AssetManager |
res目录下的资源 | res:// | Resources.openRawResource |
Uri中指定图片数据 | data:mime/type;base64, | 数据类型必须符合 rfc2397规定 (仅支持 UTF-8) |
3.1. 在xml中配置SimpleDraweeView的属性
<com.facebook.drawee.view.SimpleDraweeView xmlns:fresco="http://schemas.android.com/apk/res-auto" android:id="@+id/sdv_head_image" android:layout_width="20dp" android:layout_height="20dp" fresco:fadeDuration="300" fresco:actualImageScaleType="focusCrop" fresco:placeholderImage="@color/wait_color" fresco:placeholderImageScaleType="fitCenter" fresco:failureImage="@drawable/error" fresco:failureImageScaleType="centerInside" fresco:retryImage="@drawable/retrying" fresco:retryImageScaleType="centerCrop" fresco:progressBarImage="@drawable/progress_bar" fresco:progressBarImageScaleType="centerInside" fresco:progressBarAutoRotateInterval="1000" fresco:backgroundImage="@color/blue" fresco:overlayImage="@drawable/watermark" fresco:pressedStateOverlayImage="@color/red" fresco:roundAsCircle="false" fresco:roundedCornerRadius="1dp" fresco:roundTopLeft="true" fresco:roundTopRight="false" fresco:roundBottomLeft="false" fresco:roundBottomRight="true" fresco:roundWithOverlayColor="@color/corner_color" fresco:roundingBorderWidth="2dp" fresco:roundingBorderColor="@color/border_color" fresco:viewAspectRatio="1.0" />
解释下属性的意思:
属性 | 作用说明 |
---|---|
fadeDuration | 图片渐渐显示的时间,单位毫秒 |
actualImageScaleType | 图片的缩放类型,其值有:none, center,centerCrop,focusCrop,centerInside,fitCenter,fitStart,fitEnd,fitXY。Fresco建议使用focusCrop,它和centerCrop类似,centerCrop是居中后裁切掉超多视图容器的部分图片,而focusCrop可以指定一个焦点后进行裁切。 |
placeholderImage | 占位符预加载图片,可以是图片、颜色值 |
placeholderImageScaleType | 占位符图片的缩放类型,其值同actualImageScaleType一样。 |
failureImage | 图片加载失败后显示的错误图片 |
failureImageScaleType | 错误图片的缩放类型 |
retryImage | 图片加载失败后,显示的重试加载的图片,重试4次后才形式错误的图片 |
retryImageScaleType | 重试图片的缩放类型 |
progressBarImage | 正在加载图片时的加载进度条图片 |
progressBarImageScaleType | 加载进度条图片的缩放类型 |
progressBarAutoRotateInterval | 加载进度条自动旋转的间隔时间,单位毫秒 |
backgroundImage | 背景图片,最先绘制的图片 |
overlayImage | 覆盖在加载完成后图片上的叠加图片 |
pressedStateOverlayImage | 按压状态下的叠加图片 |
roundAsCircle | 是否为圆形图片 |
roundedCornerRadius | 圆角图片时候,圆角的半径大小 |
roundTopLeft | 左上角是否为圆角 |
roundTopRight | 右上角是否为圆角 |
roundBottomLeft | 左下角是否为圆角 |
roundBottomRight | 右下角是否为圆角 |
roundWithOverlayColor | 圆角或圆形图叠加的颜色,只能是颜色 |
roundingBorderWidth | 圆角或圆形图边框的宽度 |
roundingBorderColor | 圆角或圆形图边框的颜色 |
viewAspectRatio | 控件的宽高比,因为fresco不支持wrap_content, 所以有些需求可以layout_width为具体的值,layout_height为wrap_content,同时设置这个属性的比例值,否则无效不显示 |
3.2. 如何查找SimpleDraweeView控件中都有哪些可用的自定义属性
首先,查看SimpleDraweeView的源码
public class SimpleDraweeView extends GenericDraweeView { // ...省略一些代码 public SimpleDraweeView(Context context, AttributeSet attrs) { super(context, attrs); init(context, attrs); } private void init(Context context, @Nullable AttributeSet attrs) { if (isInEditMode()) { return; } Preconditions.checkNotNull( sDraweeControllerBuilderSupplier, "SimpleDraweeView was not initialized!"); mSimpleDraweeControllerBuilder = sDraweeControllerBuilderSupplier.get(); if (attrs != null) { TypedArray gdhAttrs = context.obtainStyledAttributes( attrs, R.styleable.SimpleDraweeView); try { if (gdhAttrs.hasValue(R.styleable.SimpleDraweeView_actualImageUri)) { setImageURI(Uri.parse(gdhAttrs.getString(R.styleable.SimpleDraweeView_actualImageUri)), null); } } finally { gdhAttrs.recycle(); } } } }
很容易就找到了声明属性的属性集:R.styleable.SimpleDraweeView,接下来我们需要找到声明这个属性集合的values.xml,如下:
看这就找到了xml里面配置的所有属性,是不是很简单!细心的小伙伴会发现R.styleable.SimpleDraweeView下定义的属性就一个actualImageUri,其它的属性是定义在R.styleable.GenericDraweeHierarchy下的,不禁心想博主你特么在逗我么!我能说冤枉么(55555~~~),别急小伙伴们,下面就来分析问你解惑,fresco是在哪里为我们加载和解析了我们xml配置的那些属性呢。
其次,分析fresco如何加载xml配置的属性
看SimpleDraweeView的源码会发现,它的父类是GenericDraweeView,我们来跟踪这个父类:public class GenericDraweeView extends DraweeView<GenericDraweeHierarchy> { // ...省略一些代码 public GenericDraweeView(Context context, AttributeSet attrs) { super(context, attrs); inflateHierarchy(context, attrs); } protected void inflateHierarchy(Context context, @Nullable AttributeSet attrs) { GenericDraweeHierarchyBuilder builder = GenericDraweeHierarchyInflater.inflateBuilder(context, attrs); setAspectRatio(builder.getDesiredAspectRatio()); setHierarchy(builder.build()); } }
可以看到属性的构建交给了GenericDraweeHierarchyInflater.inflateBuilder方法,继续跟踪下去:
public static GenericDraweeHierarchyBuilder inflateBuilder( Context context, @Nullable AttributeSet attrs) { Resources resources = context.getResources(); GenericDraweeHierarchyBuilder builder = new GenericDraweeHierarchyBuilder(resources); return updateBuilder(builder, context, attrs); }
继续跟踪updateBuilder方法:
public static GenericDraweeHierarchyBuilder updateBuilder( GenericDraweeHierarchyBuilder builder, Context context, @Nullable AttributeSet attrs) { // ...省略了一些代码 if (attrs != null) { TypedArray gdhAttrs = context.obtainStyledAttributes( attrs, R.styleable.GenericDraweeHierarchy); try { final int indexCount = gdhAttrs.getIndexCount(); for (int i = 0; i < indexCount; i++) { final int attr = gdhAttrs.getIndex(i); // most popular ones first if (attr == R.styleable.GenericDraweeHierarchy_actualImageScaleType) { builder.setActualImageScaleType(getScaleTypeFromXml(gdhAttrs, attr)); } else if (attr == R.styleable.GenericDraweeHierarchy_placeholderImage) { builder.setPlaceholderImage(getDrawable(context, gdhAttrs, attr)); } } } }
终于找到梦寐以求的R.styleable.GenericDraweeHierarchy,然后是一个个去遍历获取每个属性的值,设置给GenericDraweeHierarchyBuilder构造器。调用触发是在SimpleDraweeView的构造器里的super(context, attrs),经过层层调用由updateBuilder完成了所有属性的加载和解析赋值。
文章有点长,感谢耐心看完!fresco基本的加载图片的使用就是这样。后面我会陆续写一些重构和优化项目时,使用fresco的一些特性,和Glide框架的对比,优缺点等等内容。希望此文能带给小伙伴们些许帮助。谢谢~
相关文章推荐
- Android图片加载神器之Fresco-加载图片基础[详细图解Fresco的使用]
- 详解Android之图片加载框架Fresco基本使用(一)
- Android图片加载神器之Fresco-加载图片基础[详细图解Fresco的使用]
- 详解Android之图片加载框架Fresco基本使用(二)
- fresco加载圆形图片 eventbus简单使用 Glide最基本使用
- Android图片加载神器之Fresco-加载图片基础[详细图解Fresco的使用]
- Android图片加载神器之Fresco-加载图片基础[详细图解Fresco的使用]
- Android图片加载神器之Fresco-加载图片基础[详细图解Fresco的使用]
- Android图片加载神器之Fresco-加载图片基础[详细图解Fresco的使用]
- Android图片加载神器之Fresco,基于各种使用场景的讲解
- Android图片加载神器之Fresco-加载图片基础[详细图解Fresco的使用]
- Android图片加载神器之Fresco-加载图片基础[详细图解Fresco的使用]
- Android图片加载神器之Fresco-加载图片基础[详细图解Fresco的使用]
- Android图片加载神器之Fresco-加载图片基础[详细图解Fresco的使用]
- Android图片加载神器之Fresco-加载图片基础[详细图解Fresco的使用]
- Android之图片加载框架Fresco基本使用(一)
- Android图片加载神器之Fresco-加载图片基础[详细图解Fresco的使用]
- Android图片加载神器之Fresco-加载图片基础[详细图解Fresco的使用]
- Android图片加载神器之Fresco,基于各种使用场景的讲解
- Android图片加载神器之Fresco-加载图片基础[详细图解Fresco的使用]