图片加载和处理的又一个神器 Fresco 的使用摘要记录
官方网站:http://fresco-cn.org/
笔记:
如果需要用到mipmap里面的图片使用:
Uri uri = Uri.parse("res://包名(实际可以是任何字符串甚至留空)/" + R.drawable.ic_launcher)
draweeView_url.setImageURI(Uri.parse("https://material-design.storage.googleapis.com/publish/material_v_4/material_ext_publish/0Bx4BSt6jniD7NndTQW9VZTlZV2s/materialdesign_principles_bold.png"));
draweeView_res.setImageURI(Uri.parse("res://mipmap/"+R.mipmap.yoyo));
draweeView_local.setImageURI(Uri.parse("file:///data/data/com.example.xue.frescodemo/files/345.jpg"));
要设置进度条:
要显示进度,最简单的办法就是在 构建 hierarchy 时使用 ProgressBarDrawable,如下:
.setProgressBarImage(new ProgressBarDrawable())
GenericDraweeHierarchyBuilder builder = new GenericDraweeHierarchyBuilder(getResources());
GenericDraweeHierarchy genericDraweeHierarchy = builder.setProgressBarImage(new ProgressBarDrawable()).build();
GenericDraweeHierarchyBuilder builder_res = new GenericDraweeHierarchyBuilder(getResources());
GenericDraweeHierarchy genericDraweeHierarchy_res = builder_res.setProgressBarImage(new ProgressBarDrawable()).build();
draweeView_url.setHierarchy(genericDraweeHierarchy);
draweeView_res.setHierarchy(genericDraweeHierarchy_res);
设置缓存:
/**
* Created by XUE on 2015/12/30.
*/
public class BaseApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
ImagePipelineConfig config = ImagePipelineConfig.newBuilder(this)
.setBitmapMemoryCacheParamsSupplier(new Supplier<MemoryCacheParams>() {
@Override
public MemoryCacheParams get() {
return new MemoryCacheParams(20<<20,
100,
Integer.MAX_VALUE,
Integer.MAX_VALUE,
Integer.MAX_VALUE
);
}
}).setMainDiskCacheConfig(DiskCacheConfig.newBuilder()
.setMaxCacheSize(50<<20)
.setBaseDirectoryPath(getCacheDir())
.setBaseDirectoryName("fresco")
.build())
.setBitmapsConfig(Bitmap.Config.RGB_565)
.build();
Fresco.initialize(this);
}
}
引入Fresco
1. Android Studio 或者 Gradle
dependencies { compile 'com.facebook.fresco:fresco:0.6.0+'}
开始使用 Fresco
如果你仅仅是想简单下载一张网络图片,在下载完成之前,显示一张占位图,那么简单使用SimpleDraweeView即可。
为了下载网络图片,请确保在AndroidManifest.xml
中有以下权限:
<uses-permission android:name="android.permission.INTERNET"/>
在 Application 初始化时,在应用调用setContentView()
之前,进行初始化:(这里需要自己自定义Application,然后在清单文件中指定)
Fresco.initialize(context);
在xml布局文件中, 加入命名空间:
<!-- 其他元素 --><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:fresco="http://schemas.android.com/apk/res-auto">
加入SimpleDraweeView
:
<com.facebook.drawee.view.SimpleDraweeView android:id="@+id/my_image_view" android:layout_width="20dp" android:layout_height="20dp" fresco:placeholderImage="@drawable/my_drawable" />
开始加载图片
Uri uri = Uri.parse("https://raw.githubusercontent.com/facebook/fresco/gh-pages/static/fresco-logo.png");SimpleDraweeView draweeView = (SimpleDraweeView) findViewById(R.id.my_image_view);draweeView.setImageURI(uri);
剩下的,Fresco会替你完成:
- 显示占位图直到加载完成;
- 下载图片;
- 缓存图片;
- 图片不再显示时,从内存中移除;
关键概念
Drawees
Drawees 负责图片的呈现,包含几个组件,有点像MVC模式。
DraweeView
继承于View, 负责图片的显示。
一般情况下,使用SimpleDraweeView
即可. 简单的用法,在这个页面:开始使用。
它支持很多自定义效果,参见这里:自定义显示效果.
DraweeHierarchy
DraweeHierarchy 用于组织和维护最终绘制和呈现的Drawable对象,相当于MVC中的M。
如果你想在Java代码中自定义图片的展示,可以通过这类实现,具体的请参考这里:在Java代码中自定义显示效果
DraweeController
DraweeController
负责和 image loader 交互(默认是Fresco中 image pipeline),可以创建一个这个类的实例,来实现对所要显示的图片做更多的控制。
DraweeControllerBuilder
DraweeControllers
由DraweeControllerBuilder
采用 Builder 模式创建,创建之后,不可修改。具体参见:使用ControllerBuilder。
Listeners
使用 ControllerListener 的一个场景就是设置一个Listener监听图片的下载。
Image Pipeline
Fresco 的 Image Pipeline 负责图片的获取和管理。图片可以来自远程服务器,本地文件,或者Content Provider,本地资源。压缩后的文件缓存在本地存储中,Bitmap数据缓存在内存中。
在5.0系统以下,Image Pipeline 使用`pinned purgeables*将Bitmap数据避开Java堆内存,存在ashmem中。这要求图片不使用时,要显式地释放内存。
SimpleDraweeView
自动处理了这个释放过程,所以没有特殊情况,尽量使用SimpleDraweeView
,在特殊的场合,如果有需要,也可以直接控制Image Pipeline。
ImageRequest
ImageRequest
存储着Image Pipeline处理被请求图片所需要的有用信息(Uri、是否渐进式图片、是否返回缩略图、缩放、是否自动旋转等。)。
它仅仅用来装信息,而且一经初始化后就无法改变内容(即Immutable,不过可以获取内容)。并且它的初始化只能通过ImageRequest.fromUri(Uri uri)
或ImageRequestBuilder.build()
来实现。
SimpleDraweeView
调用setUri(Uri)
会产生一个默认的ImageRequest
含有指定Uri信息,如果需要修改ImageRequest
其他信息,必须手动创建ImageRequest
,并在PipelineDraweeControllerBuilder
调用.build()
之前使用.setImageRequest
设置它。
支持的URIs
Fresco 支持许多URI格式。
特别注意:Fresco不支持相对路径的URI. 所有的URI都必须是绝对路径,并且带上该URI的scheme。
如下:
类型 | Scheme | 示例 |
---|---|---|
远程图片 | http://, https:// | HttpURLConnection 或者参考使用其他网络加载方案 |
本地文件 | file:// | FileInputStream |
Content provider | content:// | ContentResolver |
asset目录下的资源 | asset:// | AssetManager |
res目录下的资源 | res:// | Resources.openRawResource |
res 示例:
Uri uri = Uri.parse("res://包名(实际可以是任何字符串甚至留空)/" + R.drawable.ic_launcher);
注意,只有图片资源才能使用在Image pipeline中,比如(PNG)。其他资源类型,比如字符串,或者XML Drawable在Image pipeline中没有意义。所以加载的资源不支持这些类型。
像ShapeDrawable这样声明在XML中的drawable可能引起困惑。注意到这毕竟不是图片,如果想把这样的drawable作为图像显示。
那么把这个drawable设置为占位图,然后把URI设置为null。
在XML中使用Drawees
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" 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" />
必须设置layoutwidth和layoutheight
如果没有在XML中声明这两个属性,将无法正确加载图像。
wrap_content
Drawees 不支持wrap_content
属性。
所下载的图像可能和占位图尺寸不一致,如果设置出错图或者重试图的话,这些图的尺寸也可能和所下载的图尺寸不一致。
如果大小不一致,图像下载完之后,假设如果是wrap_content
,View将会重新layout,改变大小和位置。这将会导致界面跳跃。
固定宽高比
只有希望显示的固定宽高比时,可以使用wrap_content
。
如果希望显示的图片保持一定宽高比例,如果 4:3,则在XML中:
<com.facebook.drawee.view.SimpleDraweeView android:id="@+id/my_image_view" android:layout_width="20dp" android:layout_height="wrap_content" <!-- other attributes -->
然后在代码中指定显示比例:
mSimpleDraweeView.setAspectRatio(1.33f);
在JAVA代码中使用Drawees
设置或更改要显示的图片
mSimpleDraweeView.setImageURI(uri);
如果要更加复杂的配置,可使用ControllerBuilder;
自定义显示图
一般情况下,在XML设置显示效果即可, 如果想更多定制化,可以这样:
创建一个 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
。
修改 DraweeHierarchy
DraweeHierarchy 的一些属性可以在运行时改变。
要改变这些属性,首先获取一个引用:
GenericDraweeHierarchy hierarchy = mSimpleDraweeView.getHierarchy();
修改占位图
修改占位图为资源id:
hierarchy.setPlaceholderImage(R.drawable.placeholderId);
或者修改为一个Drawable:
Drawable drawable; // 创建一个drawablehierarchy.setPlaceholderImage(drawable);
修改显示的图像
修改缩放类型:
hierarchy.setActualImageScaleType(ScalingUtils.ScaleType.CENTER_INSIDE);
当然,如果修改为focusCrop,
需要指定一个居中点:
hierarchy.setActualImageFocusPoint(point);
或者设置一个color filter:
ColorFilter filter;// 创建filterhierarchy.setActualImageColorFilter(filter);
圆角
All of therounding related params, except the rounding method, can be modified. You get aRoundingParams
object from the hierarchy, modify it, and set it back again:
除了圆角显示方式(原来为圆角的不能修改为圆圈,反之亦然),其他圆角相关的呈现参数,具体参见这里是可以动态修改的。
如下: 获取DraweeHierarchy的圆角显示参数,修改圆角半径为10。
RoundingParams roundingParams = hierarchy.getRoundingParams();roundingParams.setCornersRadius(10);hierarchy.setRoundingParams(roundingParams);
Drawee的各种效果配置编辑和纠错
内容导航
- 定义
- 设置要加载的图片
- 占位图
- 加载失败时的占位图
- 点击重新加载
- 显示一个进度条
- 背景
- 叠加图
- 按压状态下的叠加图
定义
本页说明如何设置实现不同的图片呈现效果。
除了要加载的图片,其他各个设置都可以在xml中指定。在xml中指定的时候,可以是drawable/下的资源,也可以颜色。
在Java 代码中也可以指定。如果需要通过程序设定的话会接触到这个类:GenericDraweeHierarchyBuilder
通过代码设置是,设置的值可以是资源id,也可以是Drawable的子类。
创建完GenericDraweeHierarchy之后,也可以通过该类的相关方法,重新设置一些效果。
大多数的用户呈现不同效果的drawables都是可以缩放的.
设置要加载的图
除了需要加载的图片是真正必须的,其他的都是可选的。如前所述,图片可以来自多个地方。
所需加载的图片实际是DraweeController的一个属性,而不是DraweeHierarchy的属性。
可使用setImageURI
方法或者通过设置DraweeController来进行设置。
对于要加载的图片,除了可以设置缩放类型外,DraweeHierarchy 还公开出一些其他方法用来控制显示效果:
- focus point (居中焦点, 用于focusCrop缩放模式)
- color filter
默认的缩放类型是:centerCrop
占位图(Placeholder)
在调用setController
或者setImageURI
之后,占位图开始显示,直到图片加载完成。
对于渐进式格式的JPEG图片,占位图会显示直到满足已加载的图片解析度到达设定值。
XML 中属性值:placeholderImage
Hierarchy builder中的方法:setPlaceholderImage
Hierarchy method:setPlaceholderImage
默认值: a transparentColorDrawable
默认缩放类型:centerInside
设置加载失败占位图
如果URI是无效的,或者下载过程中网络不可用,将会导致加载失败。当加载图片出错时,你可以设置一个出错提示图片。
XML 中属性值:failureImage
Hierarchy builder中的方法:setFailureImage
默认值: The placeholder image
默认缩放类型:centerInside
点击重新加载图
在加载失败时,可以设置点击重新加载。这时提供一个图片,加载失败时,会显示这个图片(而不是失败提示图片),提示用户点击重试。
在ControllerBuilder中如下设置:
.setTapToRetryEnabled(true)
加载失败时,image pipeline 会重试四次;如果还是加载失败,则显示加载失败提示图片。
XML 中属性值:retryImage
Hierarchy builder中的方法:setRetryImage
默认值: The placeholder image
默认缩放类型:centerInside
显示一个进度条
如果设置一个进度条图片,提示用户正在加载。该图片会覆盖在 Drawee 上直到图片加载完成。
如果需要自定义,更详细的情况,请参考进度条页面
XML 中属性值:progressBarImage
Hierarchy builder中的方法:setProgressBarImage
默认值: None
默认缩放类型:centerInside
背景
背景图会最先绘制,在XML中只可以指定一个背景图,但是在JAVA代码中,可以指定多个背景图。
当指定一个背景图列表的时候,列表中的第一项会被首先绘制,绘制在最下层,然后依次往上绘制。
背景图片不支持缩放类型,会被强制到Drawee
尺寸大小。
XML 中属性值:backgroundImage
Hierarchy builder中的方法:setBackground,
setBackgrounds
默认值: None
默认缩放类型: N/A
设置叠加图(Overlay)
叠加图会最后被绘制。
和背景图一样,XML中只可以指定一个,如果想指定多个,可以通过JAVA代码实现。
当指定的叠加图是一个列表的时候,列表第一个元素会被先绘制,最后一个元素最后被绘制到最上层。
同样的,不支持各种缩放类型。
XML 中属性值:overlayImage
Hierarchy builder中的方法:setOverlay,
setOverlays
默认值: None
默认缩放类型: N/A
设置按压状态下的叠加图
同样不支持缩放,用户按压DraweeView时呈现。
XML 中属性值:pressedStateOverlayImage
Hierarchy builder中的方法:setPressedStateOverlay
默认值: None
默认缩放类型: N/A
进度条
要显示进度,最简单的办法就是在构建 hierarchy时使用ProgressBarDrawable,如下:
.setProgressBarImage(new ProgressBarDrawable())
这样,在 Drawee 的底部就会有一个深蓝色的矩形进度条。
自定义进度条
如果你想自定义进度条,请注意,如果想精确显示加载进度,需要重写Drawable.onLevelChange:
class CustomProgressBar extends Drawable { @Override protected void onLevelChange(int level) { // level is on a scale of 0-10,000 // where 10,000 means fully downloaded // your app's logic to change the drawable's // appearance here based on progress }}
更多相关文章
- 6.22 android计算字符高度宽度,红蓝3D图片的制作原理及NDK生成实
- 学习笔记-android imageSwitcher使用
- android 拍照图片旋转问题
- Android(安卓)实现图片圆角
- Android简单模糊背景和圆形ImageView
- Android调用相机拍照获取原始照片
- Android中监听ListView滑动到底部
- android > 布局尺寸
- android强制键盘关闭