标签: Fresco

Android图片加载神器之Fresco,基于各种使用场景的讲解

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的使用帮助库,先给大家看看Demo的运行效果图:
%title插图%num

常见的各种效果
%title插图%num

从网络加载的图片墙
%title插图%num

点击图片墙中的照片后,打开的浏览大图界面
%title插图%num

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

 

效果图如下:
%title插图%num

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

 

效果图如下:
%title插图%num

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

 

效果图如下:
%title插图%num

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

 

效果图如下:
%title插图%num

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

 

效果图如下:
%title插图%num

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

 

效果图如下:
%title插图%num

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

 

效果图如下:
%title插图%num

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

 

效果图如下:
%title插图%num

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 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() {

        }
    });

 

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

 

三、推荐的使用方法

1、*种用法

初始化

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

 

……

2、第二种用法

初始化

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

 

……

3、大图浏览器
带动画的效果打开方式,详细细节请查看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();

 

我提供了两种图片加载使用方式,你想使用那种图片加载方式,全看个人爱好(推荐使用*种方式)。

【Android – 框架】之Fresco的使用

当下有很多图片加载框架,常见的有Glide、Fresco、Picasso等。Glide因为其体积小、缓存机制强大等优点,受到了广大程序员的青睐;Fresco虽然体积比较大,缓存机制也没有Glide强大,但它胜在拥有一些炫酷的效果(进度条、淡入效果)等,也有很多人在使用。今天我们就来介绍一下Fresco的使用。

先贴出【Fresco的中文官方文档】。

 

1、配置环境

使用Fresco需要先在build.gradle中导入依赖:

    // Fresco所需依赖
    compile 'com.facebook.fresco:fresco:0.12.0'
    // 在 API < 14 上的机器支持 WebP 时,需要添加
    compile 'com.facebook.fresco:animated-base-support:0.12.0'
    // 支持 GIF 动图,需要添加
    compile 'com.facebook.fresco:animated-gif:0.12.0'
    // 支持 WebP (静态图+动图),需要添加
    compile 'com.facebook.fresco:animated-webp:0.12.0'
    compile 'com.facebook.fresco:webpsupport:0.12.0'

 

如果需要从网络中下载图片,则需要在AndroidManifest.xml文件中配置网络权限:

<uses-permission android:name="android.permission.INTERNET" />

 

*后,在项目的Application中初始化Fresco:

public class MyApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();
        // 初始化Fresco
        Fresco.initialize(this);
    }
}

 

别忘了在AndroidManifest.xml文件中为Application添加name属性:

    <application
        android:name=".MyApplication"
        ......
    </application>

 

2、SimpleDraweeView

2.1、XML属性

Fresco为我们提供了一个SimpleDraweeView控件,我们可以直接在这个控件中加载图片。Fresco在这个控件中集成了很多属性,简单实用。以下是SimpleDraweeView中的常用属性:

        fresco:actualImageScaleType:实际加载的图片的伸缩样式
        fresco:backgroundImage:底层图片资源
        fresco:fadeDuration:进度条和占位符图片逐渐消失、加载的图片逐渐显示的时间间隔
        fresco:failureImage:加载失败时显示的图片资源
        fresco:failureImageScaleType:加载失败时加载的图片的伸缩样式
        fresco:overlayImage:在显示的图片表层覆盖一张图片的图片资源
        fresco:placeholderImage:占位符图片资源
        fresco:placeholderImageScaleType:占位符图片的伸缩样式
        fresco:progressBarAutoRotateInterval:进度条图片转动周期
        fresco:progressBarImage:进度条图片资源
        fresco:progressBarImageScaleType:进度条图片的伸缩样式
        fresco:retryImage:提示重新加载的图片资源
        fresco:retryImageScaleType:提示重新加载的图片的伸缩样式
        fresco:roundAsCircle:将图片剪切成圆形
        fresco:viewAspectRatio:图片宽高比

 

