采得百花成蜜后,为谁辛苦为谁甜。这篇文章主要讲述Android图片加载神器之Fresco,基于各种使用场景的讲解相关的知识,希望能为你提供帮助。
转载请标明出处:
http://blog.csdn.net/android_ls/article/details/53137867
Fresco是Facebook开源android平台上一个强大的图片加载库,
也是迄今为止Android平台上最强大的图片加载库。
优点:
相对于其他开源的第三方图片加载库,
Fresco拥有更好的内存管理和强大的功能,
基本上能满足所有的日常使用场景。
缺点:
整体比较大,
不过目前的版本已做了拆分,
你只需要导入你使用到的功能相关的库。从代码层面来说侵入性太强,
体现在要使用它需要用Fresco的组件SimpleDraweeView替换掉Android原生图片显示组件ImageView,
这也是很多人不愿意在项目中接入Fresco的主要原因。
特性:
1、内存管理
解压后的图片,
即Android中的Bitmap,
占用大量的内存。大的内存占用势必引发更加频繁的GC。在5.0以下,
GC将会显著地引发界面卡顿。
在5.0以下系统,
Fresco将图片放到一个特别的内存区域。当然,
在图片不显示的时候,
占用的内存会自动被释放。这会使得APP更加流畅,
减少因图片内存占用而引发的OOM。
2、Image Pipeline
Fresco中设计有一个叫做 Image Pipeline 的模块。它负责从网络,
从本地文件系统,
本地资源加载图片和管理。为了最大限度节省空间和CPU时间,
它含有3级缓存设计(
2级内存,
1级磁盘)
。两个内存缓存为Bitmap缓存和未解码的图片缓存,
这样既可以加快图片的加载速度,
又能节省内存的占用(
解码后的图片就是Bitmap,
其占用内存相对未解码的图片数据而言会大很多)
。
Image pipeline 负责完成加载图像,
变成Android设备可呈现的形式所要经历的大致流程如下:
a、根据Uri在已解码的(
Bitmap缓存)
内存缓存中查找,
找到了则返回Bitmap对象;
如果没找到,
则开启后台线程开始后续的工作。
b、根据Uri在未解码的内存缓存中查找,
若找到了则解码,
然后缓存到已解码的内存缓存中,
并且返回Bitmap对象。
d、如果在未解码的内存缓存中没找到,
则根据Uri在磁盘缓存中查找,
若找到了则读取数据(
byte数组)
,
并缓存到未解码的内存缓存中,
解码、然后缓存到已解码的内存缓存中,
并且返回Bitmap对象。
e、如果在磁盘缓存中没找到,
则从网络或者本地加载数据。加载完成后,
依次缓存到磁盘缓存、未解码的内存缓存中。解码、然后缓存到已解码的内存缓存中,
并且返回Bitmap对象。
其流程图如下:
文章图片
3、Drawees
Fresco 中设计有一个叫做 Drawees 模块, 负责图片的呈现。它由三个元素组成分别是:
DraweeView 继承于 View, 负责图片的显示。
DraweeHierarchy 用于组织和维护最终绘制和呈现的 Drawable 对象。
DraweeController 负责和ImagePipeline的交互, 可以创建一个这个类的实例, 来实现对所要显示的图片做更多的控制。
一般情况下, 使用 SimpleDraweeView 即可, 你可以配置其XML属性来实现各式各样的展示效果。
a、在图片加载完成前显示占位图;
b、在图片加载的过程中显示加载进度图;
c、加载成功后, 将占位图或者加载进度图, 自动替换为目标图片。
d、加载失败后, 它会显示加载失败的图( 若没配置加载失败的图, 则显示的是占位图)
e、加载失败后, 若配置过重试图, 则会显示重试图, 用户点击可以重新去加载图片( 默认配置可重试3次)
f、自定义居中焦点( 配合Google提供的服务可以实现人脸识别, 经测试国内目前使用不了)
g、显示圆角图、圆形图和圆圈;
h、添加覆盖物( 图层叠加) ;
j、 实现图片的按下效果;
k、图片的渐进式呈现; ( 目前只支持Jpeg格式的图片)
x、当图片不再显示在屏幕上时, 它会及时地释放内存和空间占用。
4、Fresco目前所支持的图片格式
a、静态图: png、jpg、web
b、动态图: gif、web格式的gif
以上聊了这么多, 大概意思就是Fresco出身名门, 很好很强大, 超牛逼! 接下来我们来聊聊在项目中的具体使用。我专门写了一个针对Fresco的使用帮助库( github地址: https://github.com/hpdx/fresco-helper) , 先给大家看看Demo的运行效果图:
文章图片
常见的各种效果
文章图片
从网络加载的图片墙
文章图片
点击图片墙中的照片后, 打开的浏览大图界面
文章图片
一、Fresco的引入及ImagePipeline参数配置
1、在build.gradle文件中添加依赖
dependencies {
// ......compile '
com.facebook.fresco:fresco:0.14.1'
compile '
com.facebook.fresco:animated-base-support:0.14.1'
compile '
com.facebook.fresco:animated-gif:0.14.1'
compile '
com.facebook.fresco:webpsupport:0.14.1'
compile '
com.facebook.fresco:animated-webp:0.14.1'
compile '
com.facebook.fresco:imagepipeline-okhttp3:0.14.1'
}
a、在 API < 14 上的机器支持 WebP 时, 需要添加以下依赖
compile '
com.facebook.fresco:animated-base-support:0.14.1'
b、支持GIF动图, 需要添加以下依赖
compile '
com.facebook.fresco:animated-gif:0.14.1'
c、支持WebP, 需要添加以下依赖
compile '
com.facebook.fresco:webpsupport:0.14.1'
d、支持WebP动图, 需要添加以下依赖
compile '
com.facebook.fresco:animated-webp:0.14.1'
e、网络实现层想使用okhttp3, 需要添加以下依赖
compile '
com.facebook.fresco:imagepipeline-okhttp3:0.14.1'
2、ImagePipeline配置
a、磁盘缓存目录, 推荐缓存到应用本身的缓存文件夹, 这么做的好处是: 当应用被用户卸载后能自动清除缓存, 增加用户好感( 可能以后用得着时, 还会想起我) ; 一些内存清理软件可以扫描出来, 进行内存的清理。
File fileCacheDir =
context.getApplicationContext().getCacheDir();
b、配置磁盘缓存, 大部分的应用有一个磁盘缓存就够了, 但是在一些情况下, 你可能需要两个缓存。比如你想把小文件放在一个缓存中( 50*50及以下尺寸) , 大文件放在另外一个文件中, 这样小文件就不会因大文件的频繁变动而被从缓存中移除。
DiskCacheConfig mainDiskCacheConfig =
DiskCacheConfig.newBuilder(context)
.setBaseDirectoryName(IMAGE_PIPELINE_CACHE_DIR)
.setBaseDirectoryPath(fileCacheDir)
.build();
DiskCacheConfig smallDiskCacheConfig =
DiskCacheConfig.newBuilder(context)
.setBaseDirectoryPath(fileCacheDir)
.setBaseDirectoryName(IMAGE_PIPELINE_SMALL_CACHE_DIR)
.setMaxCacheSize(MAX_DISK_SMALL_CACHE_SIZE)
.setMaxCacheSizeOnLowDiskSpace(MAX_DISK_SMALL_ONLOWDISKSPACE_CACHE_SIZE)
.build();
c、ImagePipeline的完整配置代码如下:
package com.facebook.fresco.helper.config;
import android.app.ActivityManager;
import android.content.Context;
import android.graphics.Bitmap;
import com.facebook.cache.disk.DiskCacheConfig;
import com.facebook.common.logging.FLog;
import com.facebook.common.memory.MemoryTrimType;
import com.facebook.common.memory.MemoryTrimmable;
import com.facebook.common.memory.MemoryTrimmableRegistry;
import com.facebook.common.memory.NoOpMemoryTrimmableRegistry;
import com.facebook.common.util.ByteConstants;
import com.facebook.drawee.backends.pipeline.Fresco;
import com.facebook.fresco.helper.utils.MLog;
import com.facebook.imagepipeline.backends.okhttp3.OkHttpImagePipelineConfigFactory;
import com.facebook.imagepipeline.core.ImagePipelineConfig;
import com.facebook.imagepipeline.decoder.ProgressiveJpegConfig;
import com.facebook.imagepipeline.image.ImmutableQualityInfo;
import com.facebook.imagepipeline.image.QualityInfo;
import com.facebook.imagepipeline.listener.RequestListener;
import com.facebook.imagepipeline.listener.RequestLoggingListener;
import java.io.File;
import java.util.HashSet;
import java.util.Set;
import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
/**
*
* Created by android_ls on 16/9/8.
*/
public class ImageLoaderConfig {private static final String IMAGE_PIPELINE_CACHE_DIR =
"
image_cache"
;
private static final String IMAGE_PIPELINE_SMALL_CACHE_DIR =
"
image_small_cache"
;
private static final int MAX_DISK_SMALL_CACHE_SIZE =
10 * ByteConstants.MB;
private static final int MAX_DISK_SMALL_ONLOWDISKSPACE_CACHE_SIZE =
5 * ByteConstants.MB;
private static ImagePipelineConfig sImagePipelineConfig;
/**
* Creates config using android http stack as network backend.
*/
public static ImagePipelineConfig getImagePipelineConfig(final Context context) {
if (sImagePipelineConfig =
=
null) {
/**
* 推荐缓存到应用本身的缓存文件夹,
这么做的好处是:
* 1、当应用被用户卸载后能自动清除缓存,
增加用户好感(
可能以后用得着时,
还会想起我)
* 2、一些内存清理软件可以扫描出来,
进行内存的清理
*/
File fileCacheDir =
context.getApplicationContext().getCacheDir();
//if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
//fileCacheDir =
new File(Environment.getExternalStorageDirectory().getAbsolutePath() +
"
/Fresco"
);
//}DiskCacheConfig mainDiskCacheConfig =
DiskCacheConfig.newBuilder(context)
.setBaseDirectoryName(IMAGE_PIPELINE_CACHE_DIR)
.setBaseDirectoryPath(fileCacheDir)
.build();
DiskCacheConfig smallDiskCacheConfig =
DiskCacheConfig.newBuilder(context)
.setBaseDirectoryPath(fileCacheDir)
.setBaseDirectoryName(IMAGE_PIPELINE_SMALL_CACHE_DIR)
.setMaxCacheSize(MAX_DISK_SMALL_CACHE_SIZE)
.setMaxCacheSizeOnLowDiskSpace(MAX_DISK_SMALL_ONLOWDISKSPACE_CACHE_SIZE)
.build();
FLog.setMinimumLoggingLevel(FLog.VERBOSE);
Set<
RequestListener>
requestListeners =
new HashSet<
>
();
requestListeners.add(new RequestLoggingListener());
// 当内存紧张时采取的措施
MemoryTrimmableRegistry memoryTrimmableRegistry =
NoOpMemoryTrimmableRegistry.getInstance();
memoryTrimmableRegistry.registerMemoryTrimmable(new MemoryTrimmable() {
@
Override
public void trim(MemoryTrimType trimType) {
final double suggestedTrimRatio =
trimType.getSuggestedTrimRatio();
MLog.i(String.format("
Fresco onCreate suggestedTrimRatio : %d"
, suggestedTrimRatio));
if (MemoryTrimType.OnCloseToDalvikHeapLimit.getSuggestedTrimRatio() =
=
suggestedTrimRatio
|| MemoryTrimType.OnSystemLowMemoryWhileAppInBackground.getSuggestedTrimRatio() =
=
suggestedTrimRatio
|| MemoryTrimType.OnSystemLowMemoryWhileAppInForeground.getSuggestedTrimRatio() =
=
suggestedTrimRatio
) {
// 清除内存缓存
Fresco.getImagePipeline().clearMemoryCaches();
}
}
});
HttpLoggingInterceptor loggingInterceptor =
new HttpLoggingInterceptor();
loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
OkHttpClient okHttpClient =
new OkHttpClient.Builder()
.addInterceptor(loggingInterceptor)
//.retryOnConnectionFailure(false)
.build();
sImagePipelineConfig =
OkHttpImagePipelineConfigFactory.newBuilder(context, okHttpClient)
//sImagePipelineConfig =
ImagePipelineConfig.newBuilder(context)
.setBitmapsConfig(Bitmap.Config.RGB_565) // 若不是要求忒高清显示应用,
就用使用RGB_565吧(
默认是ARGB_8888)
.setDownsampleEnabled(true) // 在解码时改变图片的大小,
支持PNG、JPG以及WEBP格式的图片,
与ResizeOptions配合使用
// 设置Jpeg格式的图片支持渐进式显示
.setProgressiveJpegConfig(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);
}
})
.setRequestListeners(requestListeners)
.setMemoryTrimmableRegistry(memoryTrimmableRegistry) // 报内存警告时的监听
// 设置内存配置
.setBitmapMemoryCacheParamsSupplier(new BitmapMemoryCacheParamsSupplier(
(ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE)))
.setMainDiskCacheConfig(mainDiskCacheConfig) // 设置主磁盘配置
.setSmallImageDiskCacheConfig(smallDiskCacheConfig) // 设置小图的磁盘配置
.build();
}
return sImagePipelineConfig;
}}
d、替换网络实现为okhttp3
OkHttpClient okHttpClient =
new OkHttpClient.Builder()
.addInterceptor(loggingInterceptor)
//.retryOnConnectionFailure(false)
.build();
sImagePipelineConfig =
OkHttpImagePipelineConfigFactory.newBuilder(context, okHttpClient)
e、支持调试时, 显示图片加载的Log
FLog.setMinimumLoggingLevel(FLog.VERBOSE);
Set<
RequestListener>
requestListeners =
new HashSet<
>
();
requestListeners.add(new RequestLoggingListener());
f、内存缓存配置完整代码:
package com.facebook.fresco.helper.config;
import android.app.ActivityManager;
import android.os.Build;
import com.facebook.common.internal.Supplier;
import com.facebook.common.util.ByteConstants;
import com.facebook.fresco.helper.utils.MLog;
import com.facebook.imagepipeline.cache.MemoryCacheParams;
/**
* 内存缓存配置
* https://github.com/facebook/fresco/issues/738
*
* Created by android_ls on 16/9/8.
*/
public class BitmapMemoryCacheParamsSupplier implements Supplier<
MemoryCacheParams>
{private final ActivityManager mActivityManager;
public BitmapMemoryCacheParamsSupplier(ActivityManager activityManager) {
mActivityManager =
activityManager;
}@
Override
public MemoryCacheParams get() {
if (Build.VERSION.SDK_INT >
=
Build.VERSION_CODES.LOLLIPOP) {
return new MemoryCacheParams(getMaxCacheSize(), // 内存缓存中总图片的最大大小,以字节为单位。
56,// 内存缓存中图片的最大数量。
Integer.MAX_VALUE,// 内存缓存中准备清除但尚未被删除的总图片的最大大小,以字节为单位。
Integer.MAX_VALUE,// 内存缓存中准备清除的总图片的最大数量。
Integer.MAX_VALUE);
// 内存缓存中单个图片的最大大小。
} else {
return new MemoryCacheParams(
getMaxCacheSize(),
256,
Integer.MAX_VALUE,
Integer.MAX_VALUE,
Integer.MAX_VALUE);
}
}private int getMaxCacheSize() {
final int maxMemory =
Math.min(mActivityManager.getMemoryClass() * ByteConstants.MB, Integer.MAX_VALUE);
MLog.i(String.format("
Fresco Max memory [%d] MB"
, (maxMemory/ByteConstants.MB)));
if (maxMemory <
32 * ByteConstants.MB) {
return 4 * ByteConstants.MB;
} else if (maxMemory <
64 * ByteConstants.MB) {
return 6 * ByteConstants.MB;
} else {
// We don'
t want to use more ashmem on Gingerbread for now, since it doesn'
t respond well to
// native memory pressure (doesn'
t throw exceptions, crashes app, crashes phone)
if (Build.VERSION.SDK_INT <
Build.VERSION_CODES.HONEYCOMB) {
return 8 * ByteConstants.MB;
} else {
return maxMemory / 4;
}
}
}}
g、初始化Fresco
Fresco.initialize(context,ImageLoaderConfig.getImagePipelineConfig(context));
二、Fresco的各种使用场景
从网络加载一张图片
String url =
"
http://ww3.sinaimg.cn/large/610dc034jw1f6m4aj83g9j20zk1hcww3.jpg"
;
ImageLoader.loadImage((SimpleDraweeView)findViewById(R.id.sdv_1), url);
1、显示一张图片
<
com.facebook.drawee.view.SimpleDraweeView
android:id=
"
@
+
id/sdv_1"
android:layout_width=
"
90dp"
android:layout_height=
"
90dp"
app:actualImageScaleType=
"
centerCrop"
/>
效果图如下:
文章图片
2、显示一张圆形图片
<
com.facebook.drawee.view.SimpleDraweeView
android:id=
"
@
+
id/sdv_2"
android:layout_width=
"
90dp"
android:layout_height=
"
90dp"
android:layout_marginTop=
"
15dp"
app:actualImageScaleType=
"
centerCrop"
app:roundAsCircle=
"
true"
/>
效果图如下:
文章图片
3、显示一张圆形带边框的图片
<
com.facebook.drawee.view.SimpleDraweeView
android:id=
"
@
+
id/sdv_3"
android:layout_width=
"
90dp"
android:layout_height=
"
90dp"
android:layout_marginTop=
"
15dp"
app:actualImageScaleType=
"
centerCrop"
app:roundAsCircle=
"
true"
app:roundingBorderColor=
"
#fff3cf44"
app:roundingBorderWidth=
"
2dp"
/>
效果图如下:
文章图片
4、显示一张圆角图片
<
com.facebook.drawee.view.SimpleDraweeView
android:id=
"
@
+
id/sdv_4"
android:layout_width=
"
90dp"
android:layout_height=
"
90dp"
android:layout_marginTop=
"
15dp"
app:actualImageScaleType=
"
centerCrop"
app:roundAsCircle=
"
false"
app:roundedCornerRadius=
"
10dp"
/>
效果图如下:
文章图片
5、显示一张底部是圆角的图片
<
com.facebook.drawee.view.SimpleDraweeView
android:id=
"
@
+
id/sdv_5"
android:layout_width=
"
90dp"
android:layout_height=
"
90dp"
android:layout_marginTop=
"
15dp"
app:actualImageScaleType=
"
centerCrop"
app:roundAsCircle=
"
false"
app:roundedCornerRadius=
"
10dp"
app:roundTopLeft=
"
false"
app:roundTopRight=
"
false"
app:roundBottomLeft=
"
true"
app:roundBottomRight=
"
true"
/>
效果图如下:
文章图片
6、显示一张左上和右下是圆角的图片
<
com.facebook.drawee.view.SimpleDraweeView
android:id=
"
@
+
id/sdv_6"
android:layout_width=
"
90dp"
android:layout_height=
"
90dp"
android:layout_marginTop=
"
15dp"
app:actualImageScaleType=
"
centerCrop"
app:roundAsCircle=
"
false"
app:roundedCornerRadius=
"
10dp"
app:roundTopLeft=
"
true"
app:roundTopRight=
"
false"
app:roundBottomLeft=
"
false"
app:roundBottomRight=
"
true"
/>
效果图如下:
文章图片
7、设置占位图
<
com.facebook.drawee.view.SimpleDraweeView
android:id=
"
@
+
id/sdv_7"
android:layout_width=
"
90dp"
android:layout_height=
"
90dp"
android:layout_marginTop=
"
15dp"
app:actualImageScaleType=
"
centerCrop"
app:placeholderImage=
"
@
mipmap/ic_launcher"
app:placeholderImageScaleType=
"
centerCrop"
/>
8、带动画的显示( 从半透明到不透明)
<
com.facebook.drawee.view.SimpleDraweeView
android:id=
"
@
+
id/sdv_8"
android:layout_width=
"
90dp"
android:layout_height=
"
90dp"
android:layout_marginTop=
"
15dp"
app:actualImageScaleType=
"
centerCrop"
app:fadeDuration=
"
3000"
/>
9、图层叠加显示
<
com.facebook.drawee.view.SimpleDraweeView
android:id=
"
@
+
id/sdv_10"
android:layout_width=
"
90dp"
android:layout_height=
"
90dp"
android:layout_marginTop=
"
15dp"
app:actualImageScaleType=
"
centerCrop"
app:overlayImage=
"
@
mipmap/ic_launcher"
/>
10、其它的属性的配置, 比如加载进度、加载失败、重试图
<
com.facebook.drawee.view.SimpleDraweeView
android:id=
"
@
+
id/sdv_11"
android:layout_width=
"
90dp"
android:layout_height=
"
90dp"
android:layout_marginTop=
"
15dp"
app:actualImageScaleType=
"
centerCrop"
app:failureImage=
"
@
mipmap/ic_launcher"
app:failureImageScaleType=
"
centerInside"
app:retryImage=
"
@
mipmap/ic_launcher"
app:retryImageScaleType=
"
centerCrop"
app:progressBarImage=
"
@
mipmap/ic_launcher"
app:progressBarImageScaleType=
"
centerCrop"
app:progressBarAutoRotateInterval=
"
5000"
/>
11、从本地文件( 比如SDCard上) 加载图片
public static void loadFile(final SimpleDraweeView draweeView, String filePath, final int reqWidth, final int reqHeight) {
Uri uri =
new Uri.Builder()
.scheme(UriUtil.LOCAL_FILE_SCHEME)
.path(filePath)
.build();
ImageRequest request =
ImageRequestBuilder.newBuilderWithSource(uri)
.setRotationOptions(RotationOptions.autoRotate())
.setLocalThumbnailPreviewsEnabled(true)
.setResizeOptions(new ResizeOptions(reqWidth, reqHeight))
.build();
DraweeController controller =
Fresco.newDraweeControllerBuilder()
.setImageRequest(request)
.setOldController(draweeView.getController())
.setControllerListener(new BaseControllerListener<
ImageInfo>
() {
@
Override
public void onFinalImageSet(String id, @
Nullable ImageInfo imageInfo, @
Nullable Animatable anim) {
if (imageInfo =
=
null) {
return;
}ViewGroup.LayoutParams vp =
draweeView.getLayoutParams();
vp.width =
reqWidth;
vp.height =
reqHeight;
draweeView.requestLayout();
}
})
.build();
draweeView.setController(controller);
}
使用:
ImageLoader.loadFile((SimpleDraweeView)itemView, photoInfo.thumbnailUrl, 120, 120);
12、从本地资源( Resources) 加载图片
public static void loadDrawable(SimpleDraweeView draweeView, int resId) {
Uri uri =
new Uri.Builder()
.scheme(UriUtil.LOCAL_RESOURCE_SCHEME)
.path(String.valueOf(resId))
.build();
DraweeController controller =
Fresco.newDraweeControllerBuilder()
.setUri(uri)
.setOldController(draweeView.getController())
.build();
draweeView.setController(controller);
}
使用:
ImageLoader.loadDrawable(simpleDraweeView, R.drawable.meizi);
效果图如下:
文章图片
13、对图片进行性高斯模糊处理
public static void loadImageBlur(final SimpleDraweeView draweeView, String url) {
loadImage(draweeView, url, new BasePostprocessor() {
@
Override
public String getName() {
return "
blurPostprocessor"
;
}@
Override
public void process(Bitmap bitmap) {
BitmapBlurHelper.blur(bitmap, 35);
}
});
}
其内部调用的方法
public static void loadImage(SimpleDraweeView simpleDraweeView, String url, BasePostprocessor processor) {
if (TextUtils.isEmpty(url)) {
return;
}Uri uri =
Uri.parse(url);
ImageRequest request =
ImageRequestBuilder.newBuilderWithSource(uri)
.setRotationOptions(RotationOptions.autoRotate())
.setPostprocessor(processor)
.build();
DraweeController controller =
Fresco.newDraweeControllerBuilder()
.setImageRequest(request)
.setOldController(simpleDraweeView.getController())
.build();
simpleDraweeView.setController(controller);
}
使用:
String url =
"
http://a.hiphotos.baidu.com/image/pic/item/55e736d12f2eb938d3de795ad0628535e4dd6fe2.jpg"
;
SimpleDraweeView simpleDraweeView =
(SimpleDraweeView)findViewById(R.id.sdv_1);
simpleDraweeView.setAspectRatio(0.7f);
ViewGroup.LayoutParams lvp =
simpleDraweeView.getLayoutParams();
lvp.width =
DensityUtil.getDisplayWidth(this);
ImageLoader.loadImageBlur(simpleDraweeView, url,
DensityUtil.getDisplayWidth(this), DensityUtil.getDisplayHeight(this));
效果图如下:
文章图片
14、我们知道使用Fresco加载并显示一张图片, 需要指定SimpleDraweeView的宽高或者指定其中一个值并设置宽高比, 可是我真的不知道要显示的图片有多大, 该显示多大? 可以帮我搞定吗? 答案是肯定的。
String url =
"
http://feed.chujianapp.com/20161108/452ab5752287a99a1b5387e2cd849006.jpg@
1080w"
;
SimpleDraweeView simpleDraweeView =
(SimpleDraweeView)findViewById(R.id.sdv_1);
ImageLoader.loadImage(simpleDraweeView, url, new SingleImageControllerListener(simpleDraweeView));
15、从网络加载并显示gif格式的图片
String url =
"
http://img4.178.com/acg1/201506/227753817857/227754566617.gif"
;
SimpleDraweeView simpleDraweeView =
(SimpleDraweeView)findViewById(R.id.sdv_1);
ImageLoader.loadImage(simpleDraweeView, url);
16、加载并显示webp格式的图片
SimpleDraweeView simpleDraweeView =
(SimpleDraweeView)findViewById(R.id.sdv_1);
ViewGroup.LayoutParams lvp =
simpleDraweeView.getLayoutParams();
lvp.width =
DensityUtil.getDisplayWidth(this);
simpleDraweeView.setAspectRatio(0.6f);
// 设置宽高比ImageLoader.loadDrawable(simpleDraweeView, R.drawable.meizi_webp,
DensityUtil.getDisplayWidth(this), DensityUtil.getDisplayHeight(this));
其中R.drawable.meizi_webp为meizi_webp.webp
17、从内存缓存中移除指定图片的缓存
if (!TextUtils.isEmpty(photoInfo.originalUrl)) {
ImagePipeline imagePipeline =
Fresco.getImagePipeline();
Uri uri =
Uri.parse(photoInfo.originalUrl);
if (imagePipeline.isInBitmapMemoryCache(uri)) {
imagePipeline.evictFromMemoryCache(uri);
}
}
18、从磁盘缓存中移除指定图片的缓存
ImagePipeline imagePipeline =
Fresco.getImagePipeline();
Uri uri =
Uri.parse(photoInfo.originalUrl);
// 下面的操作是异步的
if (imagePipeline.isInDiskCacheSync(uri)) {
imagePipeline.evictFromDiskCache(uri);
}
19、清空磁盘缓存
Fresco.getImagePipeline().clearDiskCaches();
20、清空内存缓存
Fresco.getImagePipeline().clearMemoryCaches();
21、清空缓存( 内存缓存 + 磁盘缓存)
Fresco.getImagePipeline().clearCaches();
22、在列表视图滚动时, 不加载图片, 等滚动停止后再开始加载图片, 提升列表视图的滚动流畅度。
// 需要暂停网络请求时调用
public static void pause(){
Fresco.getImagePipeline().pause();
}// 需要恢复网络请求时调用
public static void resume(){
Fresco.getImagePipeline().resume();
}
23、下载图片存储到指定的路径
/**
* 从网络下载图片
* 1、根据提供的图片URL,
获取图片数据流
* 2、将得到的数据流写入指定路径的本地文件
*
* @
param urlURL
* @
param loadFileResult LoadFileResult
*/
public static void downloadImage(Context context, String url, final DownloadImageResult loadFileResult) {
if (TextUtils.isEmpty(url)) {
return;
}Uri uri =
Uri.parse(url);
ImagePipeline imagePipeline =
Fresco.getImagePipeline();
ImageRequestBuilder builder =
ImageRequestBuilder.newBuilderWithSource(uri);
ImageRequest imageRequest =
builder.build();
// 获取未解码的图片数据
DataSource<
CloseableReference<
PooledByteBuffer>
>
dataSource =
imagePipeline.fetchEncodedImage(imageRequest, context);
dataSource.subscribe(new BaseDataSubscriber<
CloseableReference<
PooledByteBuffer>
>
() {
@
Override
public void onNewResultImpl(DataSource<
CloseableReference<
PooledByteBuffer>
>
dataSource) {
if (!dataSource.isFinished() || loadFileResult =
=
null) {
return;
}CloseableReference<
PooledByteBuffer>
imageReference =
dataSource.getResult();
if (imageReference !=
null) {
final CloseableReference<
PooledByteBuffer>
closeableReference =
imageReference.clone();
try {
PooledByteBuffer pooledByteBuffer =
closeableReference.get();
InputStream inputStream =
new PooledByteBufferInputStream(pooledByteBuffer);
String photoPath =
loadFileResult.getFilePath();
Log.i("
ImageLoader"
, "
photoPath =
"
+
photoPath);
byte[] data =
StreamTool.read(inputStream);
StreamTool.write(photoPath, data);
loadFileResult.onResult(photoPath);
} catch (IOException e) {
loadFileResult.onFail();
e.printStackTrace();
} finally {
imageReference.close();
closeableReference.close();
}
}
}@
Override
public void onFailureImpl(DataSource dataSource) {
if (loadFileResult !=
null) {
loadFileResult.onFail();
}Throwable throwable =
dataSource.getFailureCause();
if (throwable !=
null) {
Log.e("
ImageLoader"
, "
onFailureImpl =
"
+
throwable.toString());
}
}
}, Executors.newSingleThreadExecutor());
}
使用:
String url =
"
http://feed.chujianapp.com/20161108/452ab5752287a99a1b5387e2cd849006.jpg@
1080w"
;
String filePath =
"
"
;
ImageLoader.downloadImage(context, url, new DownloadImageResult(filePath) {@
Override
public void onResult(String filePath) {}@
Override
public void onFail() {}
});
【Android图片加载神器之Fresco,基于各种使用场景的讲解】24、不使用SimpleDraweeView组件, 但是想使用Fresco去加载图片( 两级内存缓存+ 磁盘缓存要有) 并显示到其他组件上( 比如显示在TextView的drawableLeft属性上或者显示为View的背景) 。
public static void loadTextDrawable(final TextView view, String url, final int direction, final int iconWidth, final int iconHeight) {
ImageLoader.loadImage(view.getContext(), url, new LoadImageResult() {
@
Override
public void onResult(Bitmap bitmap) {
Drawable drawable =
new BitmapDrawable(view.getContext().getResources(), bitmap);
final int width =
DensityUtil.dipToPixels(view.getContext(), iconWidth);
final int height =
DensityUtil.dipToPixels(view.getContext(), iconHeight);
drawable.setBounds(0, 0, width, height);
switch (direction) {
case 0:
view.setCompoundDrawables(drawable, null, null, null);
break;
case 1:
view.setCompoundDrawables(null, drawable, null,
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Android 性能优化(多线程注)
- Android广播BroadcastReceiver
- wemall doraemon中Android app商城系统向指定URL发送GET方法的请求代码
- cocos2dx在Mac平台下利用Eclipse打包安卓apk安装包详细教程
- Android proguard代码混淆
- Android-Eclipse-INSTALL_FAILED_UPDATE_INCOMPATIBLE错误
- 2.Android 自定义通用的Item布局
- 3.Android 优化布局(解决TextView布局)
- Android CoordinatorLayout 入门介绍