上篇中的美团app弹窗,图片的加载使用的是SimpleDraweeView,可以根据URI来加载图片。这个控件就是来自于图片加载开源框架Fresco,其中文官网为https://www.fresco-cn.org/。本篇总结一下SimpleDraweeView的基本使用(基于Android Studio)
1. 环境配置
build.gradle 中配置 dependencies 再同步一下,下载依赖包
compile 'com.facebook.fresco:fresco:1.5.0'
2. Fresco 的初始化
官网提供的初始化是在Application中, 原因是为了避免内存泄漏,因为使用到了Context,如果在Activity中使用其Context,可能造成Activity回收不掉.
源码解释如下:
Fresco,java - initialize() 方法中介绍
// we should always use the application context to avoid memory leaks context = context.getApplicationContext();
so 创建方法就有两种了
(1) 自定义MyApplication
public class MyApplication extends Application { @Override public void onCreate() { super.onCreate(); Fresco.initialize(this); } }
记得在AndroidManifest.xml 中重新定义下全局的Application
android:name=".MyApplication"
(2) 在Activity 中使用getApplicationContext
Fresco.initialize(getApplicationContext());
ps: 只需要初始化一次,多次初始化是没有意义的
3. SimpleDraweeView 的xml 使用,以及各属性的意义
在布局文件中使用
<com.facebook.drawee.view.SimpleDraweeView android:id="@+id/my_image_view" android:layout_width="100dp" android:layout_height="100dp" android:clickable="true" fresco:placeholderImage="@drawable/simple" 占位符图片 加载的图片出来之前消失 fresco:placeholderImageScaleType="fitCenter" 占位符图片的缩放类型 fresco:progressBarImage="@drawable/load" 正在加载时的图片 fresco:progressBarImageScaleType="centerInside" 正在加载时图片的缩放类型 fresco:progressBarAutoRotateInterval="5000" 正在加载时图片的旋转时间,如果网速很好,则显示时间短 fresco:failureImage="@drawable/faile" 加载失败后显示的图片 fresco:failureImageScaleType="centerInside" 加载失败显示图片的缩放类型 fresco:fadeDuration="5000" 淡入淡出的时间 fresco:retryImage="@drawable/restart" 重新加载时图片 fresco:retryImageScaleType="centerInside" 重新加载时图片的缩放类型 fresco:background="@drawable/ic_launcher" 背景图片 fresco:pressedStateOverlayImage="@android:color/holo_green_dark" 点击SimpleDraweeView时,显示的图片 fresco:overlayImage="@drawable/ic_launcher" 覆盖在上层的图片 fresco:roundAsCircle="true" 圆形图 fresco:roundedCornerRadius="30dp" 圆角半径 fresco:roundTopLeft="true" 左上角是否圆角 以下类推 fresco:roundTopRight="true" fresco:roundBottomLeft="true" fresco:roundBottomRight="true" fresco:roundingBorderWidth="10dp" 边框宽度 fresco:roundingBorderColor="@android:color/black" 边框颜色 fresco:roundWithOverlayColor="@color/colorAccent" 设置圆形圆角后,被减去部分的背景色 />
4. 注意点
(1) 必须给SimpleDraweeView 设置一个宽高,wrap_content 不支持,否则图片显示不出
(2) fresco 在使用其属性时,需在根布局下面添加,否则引用不到属性
xmlns:fresco="http://schemas.android.com/apk/res-auto"
(3) 使用pressedStateOverlayImage 时,我在使用时发现点击了SimpleDraweeView没有效果,原因是当前控件要是可点的,so 添加了下面参数即可
android:clickable="true"(4) retryImage 使用时,发现没效果,那是因在java代码中需要设置一下setTapToRetryEnabled
DraweeController draweeController = (DraweeController) Fresco.newDraweeControllerBuilder() .setUri(Uri.parse("http://img3.redocn.com/tupian/20150312/haixinghezhenzhubeikeshiliangbeijing_3937174.jpg")) //需要加载图片的uri .setTapToRetryEnabled(true) //设置点击重试是否开启 .setOldController(simpleDraweeView.getController()).build();
simpleDraweeView.setController(draweeController);
5. 代码中设置属性
代码中动态设置属性,使用的是GenericDraweeHierarchy 参数就不填了。 其中设置圆形圆角的使用的是RoundingParams,在将参数设置到GenericDraweeHierarchy 中
RoundingParams roundingParams = new RoundingParams(); roundingParams.setRoundAsCircle() .setCornersRadius() .setCornersRadii() // 置圆角时,支持4个角不同的半径。XML中无法配置,但可在Java代码中配置。 .setBorderColor() .setBorderWidth(); GenericDraweeHierarchyBuilder builder = new GenericDraweeHierarchyBuilder(getResources()); GenericDraweeHierarchy hierarchy = builder .setPlaceholderImage() .setPlaceholderImageScaleType() .setProgressBarImage() .setProgressBarImageScaleType() .setFailureImage() .setFailureImageScaleType() .setFadeDuration() .setRetryImage() .setRetryImageScaleType() .setBackground() .setPressedStateOverlay() .setOverlay() .setRoundingParams(roundingParams) .build(); simpleDraweeView.setHierarchy(hierarchy);
ps:对于同一个View,请不要多次调用setHierarchy,即使这个View是可回收的。创建 DraweeHierarchy 的较为耗时的一个过程,应该多次利用。
一个DraweeHierarchy 是不可以被多个 View 共用的!
那么如何多次使用呢,通过获得当前SimpleDraweeView的GenericDraweeHierarchy 对象,进行重新设置
simpleDraweeView.getHierarchy().setFailureImage();
simpleDraweeView.getHierarchy().getRoundingParams(); //获得圆形设置,再重新设置参数并传入GenericDraweeHierarchy中
6. java代码中访问图片
通过findViewById 获得SimpleDraweeView对象
(1) 普通使用
simpleDraweeView.setImageURI(Uri.parse("http://img3.redocn.com/tupian/20150312/haixinghezhenzhubeikeshiliangbeijing_3937174.jpg"));
(2) 使用DraweeController
DraweeController draweeController = (DraweeController) Fresco.newDraweeControllerBuilder() .setUri(Uri.parse("http://img3.redocn.com/tupian/20150312/haixinghezhenzhubeikeshiliangbeijing_3937174.jpg")) //需要加载图片的uri .setTapToRetryEnabled(true) //设置点击重试是否开启 .setOldController(simpleDraweeView.getController()).build();
simpleDraweeView.setController(draweeController);
(3) ImageRequest
ImageRequest imageRequest = ImageRequestBuilder.newBuilderWithSource(Uri.parse( "http://img3.redocn.com/tupian/20150312/haixinghezhenzhubeikeshiliangbeijing_3937174.jpg")).build(); DraweeController draweeController = (DraweeController) Fresco.newDraweeControllerBuilder() // .setUri(Uri.parse("http://img3.redocn.com/tupian/20150312/haixinghezhenzhubeikeshiliangbeijing_3937174.jpg")) //需要加载图片的uri .setTapToRetryEnabled(true) //设置点击重试是否开启 .setControllerListener(controllerListener) .setImageRequest(imageRequest) //将对象传入setImageRequest 中 .setOldController(simpleDraweeView.getController()).build(); simpleDraweeView.setController(draweeController);