图片加载框架Fresco使用总结

本文总结了Fresco在Android中的使用,包括配置全局参数、SimpleDraweeView的属性介绍及如何在Java代码中控制图片显示。Fresco支持内存和磁盘缓存,并提供了不支持wrap_content属性的SimpleDraweeView,允许在运行时动态调整显示效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、Fresco配置

这里的配置是Fresco加载图片全局的配置,主要是设置内存缓存,磁盘缓存,图片配置等参数。负责配置相关的类是ImagePipelineConfig,在使用Fresco前需要初始化Fresco,传入的参数是ImagePipelineConfig:

Fresco.initialize(this, ImagePipelineConfigFactory.getOkHttpImagePipelineConfig(this));

下面是整个配置的一个工厂类,包含正常网络加载的配置和使用OKhttp网络库加载的配置。


public class ImagePipelineConfigFactory {
    private static final int MAX_HEAP_SIZE = (int) Runtime.getRuntime().maxMemory();
    public static final int MAX_DISK_CACHE_SIZE = 40 * ByteConstants.MB;
    public static final int MAX_MEMORY_CACHE_SIZE = MAX_HEAP_SIZE / 4;
    private static final String IMAGE_PIPELINE_CACHE_DIR = "imagepipeline_cache";
    private static ImagePipelineConfig sImagePipelineConfig;
    private static ImagePipelineConfig sOkHttpImagePipelineConfig;

    /**
     * 使用Android自带的网络加载图片
     */
    public static ImagePipelineConfig getImagePipelineConfig(Context context) {
        if (sImagePipelineConfig == null) {
            ImagePipelineConfig.Builder configBuilder = ImagePipelineConfig.newBuilder(context);
            configBuilder.setProgressiveJpegConfig(mProgressiveJpegConfig);
            configBuilder.setBitmapsConfig(Bitmap.Config.ARGB_4444);
            configureCaches(configBuilder, context);
            configureLoggingListeners(configBuilder);
            configureOptions(configBuilder);
            sImagePipelineConfig = configBuilder.build();
        }
        return sImagePipelineConfig;
    }

    /**
     * 使用OkHttp网络库加载图片
     */
    public static ImagePipelineConfig getOkHttpImagePipelineConfig(Context context) {
        if (sOkHttpImagePipelineConfig == null) {
            OkHttpClient okHttpClient = new OkHttpClient();
            ImagePipelineConfig.Builder configBuilder =
                    OkHttpImagePipelineConfigFactory.newBuilder(context, okHttpClient);
            configureCaches(configBuilder, context);
            configureLoggingListeners(configBuilder);
            sOkHttpImagePipelineConfig = configBuilder.build();
        }
        return sOkHttpImagePipelineConfig;
    }

    /**
     * 配置内存缓存和磁盘缓存
     */
    private static void configureCaches(
            ImagePipelineConfig.Builder configBuilder,
            Context context) {
        final MemoryCacheParams bitmapCacheParams = new MemoryCacheParams(
                MAX_MEMORY_CACHE_SIZE, // Max total size of elements in the cache
                Integer.MAX_VALUE,                     // Max entries in the cache
                MAX_MEMORY_CACHE_SIZE, // Max total size of elements in eviction queue
                Integer.MAX_VALUE,                     // Max length of eviction queue
                Integer.MAX_VALUE);                    // Max cache entry size
        configBuilder
                .setBitmapMemoryCacheParamsSupplier(
                        new Supplier<MemoryCacheParams>() {
                            public MemoryCacheParams get() {
                                return bitmapCacheParams;
                            }
                        })
                .setMainDiskCacheConfig(
                        DiskCacheConfig.newBuilder()
                                .setBaseDirectoryPath(context.getApplicationContext().getCacheDir())
                                .setBaseDirectoryName(IMAGE_PIPELINE_CACHE_DIR)
                                .setMaxCacheSize(MAX_DISK_CACHE_SIZE)
                                .build());
    }

    private static void configureLoggingListeners(ImagePipelineConfig.Builder configBuilder) {
        Set<RequestListener> requestListeners = new HashSet<>();
        requestListeners.add(new RequestLoggingListener());
        configBuilder.setRequestListeners(requestListeners);
    }

    private static void configureOptions(ImagePipelineConfig.Builder configBuilder) {
        configBuilder.setDownsampleEnabled(true);
    }

    //渐进式图片
    static ProgressiveJpegConfig mProgressiveJpegConfig = 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);
        }
    };
}

