图片加载和处理的又一个神器 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; 
// 创建一个drawable
hierarchy.setPlaceholderImage(drawable);

修改显示的图像

修改缩放类型:

hierarchy.setActualImageScaleType(ScalingUtils.ScaleType.CENTER_INSIDE);

当然,如果修改为 focusCrop, 需要指定一个居中点:

hierarchy.setActualImageFocusPoint(point);

或者设置一个color filter:

ColorFilter filter;
// 创建filter
hierarchy.setActualImageColorFilter(filter);

圆角

All of the rounding 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 transparent ColorDrawable
默认缩放类型: 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
   }
}

你可能感兴趣的:(android,android,Studio,Fresco,千雅爸爸)