本文来自于Fresco中文文档,这仅仅是自己的学习笔记!!!大牛绕路,放我我。
关于Fresco的介绍,请查看链接
关于android图片缓存,这是一个android程序员必须了解的。关于四大图片缓存框架的特性与对比,请移步MDCC传送门

首先说明,本文的大多数内容来自于官方文档,请勿喷!!!
那么今天我们就来了解下Fresco,作为FB出版的开源项目,据说是目前最好的缓存框架。

那么我们就先来了解下Fresco是个什么。

  • Fresco是一个强大的图片加载组件
  • Fresco中设计有一个叫做image pipeline 的模块。他负责从网络,从本地文件系统,本地资源加载图片。为了最大限度上节省空间和CPU时间,它含有3级缓存的设计(额,没三级能拿出手?)
  • Fresco中设计有一个叫做Drawees模块,方便地显示loading图,当图片不再显示在屏幕上时,及时地释放内存和空间占用。
  • Fresco支持Android2.3及以上系统

简单的看下使用SimpleDraweeView显示一张占位图。在XML文件中加入

<com.facebook.drawee.view.SimpleDraweeView        android:id="@+id/my_image_view"        android:layout_width="200dp"        android:layout_height="200dp"        android:layout_centerInParent="true"        >    </com.facebook.drawee.view.SimpleDraweeView>

在代码中设置Uri,

draweeView = (SimpleDraweeView) findViewById(R.id.my_image_view);        Uri uri = Uri.parse("https://raw.githubusercontent.com/facebook/fresco/gh-pages/static/fresco-logo.png");//        draweeView.setController(draweeController);        draweeView.setImageURI(uri);

最后添加网络权限,就可以了。我们在来看下这里的Uri支持什么格式:

  • 远程图片 http:// 或者 https://
  • 本地文件 file://
  • Content Provider content://
  • asset目录下的资源 asset://
  • res目录下的资源 res://包名/+R……

接下来便详细的介绍Drawee
举个栗子:

<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"  />

上面这个是官方的栗子,上面有所有的属性,我们就来看看,这些属性代表什么意思,

  • layout_width和layout_height 不支持warp_content,但是可以通过setAspectRetio();来设置宽高比
  • fadeDuration() 淡..时间
  • actualImageScaleType 设置图片缩放,通常使用foucsCrop,该属性值会通过算法把人头像放在中间,关于缩放,请移步黑洞
  • placeholderImage 下载成功之前显示的图片
  • placeholderImageScaleType
  • failureImage 加载失败时显示的图片
  • failureImageScaleType
  • retryImage 加载失败,提示用户点击重新加载的图片
  • retryImageScaleType
  • progressBarImage 提示 用户正在加载,和进度无关
  • progressBarImageScaleType
  • progressBarAutoRotateInterval 图片自动旋转的时间间隔
  • backgroundImage 背景
  • overlayImage 叠加图
  • pressedStateOverlayImage 按下时候的叠加图
  • roundAsCircle 是否涉及圆圈
  • roundedCornerRadius 圆角
  • roundTopLeft、roundTopRight….. 分别设置4个角不同半径,设置为true以后可以再代码中设置角度。通过RoundingParams的setConnersRadii()方法
public RoundingParams setCornersRadii(float topLeft, float topRight, float bottomRight, float bottomLeft) {        float[] radii = this.getOrCreateRoundedCornersRadii();        radii[0] = radii[1] = topLeft;        radii[2] = radii[3] = topRight;        radii[4] = radii[5] = bottomRight;        radii[6] = radii[7] = bottomLeft;        return this;    }
  • roundWithOverlayColor,边框的叠加颜色
  • roundingBorderWidth 边框宽度
  • roundingBorderColor 边框颜色

    我们看到,仅仅靠xml文件的属性,功能就已经很强大了。我们通过什么来在代码中设置各种效果呢?看代码

GenericDraweeHierarchyBuilder builder =    new GenericDraweeHierarchyBuilder(getResources());GenericDraweeHierarchy hierarchy = builder    .setFadeDuration(300)    .setPlaceholderImage(new MyCustomDrawable())    .setBackgrounds(backgroundList)    .setOverlays(overlaysList)    .build();mSimpleDraweeView.setHierarchy(hierarchy);

DraweeHierarchy的一些属性可以在运行时改变。

GenericDraweeHierarchy hierarchy =mSimpleDraweeView.getHierarchy();hierarchy.setPlaceholderImage(R.drawable.placeholderId);

注意:对于同一个View,不要多次调用setHierarchy。

