Android圖片加載神器之Fresco,基於各類使用場景的講解

轉載請標明出處:http://blog.csdn.net/android_ls/article/details/53137867java

Fresco是Facebook開源Android平臺上一個強大的圖片加載庫,也是迄今爲止Android平臺上最強大的圖片加載庫。android

優勢:相對於其餘開源的第三方圖片加載庫,Fresco擁有更好的內存管理和強大的功能,基本上能知足全部的平常使用場景。git

缺點:總體比較大,不過目前的版本已作了拆分,你只須要導入你使用到的功能相關的庫。從代碼層面來講侵入性太強,體如今要使用它須要用Fresco的組件SimpleDraweeView替換掉Android原生圖片顯示組件ImageView,這也是不少人不肯意在項目中接入Fresco的主要緣由。github

特性:
一、內存管理
解壓後的圖片,即Android中的Bitmap,佔用大量的內存。大的內存佔用勢必引起更加頻繁的GC。在5.0如下,GC將會顯著地引起界面卡頓。
在5.0如下系統,Fresco將圖片放到一個特別的內存區域。固然,在圖片不顯示的時候,佔用的內存會自動被釋放。這會使得APP更加流暢,減小因圖片內存佔用而引起的OOM。web

二、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對象。數組

其流程圖以下:
這裏寫圖片描述瀏覽器

三、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、當圖片再也不顯示在屏幕上時,它會及時地釋放內存和空間佔用。緩存

四、Fresco目前所支持的圖片格式
a、靜態圖:png、jpg、web
b、動態圖:gif、web格式的gifbash

以上聊了這麼多,大概意思就是Fresco出身名門,很好很強大,超牛逼!接下來咱們來聊聊在項目中的具體使用。我專門寫了一個針對Fresco的使用幫助庫(github地址:https://github.com/hpdx/fresco-helper),先給你們看看Demo的運行效果圖:
markdown

常見的各類效果

從網絡加載的圖片牆

點擊圖片牆中的照片後,打開的瀏覽大圖界面

1、Fresco的引入及ImagePipeline參數配置
一、在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'

 

二、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) { /** * 推薦緩存到應用自己的緩存文件夾,這麼作的好處是: * 一、當應用被用戶卸載後能自動清除緩存,增長用戶好感(可能之後用得着時,還會想起我) * 二、一些內存清理軟件能夠掃描出來,進行內存的清理 */ 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));

 

2、Fresco的各類使用場景

從網絡加載一張圖片

String url = "http://ww3.sinaimg.cn/large/610dc034jw1f6m4aj83g9j20zk1hcww3.jpg"; ImageLoader.loadImage((SimpleDraweeView)findViewById(R.id.sdv_1), url);

一、顯示一張圖片

<com.facebook.drawee.view.SimpleDraweeView android:id="@+id/sdv_1" android:layout_width="90dp" android:layout_height="90dp" app:actualImageScaleType="centerCrop"/>

效果圖以下:

二、顯示一張圓形圖片

<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"/>

效果圖以下:

三、顯示一張圓形帶邊框的圖片

<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"/>

效果圖以下:

四、顯示一張圓角圖片

<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"/>

效果圖以下:

五、顯示一張底部是圓角的圖片

<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"/>

效果圖以下:

六、顯示一張左上和右下是圓角的圖片

<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"/>

效果圖以下:

七、設置佔位圖

<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" />

八、帶動畫的顯示(從半透明到不透明)

<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"/>

九、圖層疊加顯示

<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"/>

十、其它的屬性的配置,好比加載進度、加載失敗、重試圖

<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"/>

十一、從本地文件(好比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);

 

十二、從本地資源(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);

 

效果圖以下:

1三、對圖片進行性高斯模糊處理

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));

效果圖以下:

1四、咱們知道使用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)); 

1五、從網絡加載並顯示gif格式的圖片

String url = "http://img4.178.com/acg1/201506/227753817857/227754566617.gif"; SimpleDraweeView simpleDraweeView = (SimpleDraweeView)findViewById(R.id.sdv_1); ImageLoader.loadImage(simpleDraweeView, url);

