使用原因
最近工作需要在4.4的开发板上开发软件,并且需要展示大量的图片.
平时一直使用的图片加载框架是Picasso,但是Fresco在4.4以下使用的黑科技让人不得不心动.
Fresco在android4.4以下版本时,图片使用的内存空间是在匿名类的内存空间,极大的减少内存空间占用,从而可以让你摆脱99%由于图片造成的OOM,真乃神器(外挂)也~~
作用:
显示占位图直到加载完成;
下载图片
缓存图片
图片不再显示时,从内存中移除;
导包
compile 'com.facebook.fresco:fresco:0.12.0'
按需求添加:
compile 'com.facebook.fresco:animated-base-support:0.12.0'
compile 'com.facebook.fresco:animated-gif:0.12.0'
compile 'com.facebook.fresco:animated-webp:0.12.0'
compile 'com.facebook.fresco:webpsupport:0.12.0'
compile 'com.facebook.fresco:webpsupport:0.12.0'
基本使用
.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:fresco="http://schemas.android.com/apk/res-auto" //添加fresco的命名空间
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.junx.fresco.MainActivity">
<com.facebook.drawee.view.SimpleDraweeView
android:id="@+id/my_image_view"
android:layout_width="300dp" //不支持wrap_content
android:layout_height="wrap_content"//但可以配合fresco:viewAspectRatio属性
fresco:viewAspectRatio="1.33"
fresco:placeholderImage="@mipmap/ic_launcher_round"
android:layout_marginRight="8dp"
app:layout_constraintRight_toRightOf="parent" android:layout_marginLeft="8dp"
app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginBottom="8dp" app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="8dp"/>
.support.constraint.ConstraintLayout>
iv = (SimpleDraweeView) findViewById(R.id.my_image_view);
/*远程图片 http:
本地文件 file:
Content provider content:
asset目录下的资源 asset:
res目录下的资源 res:
Uri中指定图片数据 data:mime/type;base64, 数据类型必须符合 rfc2397规定 (仅支持 UTF-8)
Uri uri = Uri.parse("res://包名(实际可以是任何字符串甚至留空)/" + R.drawable.ic_launcher)
*/
iv.setImageURI(pic_umr);
XML中属性的使用
.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"
/>
代码中设置属性
//动态设置属性,应该在设置uri前进行
private GenericDraweeHierarchy setAttrs() {
//圆角属性,只有BitmapDrawable 和 ColorDrawable类的图片可以实现圆角。
RoundingParams roundingParams = RoundingParams.fromCornersRadius(7f)
roundingParams.setRoundAsCircle(true)
//设置外层的颜色,默认为透明
roundingParams.setOverlayColor(Color.TRANSPARENT)
GenericDraweeHierarchyBuilder builder =new GenericDraweeHierarchyBuilder(getResources())
GenericDraweeHierarchy hierarchy = builder
.setRoundingParams(roundingParams)
//图片缓缓展示出来
.setFadeDuration(3000)
.setPlaceholderImage(R.mipmap.ic_launcher_round)
.setFailureImage(R.mipmap.ic_launcher)
// .setOverlays(overlaysList)
.build()
iv.setHierarchy(hierarchy)
return hierarchy
}
private void changeParams(){
GenericDraweeHierarchy hierarchy = iv.getHierarchy();
hierarchy.setPlaceholderImage(R.mipmap.ic_launcher_round);
hierarchy.setActualImageScaleType(ScalingUtils.ScaleType.CENTER_INSIDE);
hierarchy.setActualImageFocusPoint(new PointF(50,50));
hierarchy.setActualImageColorFilter(new ColorFilter());
RoundingParams roundingParams = hierarchy.getRoundingParams();
roundingParams.setCornersRadius(10);
hierarchy.setRoundingParams(roundingParams);
}
各种效果设置
private void setController() {
ControllerListener listener = new BaseControllerListener(){
@Override
public void onSubmit(String id, Object callerContext) {
super.onSubmit(id, callerContext);
}
@Override
public void onFinalImageSet(String id, Object imageInfo, Animatable animatable) {
super.onFinalImageSet(id, imageInfo, animatable);
Log.v("meee",getClass()+":\n"+"加载成功时触发");
}
@Override
public void onIntermediateImageSet(String id, Object imageInfo) {
super.onIntermediateImageSet(id, imageInfo);
}
@Override
public void onIntermediateImageFailed(String id, Throwable throwable) {
super.onIntermediateImageFailed(id, throwable);
}
@Override
public void onFailure(String id, Throwable throwable) {
super.onFailure(id, throwable);
Log.v("meee",getClass()+":\n"+"失败");
}
@Override
public void onRelease(String id) {
super.onRelease(id);
}
};
DraweeController controller = Fresco.newDraweeControllerBuilder()
.setUri(pic_umr)
.setTapToRetryEnabled(true)
.setOldController(iv.getController())
.setControllerListener(listener)
.build();
iv.setController(controller);
}
先展示一张低分辨率的缩略图,在展开一张高分辨的图
DraweeController controller = Fresco.newDraweeControllerBuilder()
.setUri(pic_umr)
//先展示一张低分辨率的图片
.setLowResImageRequest(ImageRequest.fromUri(pic_umr))
.build()
缩略图预览
仅支持本地uri
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。直接下载我们本地可能已经有了的图片不是一件光彩的事。
Image pipeline 会首先从内存中搜寻图片,然后是磁盘缓存,再然后是网络或其他来源。对于多张图片,不是一张一张按上面的过程去做,而是 pipeline 先检查所有图片是否在内存。只有没在内存被搜寻到的才会寻找磁盘缓存。还没有被搜寻到的,才会进行一个外部请求。
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)
设置按压状态的图
GenericDraweeHierarchy hierarchy = builder
//设置叠加的绘制图,可以是单个,也可以是数组,数组会从第一个开始绘制
// .setOverlays(overlaysList)
// .setOverlay()
//按压状态下展示的图片
.setPressedStateOverlay(getResources().getDrawable(R.mipmap.ic_launcher))
.build()
设置gif自动播放
在这一步卡了很久....为啥?
因为没效果啊,连图片都展示不出来
原因不明...
最后,
换了模拟器发现6.0 4.1 的可以 4.4的不行
也有可能是因为我常用4.4的模拟器,安装了很多软件造成的
更新:
测试完毕,就特么4.4的不行
再次更新:
我用了抓包软件后忘记把ip代理关了
但是比较神奇的是...
普通图片联网就没问题诶
Uri uri = Uri.parse("http://img.huofar.com/data/jiankangrenwu/shizi.gif")
DraweeController controller = Fresco.newDraweeControllerBuilder()
//开启gif效果,如果可以的话
.setAutoPlayAnimations(true)
.build()
iv.setController(controller)
ControllerListener controllerListener = new BaseControllerListener() {
@Override
public void onFinalImageSet(
String id,
@Nullable ImageInfo imageInfo,
@Nullable Animatable anim) {
if (anim != null) {
anim.start();
}
}
};
Uri uri;
DraweeController controller = Fresco.newDraweeControllerBuilder()
.setUri(uri)
.setControllerListener(controllerListener)
.build();
mSimpleDraweeView.setController(controller);
获取本地图片的url
public static String getResUrl(Context context, int id) {
return String.format("res://%s/%d", context.getPackageName(),id);
}