我们的XML布局文件中的代码如下:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:fresco="http://schemas.android.com/apk/res-auto"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.facebook.drawee.view.SimpleDraweeView
        android:id="@+id/id_main_sdv_sdv"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        fresco:actualImageScaleType="focusCrop"
        fresco:fadeDuration="3000"
        fresco:failureImage="@mipmap/ic_launcher"
        fresco:failureImageScaleType="centerInside"
        fresco:placeholderImage="@mipmap/ic_launcher"
        fresco:placeholderImageScaleType="fitCenter"
        fresco:progressBarAutoRotateInterval="1000"
        fresco:progressBarImage="@mipmap/ic_launcher"
        fresco:progressBarImageScaleType="centerInside"
        fresco:retryImage="@mipmap/ic_launcher"
        fresco:retryImageScaleType="centerCrop"
        fresco:roundAsCircle="false"
        fresco:viewAspectRatio="1.6" />

    <Button
        android:id="@+id/id_main_btn_load"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_margin="20.0dip"
        android:text="Start Load Image" />

</RelativeLayout>

 

2.2、注意事项

(1)SimpleDraweeView控件的宽高不能设置为wrap_content,只能是match_parent、具体值或使用viewAspectRatio属性设置宽高比。

(2)如果在一个页面中加载多张图片,不要将SimpleDraweeView直接放在ScollView中,建议使用RecyclerView、ListView或GridView,因为ScrollView中的SimpleDraweeView会持有内存直到Activity或Fragment销毁。

(3)使用SimpleDraweeView时,不要使用imageView中有、View中没有的属性。

3、框架使用

3.1、简单使用

像TextView、Button等其他控件一样后去到SimpleDraweeView,然后调用如下代码即可加载网络图片:

SimpleDraweeView sdv = (SimpleDraweeView) findViewById(R.id.id_main_sdv_sdv);
sdv.setImageURI("http://image5.tuku.cn/pic/wallpaper/fengjing/menghuandaziranmeijingbizhi/009.jpg");

 

3.2、JAVA代码设置属性

我们可以通过GenericDraweeHierarchy,在JAVA代码中动态的设置SimpleDraweeView控件的属性。需要注意的是,如果在JAVA代码中设置了属性,那么XML文件中设置的属性就都无效了。一个实例代码如下:

        // 代码设置SimpleDraweeView的属性(会覆盖XML设置的所有属性,即在XML中有在这里没有的属性都会失效)
        // 注意:一个GenericDraweeHierarchy是不能被多个SimpleDraweeView共用的
        GenericDraweeHierarchy hierarchy = new GenericDraweeHierarchyBuilder(getResources())
                .setFadeDuration(3000)
                .setPlaceholderImage(R.mipmap.ic_launcher)
                .setPlaceholderImageScaleType(ScalingUtils.ScaleType.FIT_XY)
                .setProgressBarImage(new ProgressBarDrawable()) // 显示进度条(Fresco自带的进度条)
                .build();
        // 设置图片圆角
        RoundingParams roundingParams = new RoundingParams();
        roundingParams.setRoundAsCircle(false); // 不将图片剪切成圆形
        roundingParams.setCornersRadius(200);
        hierarchy.setRoundingParams(roundingParams);
        // 为SimpleDraweeView设置属性
        sdv.setHierarchy(hierarchy);

 

注意:不能把同一个GenericDraweeHierarchy对象设置给多个SimpleDraweeView!

 

3.3、设置下载事件

        sdv.setController(Fresco.newDraweeControllerBuilder()
                .setControllerListener(new BaseControllerListener<ImageInfo>() {
                    @Override
                    public void onFinalImageSet(String id, ImageInfo imageInfo, Animatable animatable) {
                        // 所有图片都加载成功时触发的方法
                        int width = imageInfo.getWidth();
                        int height = imageInfo.getHeight();
                        QualityInfo qualityInfo = imageInfo.getQualityInfo();
                        int quality = qualityInfo.getQuality();
                        boolean isOfFullQuality = qualityInfo.isOfFullQuality();
                        boolean isOfGoodEnoughQuality = qualityInfo.isOfGoodEnoughQuality();
                    }

                    @Override
                    public void onIntermediateImageSet(String id, ImageInfo imageInfo) {
                        // 加载渐进式图片时回调的方法
                    }

                    @Override
                    public void onFailure(String id, Throwable throwable) {
                        // 加载图片失败时回调的方法
                    }
                })
                .setUri("http://image5.tuku.cn/pic/wallpaper/fengjing/menghuandaziranmeijingbizhi/009.jpg")
                .build());

 