我们看看GenericDraweeHierarchy提供了哪些set方法

看到这里有相当多的drawable啊。我们在来看看,Fresco源码中有哪些Drawable,

我们在set…(new ..Drawable),就可以轻松使用了。我们以ProgressBarDrawable为例,看看他提供了哪些方法。
,看起来还是很强大的。当然,我们可以自定义Drawable,关于自定义Drawable,我这里就不再说了,网上还是很多的。

我们在来看看ControllerBuilder,从字面上就可以看出,这个可以对图片做出一些控制。

ControllerListener listener = new BaseControllerListener() {...}DraweeController controller = Fresco.newDraweeControllerBuilder()    .setUri(uri)    .setTapToRetryEnabled(true)    .setOldController(mSimpleDraweeView.getController())    .setControllerListener(listener)    .build();mSimpleDraweeView.setController(controller);

在指定一个新的controller的时候,使用setOldController,可以节省不必要的内存分配。
我们来看看Fresco.newDraweeControllerBuilder()有哪些set方法。

自定义图片加载请求

Uri uri;Postprocessor myPostprocessor = new Postprocessor() { ... }ImageRequest request = ImageRequestBuilder.newBuilderWithSource(uri)    .setPostprocessor(myPostprocessor)    .build();DraweeController controller = Fresco.newDraweeControllerBuilder()    .setImageRequest(request)    .setOldController(mSimpleDraweeView.getController())    // 其他设置    .build();

渐进式JPEG图

ProgressiveJpegConfig pjpegConfig = new ProgressiveJpegConfig() {  @Override  public int getNextScanNumberToDecode(int scanNumber) {    return scanNumber + 2;  }      public QualityInfo getQualityInfo(int scanNumber) {    boolean isGoodEnough = (scanNumber >= 5);    return ImmutableQualityInfo.of(scanNumber, isGoodEnough, false);  }}ImagePipelineConfig config = ImagePipelineConfig.newBuilder()    .setProgressiveJpegConfig(pjpeg)    .build();
Uri uri;ImageRequest request = ImageRequestBuilder    .newBuilderWithSource(uri)    .setProgressiveRenderingEnabled(true)    .build();PipelineDraweeController controller = Fresco.newControllerBuilder()    .setImageRequest(requests)    .setOldController(mSimpleDraweeView.getController())    .build();mSimpleDraweeView.setController(controller);

Gif动态图

Uri uri;ImageRequest request = ImageRequestBuilder.newBuilderWithSource(uri)    . // other setters    .build();DraweeController controller = Fresco.newDraweeControllerBuilder()    .setImageRequest(request)    .setAutoPlayAnimations(true)    . // other setters    .build();mSimpleDraweeView.setController(controller);

手动控制动态图播放

ControllerListener controllerListener = new BaseControllerListener<ImageInfo>() {    @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);

使用动画

