Android图片加载框架Fresco解析

来源:互联网 发布:tensorflow 下载安装 编辑:程序博客网 时间:2024/06/11 07:10

Android图片加载框架Fresco解析

标签(空格分隔): Android 框架 图片


与ImageLoader不同,Facebook的开源框架的加载方式决定了,更低的内存使用,更高的可定制性。


Fresco原理

设计一个Image Pipeline的概念,负责先检查内存,磁盘文件,如果都不存在则从给的Url中下载。
Fresco有三个线程池,其中,三个线程用于网络下载图片,2个线程用于磁盘文件的读写,还有两个线程负责CPU相关操作(解码,转换)等。


Drawees模块
它会在图片加载完成前显示占位图,加载成功后自动替换为目标图片。当图片不再显示在屏幕上时,它会及时地释放内存和空间占用。
- 自定义居中焦点
- 圆角图
- 下载失败后,点击重新下载
- 自定义占位图
- 自定义overlay
- 自定义进度条
- 指定用户按压时的overlay


Fresco的Image Pipeline允许你用很多种方式来自定义图片加载过程,比如:

  • 可以先显示一个低清晰度的图片,等下载完之后再显示高清图
  • 加载完成后回调通知
  • 本地图,如果有EXIF缩略图,则先显示缩略图,图片加载完成后再显示大图
  • 支持缩放和旋转图片
  • 可以对已下载的图片再次处理
  • 支持WebP解码,即使在对WebPage支持不完善的Android系统上也能使用。

JPEG格式的渐进式呈现
Android 本身的图片库不支持此格式,但是Fresco支持。使用时,和往常一样,仅仅需要提供一个图片的URI即可,剩下的事情,Fresco会处理。


动图加载
加载Gif图和WebP动图在任何一个Android开发者眼里看来都是一件非常头疼的事情。每一帧都是一张很大的Bitmap,每一个动画都有很多帧。Fresco让你没有这些烦恼,它处理好每一帧并管理好你的内存。


如何使用

导入库

dependencies { compile 'com.squareup.picasso:picasso:2.5.2'}  

初始化
在Application级别初始化Fresco

public class TestApplication extends Application {    @Override    public void onCreate() {        super.onCreate();        Fresco.initialize(this);    }}

Layout中添加命名空间

xmlns:fresco="http://schemas.android.com/apk/res-auto"

不添加命名空间则可以

Uri uri = Uri.parse(uri);imageView.setImageURI(uri);

常用属性

<com.facebook.drawee.view.SimpleDraweeView        android:id="@+id/image_view"        android:layout_width="300dp"        android:layout_height="300dp"        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" // 重试,可重复四次,而后是failureImage        fresco:retryImageScaleType="centerCrop" // 缩放        fresco:progressBarImage="@drawable/progress_bar" // 进度条图片        fresco:progressBarImageScaleType="centerInside"        fresco:progressBarAutoRotateInterval="1000"        fresco:backgroundImage="@color/blue" // 首先被绘制的背景图        fresco:overlayImage="@drawable/watermark" // 叠加图,xml中只能设置一张。代码可设置        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"        />

开始加载图片

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);

动态更改

setController(controller)方法加载图片

DraweeController controller = Fresco                .newDraweeControllerBuilder()                .setUri(uri).build();        imageView.setController(controller);

监听加载过程ControllerListener

                ControllerListener listener = new ControllerListener() {            /**             * Called before the image request is submitted.             * <p> IMPORTANT: It is not safe to reuse the controller from within this callback!             *             * @param id            controller id             * @param callerContext caller context             */            @Override            public void onSubmit(String id, Object callerContext) {                // 在图片加载之前调用            }            /**             * Called after the final image has been set.             *             * @param id         controller id             * @param imageInfo  image info             * @param animatable             */            @Override            public void onFinalImageSet(String id, Object imageInfo, Animatable animatable) {                // 加载成功之后            }            /**             * Called after any intermediate image has been set.             *             * @param id        controller id             * @param imageInfo image info             */            @Override            public void onIntermediateImageSet(String id, Object imageInfo) {                // 渐进式加载完成后            }            /**             * Called after the fetch of the intermediate image failed.             *             * @param id        controller id             * @param throwable failure cause             */            @Override            public void onIntermediateImageFailed(String id, Throwable throwable) {                // 渐进加载失败            }            /**             * Called after the fetch of the final image failed.             *             * @param id        controller id             * @param throwable failure cause             */            @Override            public void onFailure(String id, Throwable throwable) {                // 加载失败            }            /**             * Called after the controller released the fetched image.             * <p> IMPORTANT: It is not safe to reuse the controller from within this callback!             *             * @param id controller id             */            @Override            public void onRelease(String id) {                // 释放资源后的操作            }        };

还有一个更简化的接口调用,为单例模式,默认的ControllerListener

ControllerListener controllerListener = BaseControllerListener.getNoOpListener();

如何使用ControllerListener

DraweeController controller = Fresco.newDraweeControllerBuilder()                .setUri(uri)                .setControllerListener(listener)                .build();        imageView.setController(controller);

动态生成,重复利用GenericDraweeHierarchy动态设置

GenericDraweeHierarchy hierarchy = new GenericDraweeHierarchyBuilder(getResources())                .setFadeDuration(300)                .setBackground(getDrawable(R.drawable.ic_launcher))                .setPlaceholderImage(getDrawable(R.drawable.ic_launcher))                .setFailureImage(getDrawable(R.drawable.ic_launcher))                .build();        imageView.setHierarchy(hierarchy);

复用GenericDraweeHierarchy

GenericDraweeHierarchy hierarchy1 = imageView.getHierarchy();

JPEG渐进式网络加载
渐进式加载是由模糊到清晰的渐进过程,在网络条件不好的时候,渐进式加载能提高用户体验。
渐进式加载也是可以控制的,下面是接口

public interface ProgressiveJpegConfig {  /**   * Gets the next scan-number that should be decoded after the given scan-number.   */  int getNextScanNumberToDecode(int scanNumber);  /**   * Gets the quality information for the given scan-number.   */  QualityInfo getQualityInfo(int scanNumber);}

Fresco提供了简单的控制方式的范例

ProgressiveJpegConfig progressiveJpegConfig = new SimpleProgressiveJpegConfig(list, 2);

Fresco是非常全面而且强大的图片加载框架,可以通过阅读源代码进一步了解他的设计以及使用。


Fresco中文介绍
Github地址

0 0
原创粉丝点击