一、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());