1六、加載並顯示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

1七、從內存緩存中移除指定圖片的緩存

if (!TextUtils.isEmpty(photoInfo.originalUrl)) { ImagePipeline imagePipeline = Fresco.getImagePipeline(); Uri uri = Uri.parse(photoInfo.originalUrl); if (imagePipeline.isInBitmapMemoryCache(uri)) { imagePipeline.evictFromMemoryCache(uri); } }

1八、從磁盤緩存中移除指定圖片的緩存

ImagePipeline imagePipeline = Fresco.getImagePipeline(); Uri uri = Uri.parse(photoInfo.originalUrl); // 下面的操做是異步的 if (imagePipeline.isInDiskCacheSync(uri)) { imagePipeline.evictFromDiskCache(uri); }

1九、清空磁盤緩存

Fresco.getImagePipeline().clearDiskCaches();

 

20、清空內存緩存

Fresco.getImagePipeline().clearMemoryCaches();

 

2一、清空緩存(內存緩存 + 磁盤緩存)

Fresco.getImagePipeline().clearCaches();

 

2二、在列表視圖滾動時,不加載圖片,等滾動中止後再開始加載圖片,提高列表視圖的滾動流暢度。

// 須要暫停網絡請求時調用 public static void pause(){ Fresco.getImagePipeline().pause(); } // 須要恢復網絡請求時調用 public static void resume(){ Fresco.getImagePipeline().resume(); }

2三、下載圖片存儲到指定的路徑

