安卓大图加载开源库LargeImage源码解析

开源库地址:https://github.com/LuckyJayce/LargeImage

先上原作者对此开源的简介,后面我们会有详细的介绍

LargeImage简介

Android 加载大图 可以高清显示10000*10000像素的图片

实现原理

监听View的显示区域的变化,然后加载显示区域内应该显示的图片区域,然后绘制到View上

1.UpdateView

负责监听显示区域的变化的View,子类通过重写onUpdateWindow(Rect visiableRect)监听显示区域,大部分代码源于SurfaceView监听代码

2.ImageManager

负责加载显示区域的图片块。

3.LargeImageView

负责绘制图片块

实现细节:

每次LargeImageView的onDraw方法都会调用 ImageManagerd的getDrawData(float imageScale, Rect imageRect)方法,imageRect为在View上图片显示的区域(需要加载的图片区域),imageScale 假设等于4的话,就是View上显示1像素,image要加载4个像素的区域(缩小4倍的图片)

getDrawData(float imageScale, Rect imageRect)实现细节:

手势移动,图片显示区域会变化。比如显示区域是800800,向右移动2像素,难道要重新加载800800的图片区域? 所以我采用了 图片切块的操作,分块的优化
1. 比如图片显示比例是1,那么要横向分多少份才,纵向分多少分,才合理?图片显示比例是4,横向分多少份才,纵向分多少分,才合理。
所以我采用了 基准块(图片比例是1,一个图片块的宽高的合理sise) BASE_BLOCKSIZE = context.getResources().getDisplayMetrics().widthPixels / 2;
图片缩放比例为1的话,图片块宽高是BASE_BLOCKSIZE
图片缩放比例为4的话,图片块宽高是4*BASE_BLOCKSIZE
图片没被位移,那么屏幕上显示横向2列,纵向getDisplayMetrics().heightPixels/BASE_BLOCKSIZE行
2.因为手势放大缩小操作要加载不同清晰度的图片区域,比如之前的图片缩放是4,现在缩放是4.2,难道要重新加载?
通过public int getNearScale(float imageScale)方法计算趋于2的指数次方的值(1,2,4,8,16)
比如3.9和4.2和4比较接近,就直接加载图片显示比例为4的图片块
3.之前没加载的区域,难道要空白显示么?
为了避免加载出现白色块,我会缓存当前比例的加载的图片块,以及2倍比例的图片块(之前加载过,并且当前还属于当前显示区域的,如果不是的话也不缓存它) 所以发现没有的话去拿其他比例的图片区去显
4.难道只加载显示区域?
当然,还会去加载旁边一部分没显示的区域的图片块
5.onDraw方法是UI线程,调用getDrawData(float imageScale, Rect imageRect)加载图片块的方法怎么不卡住
getDrawData只返回之前加载过的图片块,而没有加载的是通过LoadHandler.sendMessage去加载 LoadHandler的Loop是通过HandlerThread线程创建的Loop,也就是 开个线程加载.
每加载一个图片块通过 onImageLoadListenner.onBlockImageLoadFinished();onDraw重绘

onDraw又调用getDrawData加载,直至需要显

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值