二、SimpleDraweeView 属性介绍

 <com.facebook.drawee.view.SimpleDraweeView
        android:id="@+id/my_image_view"
        android:layout_width="match_parent"
        android:layout_height="300dp"
        fresco:fadeDuration="300"
        fresco:actualImageScaleType="focusCrop"
        fresco:placeholderImage="@color/placeholder"
        fresco:placeholderImageScaleType="fitCenter"
        fresco:failureImage="@drawable/hairshare_image_loading"
        fresco:failureImageScaleType="centerInside"
        fresco:retryImage="@drawable/retrying"
        fresco:retryImageScaleType="centerCrop"
        fresco:progressBarImage="@drawable/progress_bar"
        fresco:progressBarImageScaleType="centerInside"
        fresco:progressBarAutoRotateInterval="1000"
        fresco:backgroundImage="@android:color/holo_blue_light"
        fresco:overlayImage="@drawable/watermark"
        fresco:pressedStateOverlayImage="@android:color/holo_red_light"
        fresco:roundAsCircle="false"
        fresco:roundedCornerRadius="5dp"
        fresco:roundTopLeft="true"
        fresco:roundTopRight="false"
        fresco:roundBottomLeft="false"
        fresco:roundBottomRight="true"
        fresco:roundWithOverlayColor="@android:color/holo_green_light"
        fresco:roundingBorderWidth="2dp"
        fresco:roundingBorderColor="@android:color/holo_orange_dark"/>

上面包含SimpleDraweeView 定义的一些属性,通常是同时用不到这么多的。对于SimpleDraweeView ,不支持 wrap_content 属性,只有固定宽高比时,宽高中的一个可以使用wrap_content。

各个属性的含义可以参照attr中定义的属性

 <!-- 图片显示时,淡入淡出动画的时间,单位为毫秒-->
    <attr name="fadeDuration" format="integer"/>
    <!-- 设置的View宽高的比例 -->
    <attr name="viewAspectRatio" format="float"/>
    <!-- 图片显示前的占位图片,可以为drawable或者color-->

    <attr name="placeholderImage" format="reference"/>
    <!-- 占位图缩放种类 -->
    <attr name="placeholderImageScaleType">
      <enum name="none" value="-1" />
      <enum name="fitXY" value="0" />
      <enum name="fitStart" value="1" />
      <enum name="fitCenter" value="2" />
      <enum name="fitEnd" value="3" />
      <enum name="center" value="4" />
      <enum name="centerInside" value="5" />
      <enum name="centerCrop" value="6" />
      <enum name="focusCrop" value="7" />
    </attr>

    <!-- 重新加载图片占位 -->
    <attr name="retryImage" format="reference"/>
    <!-- 重新加载图片占位缩放种类 -->
    <attr name="retryImageScaleType">
      <enum name="none" value="-1" />
      <enum name="fitXY" value="0" />
      <enum name="fitStart" value="1" />
      <enum name="fitCenter" value="2" />
      <enum name="fitEnd" value="3" />
      <enum name="center" value="4" />
      <enum name="centerInside" value="5" />
      <enum name="centerCrop" value="6" />
      <enum name="focusCrop" value="7" />
    </attr>

    <!-- 加载失败显示的图片 -->
    <attr name="failureImage" format="reference"/>
    <!-- 加载失败显示的图片缩放种类 -->
    <attr name="failureImageScaleType">
      <enum name="none" value="-1" />
      <enum name="fitXY" value="0" />
      <enum name="fitStart" value="1" />
      <enum name="fitCenter" value="2" />
      <enum name="fitEnd" value="3" />
      <enum name="center" value="4" />
      <enum name="centerInside" value="5" />
      <enum name="centerCrop" value="6" />
      <enum name="focusCrop" value="7" />
    </attr>

    <!-- 加载图片过程中显示进度的图片 -->
    <attr name="progressBarImage" format="reference"/>
    <!-- 加载图片过程中显示进度的图片缩放种类 -->
    <attr name="progressBarImageScaleType">
      <enum name="none" value="-1" />
      <enum name="fitXY" value="0" />
      <enum name="fitStart" value="1" />
      <enum name="fitCenter" value="2" />
      <enum name="fitEnd" value="3" />
      <enum name="center" value="4" />
      <enum name="centerInside" value="5" />
      <enum name="centerCrop" value="6" />
      <enum name="focusCrop" value="7" />
    </attr>
    <!--进度条旋转的的间隔,单位为毫秒-->
    <attr name="progressBarAutoRotateInterval" format="integer"/>

    <!-- 加载图片的缩放种类. -->
    <attr name="actualImageScaleType">
      <enum name="none" value="-1" />
      <enum name="fitXY" value="0" />
      <enum name="fitStart" value="1" />
      <enum name="fitCenter" value="2" />
      <enum name="fitEnd" value="3" />
      <enum name="center" value="4" />
      <enum name="centerInside" value="5" />
      <enum name="centerCrop" value="6" />
      <enum name="focusCrop" value="7" />
    </attr>

    <!-- 背景,可以为drawable或者color -->
    <attr name="backgroundImage" format="reference"/>
    <!-- 覆盖在图片上的背景,可以为drawable或者color -->
    <attr name="overlayImage" format="reference"/>
    <!--View按压时的背景,可以为drawable或者color -->
    <attr name="pressedStateOverlayImage" format="reference"/>

    <!-- 显示为圆形图片 -->
    <attr name="roundAsCircle" format="boolean"/>
    <!-- 圆角的半径 -->
    <attr name="roundedCornerRadius" format="dimension"/>

    <!-- 下面四个属性用于控制图片四个角是否为圆角 -->
    <attr name="roundTopLeft" format="boolean"/>
    <attr name="roundTopRight" format="boolean"/>
    <attr name="roundBottomRight" format="boolean"/>

    <!-- 圆外面的覆盖的颜色 -->
    <attr name="roundWithOverlayColor" format="color"/>
    <!-- 边界的宽度-->
    <attr name="roundingBorderWidth" format="dimension"/>
    <!-- 边界的的颜色 -->
    <attr name="roundingBorderColor" format="color"/>

