Android 开源框架 ( 十二 ) 图片加载框架---Fresco
Fresco是Facebook推出的一款用于Android应用中展示图片的强大图片库。它具有强大的内存管理、渐进式呈现图片、支持加载Gif图和WebP格式等特点。
相比于其他图片框架要庞大的多,但是对于图片的处理也要比其他框架支持的多。
Fresco官方中文介绍文档:https://www.fresco-cn.org/
Fresco GitHub 地址:https://github.com/facebook/fresco
Fresco使用
1.添加依赖
compile 'com.facebook.fresco:fresco:1.10.0'
其他相关依赖
compile 'com.facebook.fresco:animated-gif:1.5.0'//加载gif动图需添加此库 compile 'com.facebook.fresco:animated-webp:1.5.0'//加载webp动图需添加此库 compile 'com.facebook.fresco:webpsupport:1.5.0'//支持webp需添加此库 compile 'com.facebook.fresco:imagepipeline-okhttp3:1.5.0'//网络实现层使用okhttp3需添加此库 compile 'jp.wasabeef:fresco-processors:2.1.0@aar'//用于提供fresco的各种图片变换
2.图片加载布局控件
必须设置layout_width、layout_height两个属性,否则无法展示。并且注意SimpleDraweeView不支持wrap_content属性。可以参考官方文档:wrap_content的限制 。你必须指定尺寸或者用match_parent
来布局。
<com.facebook.drawee.view.SimpleDraweeView android:id="@+id/sdv_fresco" android:layout_width="130dp" android:layout_gravity="center" android:layout_height="130dp" fresco:placeholderImage="@drawable/atguigu_logo" />
3.常用属性
3.1 带进度条的图片
// 设置样式 GenericDraweeHierarchyBuilder builder = new GenericDraweeHierarchyBuilder(getResources()); GenericDraweeHierarchy hierarchy = builder.setProgressBarImage(new ProgressBarDrawable()).build(); sdvFresco.setHierarchy(hierarchy); // 加载图片的地址 Uri uri = Uri.parse("http://"); // 加载图片 sdvFresco.setImageURI(uri);
3.2 图片的不同裁剪
CENTER
GenericDraweeHierarchyBuilder builder = new GenericDraweeHierarchyBuilder(getResources()); //居中,无缩放 GenericDraweeHierarchy hierarchy = builder.setActualImageScaleType(ScalingUtils.ScaleType.CENTER).build();// 设置样式 sdvFresco.setHierarchy(hierarchy); // 加载图片的地址 Uri uri = Uri.parse("http://"); // 加载图片 sdvFresco.setImageURI(uri);
CENTER_CROP
//保持宽高比缩小或放大,使得两边都大于或等于显示边界。居中显示 GenericDraweeHierarchy hierarchy = builder.setActualImageScaleType(ScalingUtils.ScaleType.CENTER_CROP).build();
FOCUS_CROP
// 同centerCrop, 但居中点不是中点,而是指定的某个点,这里我设置为图片的左上角那点 PointF point = new PointF(0,0); GenericDraweeHierarchy hierarchy = builder.setActualImageScaleType(ScalingUtils.ScaleType.FOCUS_CROP)
CENTER_INSIDE
//使两边都在显示边界内,居中显示。如果图尺寸大于显示边界,则保持长宽比缩小图片 GenericDraweeHierarchy hierarchy = builder.setActualImageScaleType(ScalingUtils.ScaleType.CENTER_INSIDE).build();
FIT_CENTER
//保持宽高比,缩小或者放大,使得图片完全显示在显示边界内。居中显示 GenericDraweeHierarchy hierarchy = builder.setActualImageScaleType(ScalingUtils.ScaleType.FIT_CENTER).build();
FIT_START
//保持宽高比,缩小或者放大,使得图片完全显示在显示边界内,不居中,和显示边界左上对齐 GenericDraweeHierarchy hierarchy = builder.setActualImageScaleType(ScalingUtils.ScaleType.FIT_START).build();
FIT_END
//保持宽高比,缩小或者放大,使得图片完全显示在显示边界内,不居中,和显示边界右下对齐 GenericDraweeHierarchy hierarchy = builder.setActualImageScaleType(ScalingUtils.ScaleType.FIT_END).build();
FIT_XY
//不保持宽高比,填充满显示边界 GenericDraweeHierarchy hierarchy = builder.setActualImageScaleType(ScalingUtils.ScaleType.FIT_XY).build();
title mode
//如要使用title mode显示, 需要设置为none GenericDraweeHierarchy hierarchy = builder.setActualImageScaleType(null).build();
3.3 圆形和圆角图片
//圆形图片 parames = RoundingParams.asCircle(); GenericDraweeHierarchy hierarchy = builder.setRoundingParams(parames).build(); //圆角图片 parames = RoundingParams.fromCornersRadius(50f); //parames.setOverlayColor(getResources().getColor(android.R.color.holo_red_light));//覆盖层 //parames.setBorder(getResources().getColor(android.R.color.holo_blue_light), 5);//边框 GenericDraweeHierarchy hierarchy = builder.setRoundingParams(parames).build();
3.4 渐进式展示图片
// 加载质量配置 ProgressiveJpegConfig jpegConfig = new ProgressiveJpegConfig() { @Override public int getNextScanNumberToDecode(int scanNumber) { return scanNumber + 2; } @Override public QualityInfo getQualityInfo(int scanNumber) { boolean isGoodEnough = (scanNumber >= 5); return ImmutableQualityInfo.of(scanNumber, isGoodEnough, false); } }; ImagePipelineConfig.newBuilder(this).setProgressiveJpegConfig(jpegConfig).build(); // 获取图片URL Uri uri = Uri.parse("http://"); // 获取图片请求 ImageRequest request = ImageRequestBuilder.newBuilderWithSource(uri).setProgressiveRenderingEnabled(true).build(); DraweeController draweeController = Fresco.newDraweeControllerBuilder() .setImageRequest(request) .setTapToRetryEnabled(true) .setOldController(sdvFresco.getController())//使用oldController可以节省不必要的内存分配 .build(); // 设置加载的控制 sdvFresco.setController(draweeController);
3.5 GIF动画图片
Uri uri = Uri.parse("http://"); DraweeController controller = Fresco.newDraweeControllerBuilder() .setUri(uri) .setAutoPlayAnimations(true) //是否自动播放 .setOldController(sdvFresco.getController()) .build(); sdvFresco.setController(controller); // 动画开始 Animatable animatable = sdvFresco.getController().getAnimatable(); if(animatable != null && !animatable.isRunning()) { animatable.start(); } //动画停止 Animatable animatable = sdvFresco.getController().getAnimatable(); if(animatable != null && animatable.isRunning()) { animatable.stop(); }
3.6 多图请求及图片复用
先显示低分辨率的图,然后是高分辨率的图
// 图片地址 Uri lowUri = Uri.parse("http://"); Uri highUri = Uri.parse("http://"); // 控制加载图片 DraweeController controller = Fresco.newDraweeControllerBuilder() .setLowResImageRequest(ImageRequest.fromUri(lowUri)) .setImageRequest(ImageRequest.fromUri(highUri)) .build(); // 加载图片 sdvFresco.setController(controller); 本地缩略图预览 // 图片地址 Uri uri = Uri.fromFile(new File(Environment.getExternalStorageDirectory() +"/meinv1.jpg")); // 加载图片的请求 ImageRequest request = ImageRequestBuilder.newBuilderWithSource(uri) .setLocalThumbnailPreviewsEnabled(true) .build(); // 控制图片的加载 DraweeController controller = Fresco.newDraweeControllerBuilder() .setImageRequest(request) .build(); // 加载图片 sdvFresco.setController(controller); 本地图片复用 //本地图片的复用 //在请求之前,还会去内存中请求一次图片,没有才会先去本地,最后去网络uri //本地准备复用图片的uri 如果本地这个图片不存在,会自动去加载下一个uri // 请求加载图片 Uri uri1 = Uri.fromFile(new File(Environment.getExternalStorageDirectory()+"/meinv.jpg")); //图片的网络uri Uri uri2 = Uri.parse("http://"); ImageRequest request1 = ImageRequest.fromUri(uri1); ImageRequest request2 = ImageRequest.fromUri(uri2); ImageRequest[] requests = {request1, request2}; // 控制加载图片 DraweeController controller = Fresco.newDraweeControllerBuilder() .setFirstAvailableImageRequests(requests) .setOldController(sdvFresco.getController()) .build(); // 加载图片 sdvFresco.setController(controller);
3.7 图片加载监听
// 图片加载的控制 //添加监听事件 .setControllerListener(controllerListener) SimpleDraweeView sdvFrescoListener; DraweeController controller = Fresco.newDraweeControllerBuilder() .setOldController(sdvFrescoListener.getController()) .setImageRequest(request) .setControllerListener(controllerListener) .build();
private ControllerListener controllerListener = new BaseControllerListener<ImageInfo>(){ // 加载图片完毕 @Override public void onFinalImageSet(String id, ImageInfo imageInfo, Animatable animatable) { super.onFinalImageSet(id, imageInfo, animatable); if (imageInfo == null) { return; } // 获取图片的质量 QualityInfo qualityInfo = imageInfo.getQualityInfo(); //页面文本打印setText tvFrescoListener.setText("Final image received! " + "\nSize: " + imageInfo.getWidth() + "x" + imageInfo.getHeight() + "\nQuality level: " + qualityInfo.getQuality() + "\ngood enough: " + qualityInfo.isOfGoodEnoughQuality() + "\nfull quality: " + qualityInfo.isOfFullQuality()); } // 渐进式加载图片回调 @Override public void onIntermediateImageSet(String id, ImageInfo imageInfo) { super.onIntermediateImageSet(id, imageInfo); tvFrescoListener2.setText("IntermediateImageSet image receiced"); } // 加载图片失败 @Override public void onFailure(String id, Throwable throwable) { super.onFailure(id, throwable); tvFrescoListener.setText("Error loading" + id); } }
3.8 图片修改和旋转
修内存中改图片大小 setResizeOptions
// 图片地址 Uri uri = Uri.parse("http://"); // 图片的请求 ImageRequest request = ImageRequestBuilder.newBuilderWithSource(uri) .setResizeOptions(new ResizeOptions(50,50)) .build(); // 控制图片的加载 PipelineDraweeController controller = (PipelineDraweeController) Fresco.newDraweeControllerBuilder() .setOldController(sdvFresco.getController()) .setImageRequest(request) .build(); // 加载图片 sdvFresco.setController(controller);
旋转图片 setAutoRotateEnabled
Uri uri = Uri.parse("http://"); ImageRequest request = ImageRequestBuilder.newBuilderWithSource(uri) .setAutoRotateEnabled(true) .build(); // 控制图片的加载 DraweeController controller = Fresco.newDraweeControllerBuilder() .setOldController(sdvFresco.getController()) .setImageRequest(request) .build(); // 加载图片 sdvFresco.setController(controller);
3.9 修改图片(显示过程同上,主要更改了ImageRequest设置) setPostprocessor
// 修改图片 Postprocessor postProcessor = new BasePostprocessor() { @Override public String getName() { return "postProcessor"; } @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(postProcessor) .build();
3.10 动态展示图片(添加SimpleDraweeView到LinearLayout中)
SimpleDraweeView simpleDraweeView = new SimpleDraweeView(this); // 设置宽高比 simpleDraweeView.setAspectRatio(3.0f); // 图片的地址 Uri uri = Uri.parse("http://"); // 图片的请求 ImageRequest request = ImageRequestBuilder.newBuilderWithSource(uri) .build(); // 加载图片的控制 PipelineDraweeController controller = (PipelineDraweeController) Fresco.newDraweeControllerBuilder() .setOldController(simpleDraweeView.getController()) .setImageRequest(request) .build(); // 加载图片 simpleDraweeView.setController(controller); // 添加View到线性布局中 linearLayout.addView(simpleDraweeView);