Android ImageView 详解
目录
一、图片加载方法
二、图片缩放类型
三、updateDrawable() 原理
四、图片加载时会按缩放类型,会影响图片占用的内存大小吗?
五、总结
一、图片加载方法
在项目中,加载图片时,都会用到 ImageView,对应的几种设置图片的方式有如下几种:
- 在布局文件中设置属性 android:src=“@drawable/resId” 加载本地图片
- setImageResource(int resId); 加载drawable文件夹中的资源文件
- setImageURI(Uri); 加载手机内存卡中的图片格式文件
- setImageBitmap(Bitmap); 加载 Bitmap
- setImageDrawable(Drawable); 加载 Drawable
通过上述流程图,可以得知:
- 所有的图片格式,不管是资源,还是 Uri 还是 Bitmap ,都会转化为 Drawable;
- setImageURI(Uri) 方法,涉及到将文件转化为文件流,然后将文件流解析为 Bitmap 操作,需要注意的是在主线程中做这些操作,可能会造成延时;
- 针对性能方面,给上述加载图片方法排序,从劣到优,可以这样来:setImageURI() < setImageBitmap() < setImageRecource() < 属性设置 < setImageDrawable() ,能肯定的是,setImageDrawable() 是最优设置方法。
主要方法:updateDrawable(Drawable)
主要是根据 ImageView 设置的图片缩放类型确定其内容(即图片)绘制的边界,所以在这之前,需要知道关于 scaleType 缩放类型的一些事。
二、图片缩放类型
ImageView 对应的图片缩放类型,属性名为 scaleType,系统给出了八种缩放类型,对应含义和作用如下图所示:
网上大多以很形象的图展示各种缩放类型下ImageVIew加载图片的场景,这样看起来更容易理解,链接: ImageView的ScaleType原理及效果分析。
三、updateDrawable() 原理
对缩放类型有了清晰的认识后,再来看 updateDrawable() 方法具体做了哪些操作,源码流程如下:
四、图片加载时会按缩放类型,会影响图片占用的内存大小吗?
这里就有一个疑问了,既然图片加载时会按缩放类型放大或缩小图片,那么这会影响图片占用的内存大小吗?
测试场景:让 ImageView 加载同一张图片,然后以不同的 scaleType 进行加载,查看该图片占用的内存是否会改变?设置 vWidth = 200dp, vHeight = 160dp,加载图片原始大小:144x144 ,设备屏幕尺寸:1080x1920。
测试代码:
Log.e("ImageView", "scaleType = " + iv_img.getScaleType().toString()); // 默认为 FIT_CENTERfinal Drawable drawable = iv_img.getDrawable();int iWidth = drawable.getIntrinsicWidth(); // 216int iHeigth = drawable.getIntrinsicHeight(); // 216Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_logo);Log.e("ImageView", "bmap size = " + (bitmap.getWidth() + ", " + bitmap.getHeight()) + ", " + bitmap.getAllocationByteCount());// 216 216 432Log.e("ImageView", "drawable size = " + (iWidth + ", " + iHeigth));iv_img.post(new Runnable() {@Overridepublic void run() {Rect bounds = drawable.getBounds();int boundsW = bounds.right - bounds.left;int boundsH = bounds.bottom - bounds.top;// 216 216Log.e("ImageView", "bounds size = " + (boundsW + ", " + boundsH));}});
测试结果:
- 默认缩放类型FIT_CENTER:bmpW_H = drawableW_H = 216x216, bounds = 216x216,分配内存大小 = 186624
- 设置缩放类型FIT_XY:bmpW_H = drawableW_H = 216x216, bounds = 600x480,分配内存大小 = 186624
只设置两组区别比较到的缩放内存,从得到的结果可知缩放类型不会影响图片占用内存大小,只会影响 Drawable 在绘制图片到屏幕时的区域大小,可以看一下 Drawable ,其实也具备绘制功能。其实了解如何计算图片占用内存,就比较清楚,将图片转化为 Bitmap ,然后分场景计算:
- 加载资源文件时,计算的图片占用内存大小同图片所在drawable 文件夹和展示图片设备的分辨率有关;
- 加载内部存储中的图片文件时,则同设备屏幕密度无关,为图片本身大小。
可以明确的是,图片最终是以 Bitmap 形式存在于内存中的,ImageView 的缩放类型只是将图片展示的区域按缩放规则进行划定,并没有对图片本身产生作用,所以 scaleType 缩放对图片占用的内存大小并没有什么关系。
五、总结
了解本质之后,对图片的加载也有了大半的认识,在此做一下对 ImageView 的使用和认知做一些总结:
- setImageURI() 方法存在对 Uri 代表的图片文件转化为文件流而后解析为Bitmap 的操作,可能会存在延时,需要注意一下;
- 设置图片的最优方式是 setImageDrawable() 方法;
- 在布局中通过 src 属性展示图片 实际调用的并非 setImageResource() 方法,而是先将 resId 转化为 Drawable,然后通过 setImageDrawable() 方法加载;
- Drawable 是Android 系统中图片绘制前的最终形式,图片如何绘制到 canvas 上,也是通过 Drawable 来的;区别于在内存中存在的最终形式为 Bitmap;
- 自定义 View 时,绘制图片,使用 Drawable.setBounds() 确定边界后,再调用 drawable.draw(canvas) 方法绘制 会比 canvas.drawBitmap() 更简单强大,前者还能绘制 shape xml 文件转化的图片;
- ImageView 默认缩放类型为 FIX_CENTER;
- ImageView 缩放内存对加载图片本身占用的内存大小并没有关系,仅仅是缩放图片内容展示的边界而已;
- 图片占用内存大小,若为资源文件,则同drawable文件夹代表的密度和设备屏幕密度有关;若为网络或文件,则为图片本身大小;
- 图片的压缩方式分两种:质量压缩和分辨率压缩,前者能减少图片质量,但对图片分辨率并没有影响,图片占用的内存大小没有改变,常运用于 上传网络图片时上传字节大小有限制;后者压缩分辨率,会改变图片的清晰度,占用内存也会减少。
Android ImageView 详解相关推荐
- Android 动画详解-思维导图版
转载请注明链接: https://blog.csdn.net/feather_wch/article/details/81503233 涉及视图动画(补间动画.逐帧动画).属性动画三种动画的使用方法, ...
- android rotate 动画,Android RotateAnimation详解
RotateAnimation旋转坐标系为以旋转点为坐标系(0,0)点.x轴为0度,顺时针方向旋转一定的角度. 1.RotateAnimation(fromDegrees, toDegrees) [默 ...
- ImageView详解
ImageView详解 知识点简介 基本使用方法 常用属性 常用属性详解 子类 ImageButton QuickContactBadge AppCompatImageView 相关文章链接: 知识点 ...
- Android开发详解:第4章《UI 控件》
Android开发详解:第4章<UI 控件> 控件是Android程序设计的基本组成单位,通过使用控件可以高效地开发Android应用程序.所以熟练掌握控件的使用是合理.有效地进行Andr ...
- 【转】Android菜单详解——理解android中的Menu--不错
原文网址:http://www.cnblogs.com/qingblog/archive/2012/06/08/2541709.html 前言 今天看了pro android 3中menu这一章,对A ...
- Android菜单详解——理解android中的Menu
前言 今天看了pro android 3中menu这一章,对Android的整个menu体系有了进一步的了解,故整理下笔记与大家分享. PS:强烈推荐<Pro Android 3>,是我至 ...
- Android LayoutInflater详解
Android LayoutInflater详解 在实际开发中LayoutInflater这个类还是非常有用的,它的作用类 似于findViewById().不同点是LayoutInflater是用来 ...
- android Fragments详解
android Fragments详解一:概述 android Fragments详解二:创建Fragment 转载于:https://my.oschina.net/liangzhenghui/blo ...
- android WebView详解,常见漏洞详解和安全源码(下)
上篇博客主要分析了 WebView 的详细使用,这篇来分析 WebView 的常见漏洞和使用的坑. 上篇:android WebView详解,常见漏洞详解和安全源码(上) 转载请注明出处:http ...
最新文章
- 谷歌云盘Colaboratory如何载入文件
- 从面向过程到面向对象
- 产品经理面试中那些不忍直视的奇葩题目,面试官你真是够了!
- 函数式接口作为方法的返回值类型案例
- php自己创建函数,php自定义函数之内部函数
- 7-2 多项式求和 (10 分)
- 我的SWT与数字图像处理总结(3)—SWT如何得到图像某个位置的像素值和相应的RGB的值...
- 为Struts 2.0做好准备
- TensorRT:AttributeError: 'module' object has no attribute 'Logger'
- 拼多多快捷回复怎么设置
- 2021年下半年软件设计师考试下午题
- SpringBoot Validation参数校验 详解自定义注解规则和分组校验
- postman设置成中文
- 最实用的计算机系统清理加速,最实用的win7电脑清理垃圾方法分享
- 修改android模拟器位置
- 高级路由交换题库 答案与解释
- word2vec教程
- 智能情绪分析技术_人工智能在情绪识别领域的应用研究
- 电脑系统下载,安全,纯净,原版,iso系统
- SPSS数据分析之连续变量频率分析