PhotoDraweeView

前段时间 Facebook 祭出大杀器 Fresco,基本解决了所有 Android 图片加载需求,相比现有图片加载库,最大的亮点就是三级缓存,然后其它零零碎碎的小需求都已近写好了,用起来简单省心。于是趁着有空就开始逐步把项目里的图片加载改成 Fresco。

但在图片缩放预览就卡住了,Fresco 还不支持缩放平移等,常见的一些图片缩放库都是使用 ImageView 和 Drawable 来实现基本功能。而且 Fresco 文档里明确指出它的 DraweeView 和系统的 ImageView 将会是两个独立的控件,DraweeView 里又有许多不同特性的 Drawable,无法简单获取真正图片的 Drawable。 所以只能自己实现了,写了下面这个:

PhotoDraweeView

参照 PhotoView 和 Fresco 的一些 issues。实现了常用的双指缩放、双击缩放、平滑移动。因为 Fresco 版本升级很快,API 可能也会有少许变动,而且我也赶时间没有什么配置,所以 PhotoDraweeView 只提供 Module 导入使用,需要什么功能直接改源码好了。

使用方法如下:

// 需要使用 ControllerBuilder 方式请求图片
PipelineDraweeControllerBuilder controller = Fresco.newDraweeControllerBuilder();  
controller.setUri(URI);  
controller.setOldController(mPhotoDraweeView.getController());

// 需要设置 ControllerListener,获取图片大小后,传递给 PhotoDraweeView 更新图片长宽
controller.setControllerListener(new BaseControllerListener<ImageInfo>() {  
    @Override
    public void onFinalImageSet(String id, ImageInfo imageInfo, Animatable animatable) {
        super.onFinalImageSet(id, imageInfo, animatable);
        if (imageInfo == null || mPhotoDraweeView == null) {
            return;
        }
        mPhotoDraweeView.update(imageInfo.getWidth(), imageInfo.getHeight());
    }
});
mPhotoDraweeView.setController(controller.build());



最后吐槽一下使用 Fresco 遇到的其他问题。

  • 不能随时显示临时图片。 Fresco 内部有自己的一套图片引用计数,除了支持的 Uri 外,不能将其他地方拿到的 Bitmap 放到 DraweeView 中临时显示。

  • 使用自定义 Drawable 非常困难。比如我想用 Bitmap 处理成五角星形的 Drawable 显示。常见的图片库要达成这点也不难,而且可以避免重复创建 Bitmap 。 但是使用 Fresco 的话,呵呵…… SimpleDraweeView内部拿不到 Bitmap 或 Drawable ,使用 Image Pipeline 拿到的 Bitmap 又不能包装成自定义 Drawable 显示回去。不知道谁有精力去实现一套自定义 DraweeView。大概比较简单的方式是使用 BasePostprocessor 去修改 Bitmap, 但是很消耗系统资源。

Author

Relex

Android Developer