目录

一、图片加载方法

二、图片缩放类型

三、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 详解相关推荐

  1. Android 动画详解-思维导图版

    转载请注明链接: https://blog.csdn.net/feather_wch/article/details/81503233 涉及视图动画(补间动画.逐帧动画).属性动画三种动画的使用方法, ...

  2. android rotate 动画,Android RotateAnimation详解

    RotateAnimation旋转坐标系为以旋转点为坐标系(0,0)点.x轴为0度,顺时针方向旋转一定的角度. 1.RotateAnimation(fromDegrees, toDegrees) [默 ...

  3. ImageView详解

    ImageView详解 知识点简介 基本使用方法 常用属性 常用属性详解 子类 ImageButton QuickContactBadge AppCompatImageView 相关文章链接: 知识点 ...

  4. Android开发详解:第4章《UI 控件》

    Android开发详解:第4章<UI 控件> 控件是Android程序设计的基本组成单位,通过使用控件可以高效地开发Android应用程序.所以熟练掌握控件的使用是合理.有效地进行Andr ...

  5. 【转】Android菜单详解——理解android中的Menu--不错

    原文网址:http://www.cnblogs.com/qingblog/archive/2012/06/08/2541709.html 前言 今天看了pro android 3中menu这一章,对A ...

  6. Android菜单详解——理解android中的Menu

    前言 今天看了pro android 3中menu这一章,对Android的整个menu体系有了进一步的了解,故整理下笔记与大家分享. PS:强烈推荐<Pro Android 3>,是我至 ...

  7. Android LayoutInflater详解

    Android LayoutInflater详解 在实际开发中LayoutInflater这个类还是非常有用的,它的作用类 似于findViewById().不同点是LayoutInflater是用来 ...

  8. android Fragments详解

    android Fragments详解一:概述 android Fragments详解二:创建Fragment 转载于:https://my.oschina.net/liangzhenghui/blo ...

  9. android WebView详解,常见漏洞详解和安全源码(下)

    上篇博客主要分析了 WebView 的详细使用,这篇来分析 WebView 的常见漏洞和使用的坑.  上篇:android WebView详解,常见漏洞详解和安全源码(上)  转载请注明出处:http ...

最新文章

  1. 谷歌云盘Colaboratory如何载入文件
  2. 从面向过程到面向对象
  3. 产品经理面试中那些不忍直视的奇葩题目,面试官你真是够了!
  4. 函数式接口作为方法的返回值类型案例
  5. php自己创建函数,php自定义函数之内部函数
  6. 7-2 多项式求和 (10 分)
  7. 我的SWT与数字图像处理总结(3)—SWT如何得到图像某个位置的像素值和相应的RGB的值...
  8. 为Struts 2.0做好准备
  9. TensorRT:AttributeError: 'module' object has no attribute 'Logger'
  10. 拼多多快捷回复怎么设置
  11. 2021年下半年软件设计师考试下午题
  12. SpringBoot Validation参数校验 详解自定义注解规则和分组校验
  13. postman设置成中文
  14. 最实用的计算机系统清理加速,最实用的win7电脑清理垃圾方法分享
  15. 修改android模拟器位置
  16. 高级路由交换题库 答案与解释
  17. word2vec教程
  18. 智能情绪分析技术_人工智能在情绪识别领域的应用研究
  19. 电脑系统下载,安全,纯净,原版,iso系统
  20. SPSS数据分析之连续变量频率分析

热门文章

  1. 小白连接阿里云服务器
  2. 如何记账手把手教你轻松记账
  3. mysql的ace什么概念,饭圈ace是什么意思 全能ace多用于团体详细含义揭秘
  4. python引用turtle画烟花_代码也浪漫:用Python放一场烟花秀!
  5. linux新建用户只能查看自己的目录,Linux创建用户只能访问某个目录
  6. 我在CSDN学生大本营的第一步,一切都充满希望
  7. 阿里P8都觉得烧脑的是什么数据库 - 绝世好剑(数组的相似约束与实时判定)
  8. 壁纸制作 App隐私政策
  9. RabbitMQ-ack、nack、reject、unacked
  10. ozip转zip工具教程(附下载)