以下内容均来自Fresco中文网站,网址为http://fresco-cn.org/
本文仅用于个人整理笔记,如涉及侵权,请原作者联系我。
一、使用Fresco
- 添加依赖
dependencies {
compile 'com.facebook.fresco:fresco:0.12.0'
compile 'com.facebook.fresco:imagepipeline-okhttp3: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'
compile 'com.facebook.fresco:webpsupport:0.12.0'
// 仅支持 WebP 静态图,需要添加
compile 'com.facebook.fresco:webpsupport:0.12.0'
}
2.初始化Fresco
在Application中调用Fresco.initialize方法即可。
3.在清单文件中使用指定的Application,并声明网络请求的权限。
4.写布局文件。
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
//注意:在布局文件中我们需要添加命名空间:
xmlns:fresco="http://schemas.android.com/apk/res-auto"
android:layout_height="match_parent"
android:layout_width="match_parent">
//引用Fresco的专用控件:)
<com.facebook.drawee.view.SimpleDraweeView
android:id="@+id/my_image_view"
android:layout_width="130dp"
android:layout_height="130dp"
fresco:placeholderImage="@drawable/my_drawable"
/>
注意:SimpleDraweeView不可以使用wrap_content设置宽高属性
5.Java代码中添加加载图片逻辑
简单的显示一张图片,只需要设置图片加载路径即可。
Uri uri = Uri.parse("https://raw.githubusercontent.com/facebook/fresco/gh-pages/static/logo.png");
SimpleDraweeView draweeView = (SimpleDraweeView) findViewById(R.id.my_image_view);
draweeView.setImageURI(uri);
这样我们就可以简单的显示一张从网络上加载的图片了。在这个过程中,Fresco还替我们完成了下面的事情:
①下载图片
②缓存 图片
③图片不再显示时,从内存中移除
④显示占位图知道图片加载完成
二、认识Fresco
Fresco包含Drawees、The Image Pipeline两个部分。我们先了解一下他们。
1.Drawees
Drawees负责图片的呈现,由三个元素组成,分别是DraweeView、DraweeHierarchy和DraweeController。下面用一张图来表示三者之间的关系。
(1) 在布局文件中使用Drawees
<com.facebook.drawee.view.SimpleDraweeView
android:id="@+id/my_image_view"
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"
//progressBar自动旋转时长,这个属性在Java代码中设置不起作用,原因不清楚
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强制设置宽高值,如果没有在xml中声明宽高值,则无法正确加载图像。
★ Drawees不支持wrap_content属性。所下载的图像可能和占位图尺寸不一致,如果设置errorImage或reTryImage的话,这些图的尺寸也可能和加载的图像尺寸不一致,这种情况下,使用wrap_content的话,view将会重新layout,改变大小和位置,从而导致界面跳跃的情况。了解更多,请查看wrap_content的限制。
★ 有一种情况下,我们可以任性一下,使用wrap_content,那就是当我们希望显示的图片拥有固定的宽高比时,我们可以在宽高有一个固定的情况下,为另一个设置wrap_content,并设置二者的固定比例,也可以在Java代码中指定显示比例。如:
```
//xml中设置宽高
<com.facebook.drawee.view.SimpleDraweeView
android:id="@+id/my_image_view"
android:layout_width="20dp"
android:layout_height="wrap_content"
fresco:viewAspectRatio="1.33"
<!-- other attributes -->
```
```
//在Java代码中设置宽高比
mSimpleDraweeView.setAspectRatio(1.33f);
```
(2) 在Java代码中使用Drawees
设置或更改要显示的图片简单的方法:
mSimpleDraweeView.setImageURI(uri);
如果需要对加载显示的图片做更多的控制和定制,可以使用ControllerBuilder,关于ControllerBuildr后面会说到。
自定义DraweeHierarchy,当xml布局中设置不能满足我们的需要时,可以通过自定义DraweeHierarchy来实现。我们可以创建一个GenericDraweeHierarchyBuilder来设置Drawees的属性,然后将这个builder设置给DraweeView即可。
List<Drawable> backgroundsList;
List<Drawable> overlaysList;
GenericDraweeHierarchyBuilder builder =new GenericDraweeHierarchyBuilder(getResources());
GenericDraweeHierarchy hierarchy = builder
.setFadeDuration(300)
.setPlaceholderImage(new MyCustomDrawable())
.setBackgrounds(backgroundList)
.setOverlays(overlaysList)
.build();
mSimpleDraweeView.setHierarchy(hierarchy);
注意,对于同一个view,不可以多次调用setHierarchy,即使这个view是可回收的,因为创建DraweeHierarchy是一个较为耗时的操作,应该被多次利用。如果要改变显示的图片可使用setController或setImageURI。
注意:
① 当xml布局设置的方式和Java代码中设置的方式同时使用时,默认采用Java代码设置的方式,即xml中设置的属性将不起作用。
② 两种方式都会在运行时创建一个builder,只是xml方式创建的是一个默认的,而Java代码创建的使我们自定义的。
③ 这两种方式必须使用一种,否则在加载gif时,将会无法显示动画效果
④ 在Java代码中设置progressBarAutoRotateInterval属性不起作用
⑤ 在Java代码中设置图片缩放形式不要使用setScaleType或scaleType方法来设置,Drawees不支持。
⑥ 除了需要加载的图像是真正必须设置的属性,其他的图像都是可选设置的。要显示的图像可以来自多个地方。所需加载的图像实际上是DraweeController 的一个属性,而不是 DraweeHierarchy 的属性。
⑦ 要显示进度条,最简单的办法就是在构建hierarchy时使用ProgressBarDrawable,如.setProgressBarImage(new ProgressBarDrawable()),这样就可以在Drawee底部出现一个深蓝色的矩形进度条。如果想精确显示加载进度,需要重写Drawable.onLevelChange()
⑧ 关于Drawee支持的缩放类型
基本与ImageView支持的缩放类型一样,唯一不支持的缩放类型是matrix。Fresco提供了focusCrop作为补充,通常这个使用效果更佳。focusCrop同centerCrop,但居中点不是中点,而是指定的某个点。centerCrop缩放模式会保持长宽比,放大或缩小图片,填充满显示边界,居中显示,这种缩放模式在通常情况下很有用,但是对于人脸等图片时,一味地居中显示,可能会裁剪掉一些有用的信息。所以,如果可以设置某个点为居中点,可以更好的满足我们的需求。
⑨ 关于对动画的支持
Fresco支持GIF和WebP格式的动画图片。
我们可以通过在创建DraweeController时调用.setAutoPlayAnimations(true)方法来设置动画自动播放,也可以在图片加载成功时控制动画播放。注意:目前还不支持动画的postprocessors处理。
(3)自定义view
有一些时候,DraweeViews并不能满足我们的需求,在展示图片的时候,我们可能还需要展示一些其他的内容,或者支持一些其他的操作。在同一个View里,我们可能会想显示一张或者多张图。
在自定义View中,Fresco 提供了两个类来负责图片的展现:
① DraweeHolder 单图情况下用。
DraweeHolder 是持有 DraweeHierarchy 的一个类,它和 DraweeController 紧密相关。它允许你在自定义View中也能够使用所有Drawee的特性! 你只需要通过 mDraweeHolder.getTopLevelDrawable() 就能够获取Drawable。你需要知道 Android Drawable 需要一些特殊照顾,所以请仔细阅读下面的内容。
② MultiDraweeHolder 多图情况下用。
MultiDraweeHolder 仅仅是 DraweeHolder 的一个列表。
Android 呈现View对象,只有View对象才能得到一些系统事件的通知。DraweeViews处理这些事件通知,高效地管理内存。使用DraweeHolder时,你需要自己实现这几个方法。
① 处理 attach/detach 事件
如果没按照以下步骤实现的话,很可能会引起内存泄露。当图片不再在View上显示时,比如滑动时View滑动到屏幕外,或者不再绘制,图片就不应该再存在在内存中。Drawees 监听这些事情,并负责释放内存。当图片又需要显示时,重新加载。这些在DraweeView中是自动的,但是在自定义View中,需要我们自己去操作,如下:
DraweeHolder mDraweeHolder;
@Override
public void onDetachedFrom