三、Java代码中使用SimpleDraweeView
有时需要在运行时根据业务逻辑,控制图片的显示,这时需要在Java代码中控制SimpleDraweeView,各种效果控制的代码:

 SimpleDraweeView simpleDraweeView = (SimpleDraweeView) findViewById(R.id.mSimpleDraweeView);

//对Bitmap进行后处理
        Postprocessor redMeshPostprocessor = new BasePostprocessor() {
            @Override
            public String getName() {
                return "redMeshPostprocessor";
            }

            @Override
            public void process(Bitmap bitmap) {
                for (int x = 0; x < bitmap.getWidth(); x+=2) {
                    for (int y = 0; y < bitmap.getHeight(); y+=2) {
                        bitmap.setPixel(x, y, Color.RED);
                    }
                }
            }
        };

        ImageRequest imageRequest = ImageRequestBuilder
                .newBuilderWithSource(Uri.parse(Constants.IMAGES[9]))
                .setProgressiveRenderingEnabled(true)
                //重新设置图片尺寸
                .setResizeOptions(new ResizeOptions(200, 100))
                .setAutoRotateEnabled(true)
                .setPostprocessor(redMeshPostprocessor)
                .build();

//监听图片下载过程
        ControllerListener controllerListener = new BaseControllerListener<ImageInfo>() {
            @Override
            public void onFinalImageSet(String id, @Nullable ImageInfo imageInfo, @Nullable Animatable anim) {
            }

            @Override
            public void onIntermediateImageSet(String id, @Nullable ImageInfo imageInfo) {

            }

            @Override
            public void onFailure(String id, Throwable throwable) {

            }
        };


        DraweeController draweeController = Fresco.newDraweeControllerBuilder()
                .setAutoPlayAnimations(true)
                .setImageRequest(imageRequest)
                .setControllerListener(controllerListener)
                .build();

        //设置圆角
        RoundingParams roundingParams = RoundingParams.fromCornersRadius(10)
                .setRoundingMethod(RoundingParams.RoundingMethod.BITMAP_ONLY);
        roundingParams.setCornersRadii(10, 10, 0, 0);


        GenericDraweeHierarchy genericDraweeHierarchy = new GenericDraweeHierarchyBuilder(getResources())
                .setRoundingParams(roundingParams)
                //设置缩放类型
                .setActualImageScaleType(ScalingUtils.ScaleType.CENTER)
                //设置加载图片的淡入淡出的时间
                .setFadeDuration(300)
                //设置加载的进度条
                .setProgressBarImage(new ProgressBarDrawable())
                .build();

        simpleDraweeView.setHierarchy(genericDraweeHierarchy);
        //设置宽高比例
        simpleDraweeView.setAspectRatio(0.8f);
        simpleDraweeView.setController(draweeController);

四、Fresco获取Bitmap

 // To get image using Fresco
ImageRequest imageRequest = ImageRequestBuilder.newBuilderWithSource(Uri.parse(getFeedItem(position).feedImageUrl.get(index))).setProgressiveRenderingEnabled(true).build();
        ImagePipeline imagePipeline = Fresco.getImagePipeline();
        DataSource<CloseableReference<CloseableImage>> dataSource = imagePipeline.fetchDecodedImage(imageRequest, mContext);
        dataSource.subscribe(new BaseBitmapDataSubscriber() {
            @Override
            public void onNewResultImpl(@Nullable Bitmap bitmap) {
                // You can use the bitmap in only limited ways
                // No need to do any cleanup.

            }
            @Override
            public void onFailureImpl(DataSource dataSource) {
                // No cleanup required here.
            }
        }, CallerThreadExecutor.getInstance());
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值