Animatable animation = mSimpleDraweeView.getController().getAnimatable();if (animation != null) {  // 开始播放  animation.start();  // 一段时间之后,根据业务逻辑,停止播放  animation.stop();}

多图请求以及图片复用

Uri lowResUri, highResUri;DraweeController controller = Fresco.newDraweeControllerBuilder()    .setLowResImageRequest(ImageRequest.fromUri(lowResUri))    .setImageRequest(ImageRequest.fromUri(highResUri))    .setOldController(mSimpleDraweeView.getController())    .build();mSimpleDraweeView.setController(controller);

缩略图预览

Uri uri;ImageRequest request = ImageRequestBuilder.newBuilderWithSource(uri)    .setLocalThumbnailPreviewsEnabled(true)    .build();DraweeController controller = Fresco.newDraweeControllerBuilder()    .setImageRequest(request)    .setOldController(mSimpleDraweeView.getController())    .build();mSimpleDraweeView.setController(controller);

本地图片复用

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

监听下载事件

ControllerListener controllerListener = new BaseControllerListener<ImageInfo>() {    @Override    public void onFinalImageSet(        String id,        @Nullable ImageInfo imageInfo,        @Nullable Animatable anim) {      if (imageInfo == null) {        return;      }      QualityInfo qualityInfo = imageInfo.getQualityInfo();      FLog.d("Final image received! " +           "Size %d x %d",          "Quality level %d, good enough: %s, full quality: %s",          imageInfo.getWidth(),          imageInfo.getHeight(),          qualityInfo.getQuality(),          qualityInfo.isOfGoodEnoughQuality(),          qualityInfo.isOfFullQuality());    }    @Override     public void onIntermediateImageSet(String id, @Nullable ImageInfo imageInfo) {      FLog.d("Intermediate image received");    }    @Override    public void onFailure(String id, Throwable throwable) {      FLog.e(getClass(), throwable, "Error loading %s", id)    }};Uri uri;DraweeController controller = Fresco.newControllerBuilder()    .setControllerListener(controllerListener)    .setUri(uri);    // other setters    .build();mSimpleDraweeView.setController(controller);

修改图片尺寸

Uri uri = "file:///mnt/sdcard/MyApp/myfile.jpg";int width = 50, height = 50;ImageRequest request = ImageRequestBuilder.newBuilderWithSource(uri)    .setResizeOptions(new ResizeOptions(width, height))    .build();PipelineDraweeController controller = Fresco.newDraweeControllerBuilder()    .setOldController(mDraweeView.getController())    .setImageRequest(request)    .build();mSimpleDraweeView.setController(controller);

自动旋转

ImageRequest request = ImageRequestBuilder.newBuilderWithSource(uri)    .setAutoRotateEnabled(true)    .build();

图片的修改。后处理器

Uri uri;Postprocessor redMeshPostprocessor = new BasePostprocessor() {   @Override  public String getName() {    return "redMeshPostprocessor";  }  @Override  public void process(Bitmap bitmap) {    for (int x = 0; x < bitmap.getWidth(); x+=2) {      for (int y = 0; y < bitmap.getHeight(); y+=2) {        bitmap.setPixel(x, y, Color.RED);      }    }  }}ImageRequest request = ImageRequestBuilder.newBuilderWithSource(uri)    .setPostprocessor(redMeshPostprocessor)    .build();PipelineDraweeController controller = (PipelineDraweeController)     Fresco.newDraweeControllerBuilder()    .setImageRequest(request)    .setOldController(mSimpleDraweeView.getController())    // other setters as you need    .build();mSimpleDraweeView.setController(controller);

图片请求 Image Requests

Uri uri;ImageDecodeOptions decodeOptions = ImageDecodeOptions.newBuilder()    .setBackgroundColor(Color.GREEN)    .build();ImageRequest request = ImageRequestBuilder    .newBuilderWithSource(uri)    .setAutoRotateEnabled(true)    .setLocalThumbnailPreviewsEnabled(true)    .setLowestPermittedRequestLevel(RequestLevel.FULL_FETCH)    .setProgressiveRenderingEnabled(false)    .setResizeOptions(new ResizeOptions(width, height))    .build();

上面我们说了Deawee,下面我们说下Image Pipeline

配置代码

ImagePipelineConfig config = ImagePipelineConfig.newBuilder()    .setBitmapMemoryCacheParamsSupplier(bitmapCacheParamsSupplier)    .setCacheKeyFactory(cacheKeyFactory)    .setEncodedMemoryCacheParamsSupplier(encodedCacheParamsSupplier)    .setExecutorSupplier(executorSupplier)    .setImageCacheStatsTracker(imageCacheStatsTracker)    .setMainDiskCacheConfig(mainDiskCacheConfig)    .setMemoryTrimmableRegistry(memoryTrimmableRegistry)     .setNetworkFetchProducer(networkFetchProducer)    .setPoolFactory(poolFactory)    .setProgressiveJpegConfig(progressiveJpegConfig)    .setRequestListeners(requestListeners)    .setSmallImageDiskCacheConfig(smallImageDiskCacheConfig)    .build();Fresco.initialize(context, config);

是在是太多了,我也懒的写了。

参考资料:中文文档

更多相关文章

  1. android debug set screen rotation
  2. Android(安卓)UI之ImageView
  3. android自定义ListView背景
  4. Android样式开发之selector
  5. 说说Android(安卓)两种为自定义组件添加属性的使用方法和区别
  6. 安卓ListView 数据分批加载
  7. 调用手机的摄像头,并且返回照片显示在程序界面上.
  8. httpClient及android 原生接口实现下载并显示图片
  9. android vr全景图片初探(仿微博360全景图片的实现)

随机推荐

  1. smartwindow
  2. Android(安卓)判断程序是否在前台运行
  3. android之ArrayAdaper应用
  4. Android(安卓)PendingIntent的Flag设置
  5. android环境搭建
  6. android lk机制介绍
  7. android 图片按照动画不停移动
  8. MySQL InnoDB中的锁机制深入讲解
  9. mysql命令行爱好者必备工具mycli
  10. MySQL用户和权限及破解root口令的方法示