Fresco正传(6):如何将PhotoView与Fresco的加载机制相结合,解决超大图显示
2015-11-24 15:24
330 查看
前言
上图引狼正文
在前几篇文章中已经详细的介绍了Fresco。那么现在就具体应用学习到的东西,来看看PhotoView如何与Fresco相结合。还记得DraweeView分析这篇文章吗?在其中介绍了
DraweeView内部实际上是有一个
DraweeHolder对象,持有了
DraweeHierarchy和
DraweeController的引用。
在官方文档中,也实际一些
DraweeHolder的用法,主要是如何利用
DraweeHolder编写自定义控件,及其需要注意哪些东西。
那么也就是说,如果想要将PhotoView与Fresco结合起来,其中
DraweeHolder应该是会起到关键的作用。
其次,在官方文档中提到过,如果想到自定义控件,那么保证引用计数的正确性,这样才不会内存泄露。需要特别注意下列几个方法:
@Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); mDraweeHolder.onDetach(); } @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); mDraweeHolder.onAttach(); } @Override protected boolean verifyDrawable(Drawable dr) { super.verifyDrawable(dr); return dr == mDraweeHolder.getHierarchy().getTopLevelDrawable(); } @Override public void onStartTemporaryDetach() { super.onStartTemporaryDetach(); mDraweeHolder.onDetach(); } @Override public void onFinishTemporaryDetach() { super.onFinishTemporaryDetach(); mDraweeHolder.onAttach(); } @Override public boolean onTouchEvent(MotionEvent event) { return mDraweeHolder.onTouchEvent(event) || super.onTouchEvent(event); }
最后,如果想要展示图片需要:
创建图片请求
获取
ImagePipeline图片管道
获取数据源
获取加载数据的结果
Bitmap
设置
PhotoView的数据源
将
PhotoView与
DraweeHolder的
getTopLevelDrawable()相结合
下面是具体代码:
/** * ========================================================== <br> * <b>版权</b>: 别志华 版权所有(c) 2015 <br> * <b>作者</b>: 别志华 biezhihua@163.com<br> * <b>创建日期</b>: 2015/11/16 17:19 <br> * <b>描述</b>: <br> * <b>版本</b>: V1.0 <br> * <b>修订历史</b>: <br> * 自定义的View,我们就要处理好下面这几个函数, * 这样才能保证引用计数的正确性,否则可能就会引起内存泄露。 * 其实就是要在View移除屏幕或进入屏幕去维护好引用计数了。 * onAttachedToWindow() * onDetacherFromWindow() * onStartTemporaryDetach() * onFinishTemporaryDetach() * onTouchEvent() * ========================================================== <br> */ public class MyPhotoView extends PhotoView { private DraweeHolder<GenericDraweeHierarchy> mDraweeHolder; public MyPhotoView(Context context) { this(context, null); } public MyPhotoView(Context context, AttributeSet attr) { this(context, attr, 0); } public MyPhotoView(Context context, AttributeSet attr, int defStyle) { super(context, attr, defStyle); selfInit(); } private void selfInit() { if (mDraweeHolder == null) { final GenericDraweeHierarchy hierarchy = new GenericDraweeHierarchyBuilder(getResources()) .setProgressBarImage(new LoadingProgressDrawable(getContext())).build(); mDraweeHolder = DraweeHolder.create(hierarchy, getContext()); } } @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); mDraweeHolder.onDetach(); } @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); mDraweeHolder.onAttach(); } @Override protected boolean verifyDrawable(Drawable dr) { super.verifyDrawable(dr); return dr == mDraweeHolder.getHierarchy().getTopLevelDrawable(); } @Override public void onStartTemporaryDetach() { super.onStartTemporaryDetach(); mDraweeHolder.onDetach(); } @Override public void onFinishTemporaryDetach() { super.onFinishTemporaryDetach(); mDraweeHolder.onAttach(); } @Override public boolean onTouchEvent(MotionEvent event) { return mDraweeHolder.onTouchEvent(event) || super.onTouchEvent(event); } public void setImageUri(String uri, ResizeOptions options) { final ImageRequest imageRequest = ImageRequestBuilder.newBuilderWithSource(Uri.parse(uri)) .setResizeOptions(options) .setAutoRotateEnabled(true) .build(); final ImagePipeline imagePipeline = Fresco.getImagePipeline(); final DataSource<CloseableReference<CloseableImage>> dataSource = imagePipeline.fetchDecodedImage(imageRequest, this); final AbstractDraweeController controller = Fresco.newDraweeControllerBuilder() .setOldController(mDraweeHolder.getController()) .setImageRequest(imageRequest) .setControllerListener(new BaseControllerListener<ImageInfo>() { @Override public void onFinalImageSet(String id, ImageInfo imageInfo, Animatable animatable) { super.onFinalImageSet(id, imageInfo, animatable); CloseableReference<CloseableImage> imageCloseableReference = null; try { imageCloseableReference = dataSource.getResult(); if (imageCloseableReference != null) { final CloseableImage image = imageCloseableReference.get(); if (image != null && image instanceof CloseableStaticBitmap) { CloseableStaticBitmap closeableStaticBitmap = (CloseableStaticBitmap) image; final Bitmap bitmap = closeableStaticBitmap.getUnderlyingBitmap(); if (bitmap != null) { setImageBitmap(bitmap); // 如果是长图,让其宽度放大至与屏幕等宽 setScaleType(ScaleType.CENTER_CROP); } } } } finally { dataSource.close(); CloseableReference.closeSafely(imageCloseableReference); } } }) .build(); mDraweeHolder.setController(controller); setImageDrawable(mDraweeHolder.getTopLevelDrawable()); } }
重要问题
可能有些博友会碰到这样的问题,超级大图怎么用PhotoView显示出来呢?这个问题开始也困扰了我很久,项目中有个400*8000的图片让我头痛的不行,但是好在最后找到了办法。请看这里
最后
是不是一点也不复杂。还有Github例子的地址:https://github.com/biezhihua/MySimpleDraweeView
是其中的MyPhotoView类
相关文章推荐
- poj1163The Triangle(动态规划)
- 关于新款Mac电脑无法使用三指拖动的问题
- ORACLE中SQL查询优化研究
- Java NIO (二) Channel
- Sass@规则
- Eclipse中Server视图加载项目之后项目名后边有带括号的名字
- appium简明教程(1)——appium和它的哲学世界
- C++primer plus第六版课后编程练习答案3.1
- js 强制类型转换
- nyoj--12--喷水装置(二)(区间覆盖问题+贪心)
- iOS开发 底层抛析运行循环—— RunLoop
- SSL是啥?
- Windows查看SID
- PCL环境配置迁移指南
- Python数字
- 产品设计流程及UI设计注意事项
- libxml2库解析xml文档举例
- HTMLPARSER 爬取 html网页 获取标题 关键字 内容 url
- sql loader的用法简介
- 更改oracle字符集