/** * 從網絡下載圖片 * 一、根據提供的圖片URL,獲取圖片數據流 * 二、將獲得的數據流寫入指定路徑的本地文件 * * @param url URL * @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() { } });

2四、不使用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, null); break; case 2: view.setCompoundDrawables(null, null, drawable, null); break; case 3: view.setCompoundDrawables(null, null, null, drawable); break; } } }); }

3、推薦的使用方法

一、第一種用法

初始化

Phoenix.init(this); // Context

 

從網絡加載一張圖片

String url = "http://ww3.sinaimg.cn/large/610dc034jw1f6m4aj83g9j20zk1hcww3.jpg"; SimpleDraweeView simpleDraweeView = (SimpleDraweeView)findViewById(R.id.sdv_1); Phoenix.with(simpleDraweeView).load(url);

從本地加載一張圖片

String filePath = "/sdcard/image/test.jpg"; SimpleDraweeView simpleDraweeView = (SimpleDraweeView)findViewById(R.id.sdv_1); Phoenix.with(simpleDraweeView).load(filePath);

從res下面加載一張圖片

SimpleDraweeView simpleDraweeView = (SimpleDraweeView)findViewById(R.id.sdv_1); Phoenix.with(simpleDraweeView).load(R.drawable.meizi);

在寫佈局文件xml時,我不知道要顯示的圖片尺寸,須要根據業務邏輯動態的設置要顯示的圖片的大小,能夠像下面這樣寫:

String url = "http://ww3.sinaimg.cn/large/610dc034jw1f6m4aj83g9j20zk1hcww3.jpg"; SimpleDraweeView simpleDraweeView = (SimpleDraweeView)findViewById(R.id.sdv_1); Phoenix.with(simpleDraweeView) .setWidth(100) .setHeight(100) .load(url);

只知道要顯示圖片的高或者寬的值,另外一個值能夠從設置的比例得出

String url = "http://ww3.sinaimg.cn/large/610dc034jw1f6m4aj83g9j20zk1hcww3.jpg"; SimpleDraweeView simpleDraweeView = (SimpleDraweeView)findViewById(R.id.sdv_1); Phoenix.with(simpleDraweeView) .setWidth(100) .setAspectRatio(0.6f) // w/h = 6/10 .load(url);

圖片的高斯模糊處理

String url = "http://ww3.sinaimg.cn/large/610dc034jw1f6m4aj83g9j20zk1hcww3.jpg"; SimpleDraweeView simpleDraweeView = (SimpleDraweeView)findViewById(R.id.sdv_1); Phoenix.with(simpleDraweeView) .setNeedBlur(true) .load(url);

加載並顯示gif格式的圖片

String url = "http://img4.178.com/acg1/201506/227753817857/227754566617.gif"; SimpleDraweeView simpleDraweeView = (SimpleDraweeView)findViewById(R.id.sdv_1); Phoenix.with(simpleDraweeView) .load(url);

加載並顯示webp格式的圖片

SimpleDraweeView simpleDraweeView = (SimpleDraweeView)findViewById(R.id.sdv_1); Phoenix.with(simpleDraweeView) .load(R.drawable.meizi_webp);

……

二、第二種用法

初始化

Fresco.initialize(context, ImageLoaderConfig.getImagePipelineConfig(context));

 

從網絡加載一張圖片

String url = "http://ww3.sinaimg.cn/large/610dc034jw1f6m4aj83g9j20zk1hcww3.jpg"; SimpleDraweeView simpleDraweeView = (SimpleDraweeView)findViewById(R.id.sdv_1); ImageLoader.loadImage(simpleDraweeView, url);

從本地加載一張圖片

String filePath = "/sdcard/image/test.jpg"; SimpleDraweeView simpleDraweeView = (SimpleDraweeView)findViewById(R.id.sdv_1); ImageLoader.loadFile(simpleDraweeView, filePath);

從res下面加載一張圖片

SimpleDraweeView simpleDraweeView = (SimpleDraweeView)findViewById(R.id.sdv_1); ImageLoader.loadDrawable(simpleDraweeView, R.drawable.meizi, 100, 100);

在寫佈局文件xml時,我不知道要顯示的圖片尺寸,須要根據業務邏輯動態的設置要顯示的圖片的大小,能夠像下面這樣寫:

String url = "http://ww3.sinaimg.cn/large/610dc034jw1f6m4aj83g9j20zk1hcww3.jpg"; SimpleDraweeView simpleDraweeView = (SimpleDraweeView)findViewById(R.id.sdv_1); ImageLoader.loadImage(simpleDraweeView, url, 120, 120);

只知道要顯示圖片的高或者寬的值,另外一個值能夠從設置的比例得出

String url = "http://ww3.sinaimg.cn/large/610dc034jw1f6m4aj83g9j20zk1hcww3.jpg"; 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);

圖片的高斯模糊處理

String url = "http://ww3.sinaimg.cn/large/610dc034jw1f6m4aj83g9j20zk1hcww3.jpg"; SimpleDraweeView simpleDraweeView = (SimpleDraweeView)findViewById(R.id.sdv_1); ImageLoader.loadImageBlur(simpleDraweeView, url);

加載並顯示gif格式的圖片

String url = "http://img4.178.com/acg1/201506/227753817857/227754566617.gif"; SimpleDraweeView simpleDraweeView = (SimpleDraweeView)findViewById(R.id.sdv_1); ImageLoader.loadImage(simpleDraweeView, url);

加載並顯示webp格式的圖片

SimpleDraweeView simpleDraweeView = (SimpleDraweeView)findViewById(R.id.sdv_1); ImageLoader.loadDrawable(simpleDraweeView, R.drawable.meizi_webp);

……

三、大圖瀏覽器
帶動畫的效果打開方式,詳細細節請查看PhotoWallActivity中的使用

ArrayList<PhotoInfo> photos = null; PictureBrowse.newBuilder(PhotoWallActivity.this) .setParentView(parent) .setCurrentPosition(position) .setPhotoList(photos) .enabledAnimation(true) .build() .start();

無動畫效果的打開方式

ArrayList<PhotoInfo> photos = null; PictureBrowse.newBuilder(PhotoWallActivity.this) .setParentView(parent) .setCurrentPosition(position) .setPhotoList(photos) .build() .start();

我提供了兩種圖片加載使用方式,你想使用那種圖片加載方式,全看我的愛好(推薦使用第一種方式)。

文中的照片牆實現:https://github.com/hpdx/fresco-photoview (原來是包含在fresco-helper中的,後來作了拆分)

代碼我已上傳到github上了,地址:https://github.com/hpdx/fresco-helper

相關文章
相關標籤/搜索