上次说了Fresco的基本使用方式
这次来说说,Fresco的更多使用
实际图片,占位图,重试图和失败图都可以在 xml 中进行设置,用 fresco:actualImageScaleType 这样的属性。你也可以使用 GenericDraweeHierarchyBuilder 类在代码中进行设置。
其中可用的缩放类型如下
center 居中,无缩放。
centerCrop 保持宽高比缩小或放大,使得两边都大于或等于显示边界,且宽或高契合显示边界。居中显示。
focusCrop 同centerCrop, 但居中点不是中点,而是指定的某个点。
centerInside 缩放图片使两边都在显示边界内,居中显示。和 fitCenter 不同,不会对图片进行放大。
如果图尺寸大于显示边界,则保持长宽比缩小图片。
fitCenter 保持宽高比,缩小或者放大,使得图片完全显示在显示边界内,且宽或高契合显示边界。居中显示。
fitStart 同上。但不居中,和显示边界左上对齐。
fitEnd 同fitCenter, 但不居中,和显示边界右下对齐。
fitXY 不保存宽高比,填充满显示边界。
none 如要使用tile mode显示, 需要设置为``
one
其中focusCrop,只要提供一个居中聚焦点,显示时就会尽量以此点为中心。
居中点是以相对方式给出的,比如 (0f, 0f) 是左上对齐显示,(1f, 1f) 是右下角对齐。相对坐标使得居中点位置和具体尺寸无关,这是非常实用的。
(0.5f, 0.5f) 的居中点位置和缩放类型 centerCrop 是等价的。
如果要使用此缩放模式,首先在 XML 中指定缩放模式:
fresco:actualImageScaleType="focusCrop"
在Java代码中,给你的图片指定居中点:
PointF focusPoint;
// your app populates the focus point
mSimpleDraweeView
.getHierarchy()
.setActualImageFocusPoint(focusPoint);
圆角实际有2种呈现方式:
1.圆圈 - 设置roundAsCircle为true
2.圆角 - 设置roundedCornerRadius
可使用以下两种方式:
1.默认使用一个 shader 绘制圆角,但是仅仅占位图和所要显示的图有圆角效果。失败示意图和重下载示意图无圆角效果,且这种圆角方式不支持动画。
2.叠加一个solid color来绘制圆角。但是背景需要固定成指定的颜色。 在XML中指定 roundWithOverlayColor, 或者通过调用setOverlayColor来完成此设定。
SimpleDraweeView 支持如下几种圆角配置:
...
fresco:roundedCornerRadius="5dp"
fresco:roundBottomLeft="false"
fresco:roundBottomRight="false"
fresco:roundWithOverlayColor="@color/blue"
fresco:roundingBorderWidth="1dp"
fresco:roundingBorderColor="@color/red"
在创建 DraweeHierarchy 时,可以给 GenericDraweeHierarchyBuilder 指定一个RoundingParams 用来绘制圆角效果。
RoundingParams roundingParams = RoundingParams.fromCornersRadius(7f);
roundingParams.setOverlayColor(R.color.green);
// 或用 fromCornersRadii 以及 asCircle 方法
genericDraweeHierarchyBuilder
.setRoundingParams(roundingParams);
你也可以在运行时,改变圆角效果
RoundingParams roundingParams =
mSimpleDraweeView.getHierarchy().getRoundingParams();
roundingParams.setBorder(R.color.red, 1.0);
roundingParams.setRoundAsCircle(true);
mSimpleDraweeView.getHierarchy().setRoundingParams(roundingParams);
当使用BITMAP_ONLY(默认)模式时的限制:
• 并非所有的图片分支部分都可以实现圆角,目前只有占位图片和实际图片可以实现圆角,我们正在努力为背景图片实现圆角功能。
• 只有BitmapDrawable 和 ColorDrawable类的图片可以实现圆角。我们目前不支持包括NinePatchDrawable和 ShapeDrawable在内的其他类型图片。(无论他们是在XML或是程序中声明的)
• 动画不能被圆角。
• 由于Android的BitmapShader的限制,当一个图片不能覆盖全部的View的时候,边缘部分会被重复显示,而非留白。对这种情况可以使用不同的缩放类型(比如centerCrop)来保证图片覆盖了全部的View。
OVERLAY_COLOR模式没有上述限制,但由于这个模式使用在图片上覆盖一个纯色图层的方式来模拟圆角效果,因此只有在图标背景是静止的并且与图层同色的情况下才能获得较好的效果。
Fresco 支持 GIF 和 WebP 格式的动画图片。对于 WebP 格式的动画图的支持包括扩展的 WebP 格式,即使 Android 2.3及其以后那些没有原生 WebP 支持的系统。
如果你希望图片下载完之后自动播放,同时,当View从屏幕移除时,停止播放,只需要在 image request 中简单设置,如下:
Uri uri;
DraweeController controller = Fresco.newDraweeControllerBuilder()
.setUri(uri)
.setAutoPlayAnimations(true)
. // other setters
.build();
mSimpleDraweeView.setController(controller);
也许你希望在代码中直接控制动画的播放。这种情况下,你需要监听图片是否加载完毕,然后才能控制动画的播放:
ControllerListener controllerListener = new BaseControllerListener() {
@Override
public void onFinalImageSet(
String id,
@Nullable ImageInfo imageInfo,
@Nullable Animatable anim) {
if (anim != null) {
// app-specific logic to enable animation starting
anim.start();
}
};
Uri uri;
DraweeController controller = Fresco.newDraweeControllerBuilder()
.setUri(uri)
.setControllerListener(controllerListener)
// other setters
.build();
mSimpleDraweeView.setController(controller);
另外,controller提供对Animatable 的访问。
如果有可用动画的话,可对动画进行灵活的控制:
Animatable animation = mSimpleDraweeView.getController().getAnimatable();
if (animation != null) {
// 开始播放
animation.start();
// 一段时间之后,根据业务逻辑,停止播放
animation.stop();
}
多图请求需 自定义ImageRequest.
假设你要显示一张高分辨率的图,但是这张图下载比较耗时。与其一直显示占位图,你可能想要先下载一个较小的缩略图。
这时,你可以设置两个图片的URI,一个是低分辨率的缩略图,一个是高分辨率的图。
Uri lowResUri, highResUri;
DraweeController controller = Fresco.newDraweeControllerBuilder()
.setLowResImageRequest(ImageRequest.fromUri(lowResUri))
.setImageRequest(ImageRequest.fromUri(highResUri))
.setOldController(mSimpleDraweeView.getController())
.build();
mSimpleDraweeView.setController(controller);
本功能仅支持本地URI,并且是JPEG图片格式
如果本地JPEG图,有EXIF的缩略图,image pipeline 可以立刻返回它作为一个缩略图。Drawee 会先显示缩略图,完整的清晰大图在 decode 完之后再显示。
Uri uri;
ImageRequest request = ImageRequestBuilder.newBuilderWithSource(uri)
.setLocalThumbnailPreviewsEnabled(true)
.build();
DraweeController controller = Fresco.newDraweeControllerBuilder()
.setImageRequest(request)
.setOldController(mSimpleDraweeView.getController())
.build();
mSimpleDraweeView.setController(controller);
大部分时候,一张图片只有一个 URI。加载它,然后工作完成~
但是假设同一张图片有多个 URI 的情况。比如,你可能上传过一张拍摄的照片。原始图片太大而不能上传,所以图片首先经过了压缩。在这种情况下,首先尝试获取本地压缩后的图片 URI,如果失败的话,尝试获取本地原始图片 URI,如果还是失败的话,尝试获取上传到网络的图片 URI。直接下载我们本地可能已经有了的图片不是一件光彩的事。
Image pipeline 会首先从内存中搜寻图片,然后是磁盘缓存,再然后是网络或其他来源。对于多张图片,不是一张一张按上面的过程去做,而是 pipeline 先检查所有图片是否在内存。只有没在内存被搜寻到的才会寻找磁盘缓存。还没有被搜寻到的,才会进行一个外部请求。
使用时,创建一个image request 数组,然后传给 ControllerBuilder :
Uri uri1, uri2;
ImageRequest request = ImageRequest.fromUri(uri1);
ImageRequest request2 = ImageRequest.fromUri(uri2);
ImageRequest[] requests = { request1, request2 };
DraweeController controller = Fresco.newDraweeControllerBuilder()
.setFirstAvailableImageRequests(requests)
.setOldController(mSimpleDraweeView.getController())
.build();
mSimpleDraweeView.setController(controller);
这些请求中只有一个会被展示。第一个被发现的,无论是在内存,磁盘或者网络,都会是被返回的那个。pipeline 认为数组中请求的顺序即为优先顺序。
ImagePipeline现有函数可以删除缓存中的一条url。
ImagePipeline imagePipeline = Fresco.getImagePipeline();
Uri uri;
imagePipeline.evictFromMemoryCache(uri);
imagePipeline.evictFromDiskCache(uri);
// combines above two lines
imagePipeline.evictFromCache(uri);
如同上面一样,evictFromDiskCache(Uri)假定你使用的是默认的CacheKeyFactory。如果你自定义,请使用evictFromDiskCache(ImageRequest)。
ImagePipeline imagePipeline = Fresco.getImagePipeline();
imagePipeline.clearMemoryCaches();
imagePipeline.clearDiskCaches();
// combines above two lines
imagePipeline.clearCaches();
更多详情请参考官网:http://www.fresco-cn.org/