3.4、渐进式图片

渐进式图片是一种支持图片从模糊到清晰的加载模式。代码如下:

                sdv.setController(Fresco.newDraweeControllerBuilder()
                        .setImageRequest(
                                ImageRequestBuilder.newBuilderWithSource(
                                        Uri.parse("http://image5.tuku.cn/pic/wallpaper/fengjing/menghuandaziranmeijingbizhi/009.jpg"))
                                        .setProgressiveRenderingEnabled(true)
                                        .build())
                        .setOldController(sdv.getController())
                        .build());

 

以上就是对Fresco的基本使用方法的介绍,希望对大家有帮助~~~

Fresco的使用

引入Fresco

dependencies {
  // 添加依赖
  compile 'com.facebook.fresco:fresco:0.13.0'
}

开始使用 Fresco

1.进行全局初始化,添加网络权限

// 需要在 AndroidManifest.xml 中指定你的 Application 类
// android:name=".MyApplication"
public class MyApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        // onCreate()进行初始化
        Fresco.initialize(this);
    }
}

2.布局

<!-- 在xml布局文件中, 加入命名空间:-->
xmlns:fresco="http://schemas.android.com/apk/res-auto"

2.1.使用控件SimpleDraweeView(不使用ImageView)

<com.facebook.drawee.view.SimpleDraweeView
    android:id="@+id/my_image_view"
    android:layout_width="130dp"
    android:layout_height="130dp"
    fresco:placeholderImage="@drawable/my_drawable"
  />

2.2.注意:Drawees 不支持 wrap_content 属性,只能使用固定宽高(xx dp,match_parent),如果想使用wrap_content需要配合viewAspectRatio属性来使用。

<!-- placeholderImage:占位图
     placeholderImageScaleType:占位图缩放类型
     viewAspectRatio:固定宽高比例
     如果希望图片以特定的宽高比例显示,例如 1:1,
     fresco:viewAspectRatio="1"
     如果是 4:3 则改为1.33
     也可以在代码中指定显示比例:
     mSimpleDraweeView.setAspectRatio(1.33f);  -->
<com.facebook.drawee.view.SimpleDraweeView
    android:id="@+id/my_image_view"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    fresco:placeholderImage="@drawable/my_drawable"
    fresco:placeholderImageScaleType="fitXY"
    fresco:viewAspectRatio="1"
  />

3.开始加载图片:

Uri uri = Uri.parse("https://www.baidu.com/img/bd_logo1.png");
SimpleDraweeView draweeView = (SimpleDraweeView) findViewById(R.id.my_image_view);
draweeView.setImageURI(uri);

4.剩下的,Fresco会替你完成:

  • 显示占位图直到加载完成;
  • 下载图片;
  • 缓存图片;
  • 图片不再显示时,从内存中移除;
  • 等等等等。

Fresco的使用及注意事项

Fresco的使用及注意事项

添加引用

1.build.gradle添加依赖

compile 'com.facebook.fresco:fresco:0.12.0'
//以下是加载Gif使用,按需添加
compile 'com.facebook.fresco:animated-gif:0.12.0'

2.配置Jni库

根据需要配置需要的jni库,在module的build.gradle中配置

buildTypes {
    debug {
        ndk {
            abiFilters = ["armeabi"]
        }
        ...
    }
}

基本使用

1.初始化

在Application中或者MainActivity中调用:

Fresco.initialize(this);

2.加载基本的图片

加载图片一般是给SimpleDraweeView添加Uri,具体的参见Fresco加载图片封装

注意事项

1.列表中加载图片,滚动时请暂停加载.

我们经常在列表中显示图片,为了减少列表的卡顿现象,需要在列表滚动时暂停加载图片,当停止滚动时再恢复加载.

ListView中设置暂停恢复加载:

listView.setOnScrollListener(new AbsListView.OnScrollListener() {
    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
        switch (scrollState) {
            case AbsListView.OnScrollListener.SCROLL_STATE_FLING:
            case AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL:
                //ImageLoader.pauseLoader();
                if (!Fresco.getImagePipeline().isPaused()) {
                    Fresco.getImagePipeline().pause();
                }
                break;
            case AbsListView.OnScrollListener.SCROLL_STATE_IDLE:
            //ImageLoader.resumeLoader();
                if (Fresco.getImagePipeline().isPaused()) {
                    Fresco.getImagePipeline().resume();
                }
                break;
        }
    }

    @Override
    public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {

    }
});

RecyclerView与ListView类似,请自行设置.

2.图片必须设置为具体尺寸或者match_parent

3.清除缓存

当图片改变时我们需要清除缓存重新加载,可调用Fresco提供的方法.清除缓存分为清除内存缓存和清除磁盘缓存.

public static void clearDiskCache(Uri uri) {
    Fresco.getImagePipeline().evictFromDiskCache(uri);
}

public static void clearMemoryCache(Uri uri) {
    Fresco.getImagePipeline().evictFromMemoryCache(uri);
}

未完待续…

Fresco还在使用中,此文会随着使用更新注意事项.

Fresco对Listview等快速滑动时停止加载

Fresco对Listview等快速滑动时停止加载

Fresco中在listview之类的快速滑动时停止加载,滑动停止后恢复加载:

1.设置图片请求是否开启
  1. // 暂停图片请求  
  2. public static void imagePause() {  
  3.     Fresco.getImagePipeline().pause();
  4. }
  5. // 恢复图片请求  
  6. public static void imageResume() {  
  7.     Fresco.getImagePipeline().resume();
  8. }
2.设置ListView滚动监听
  1. <pre name=“code” class=”java”><pre name=”code” class=”java”>mListView.setOnScrollListener(new AbsListView.OnScrollListener() {  
  2.     @Override  
  3.     public void onScrollStateChanged(AbsListView view, int scrollState) {  
  4.         switch(scrollState){  
  5.             case AbsListView.OnScrollListener.SCROLL_STATE_IDLE://空闲状态  
  6.                 imageResume();
  7.                 break;  
  8.             case AbsListView.OnScrollListener.SCROLL_STATE_FLING://滚动状态  
  9.                 imagePause();
  10.                 break;  
  11.             case AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL://触摸后滚动  
  12.                 break;  
  13.         }
  14.     }
  15.     public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) {  
  16.     }
  17. });

 

就是这么多,赶紧试试吧!
友情链接: SITEMAP | 旋风加速器官网 | 旋风软件中心 | textarea | 黑洞加速器 | jiaohess | 老王加速器 | 烧饼哥加速器 | 小蓝鸟 | tiktok加速器 | 旋风加速度器 | 旋风加速 | quickq加速器 | 飞驰加速器 | 飞鸟加速器 | 狗急加速器 | hammer加速器 | trafficace | 原子加速器 | 葫芦加速器 | 麦旋风 | 油管加速器 | anycastly | INS加速器 | INS加速器免费版 | 免费vqn加速外网 | 旋风加速器 | 快橙加速器 | 啊哈加速器 | 迷雾通 | 优途加速器 | 海外播 | 坚果加速器 | 海外vqn加速 | 蘑菇加速器 | 毛豆加速器 | 接码平台 | 接码S | 西柚加速器 | 快柠檬加速器 | 黑洞加速 | falemon | 快橙加速器 | anycast加速器 | ibaidu | moneytreeblog | 坚果加速器 | 派币加速器 | 飞鸟加速器 | 毛豆APP | PIKPAK | 安卓vqn免费 | 一元机场加速器 | 一元机场 | 老王加速器 | 黑洞加速器 | 白石山 | 小牛加速器 | 黑洞加速 | 迷雾通官网 | 迷雾通 | 迷雾通加速器 | 十大免费加速神器 | 猎豹加速器 | 蚂蚁加速器 | 坚果加速器 | 黑洞加速 | 银河加速器 | 猎豹加速器 | 海鸥加速器 | 芒果加速器 | 小牛加速器 | 极光加速器 | 黑洞加速 | movabletype中文网 | 猎豹加速器官网 | 烧饼哥加速器官网 | 旋风加速器度器 | 哔咔漫画 | PicACG | 雷霆加速