ImageView的ScaleType原理及效果分析

简介: ImageView的ScaleType决定了图片在ImageView中的缩放形式。本文从ImageView的源码角度,结合图表展示不同ScaleType状态下图片的展示形式。

ImageView的ScaleType决定了图片在ImageView中的缩放形式。本文从ImageView的源码角度,结合图表展示不同ScaleType状态下图片的展示形式。下图所示为Android给ImageView定义的ScaleType枚举类,包含了八种ScaleType类型:

img_83a7b15e328c28f4def7b75b8f803524.png
ScaleType枚举类

当用户在设置了ImageView的ScaleType后,ImageView会根据ScaleType的值进行图片的缩放,代码实现在ImageView.java类的private void configureBounds()函数中:

img_e8d7ae62f51d35c13c14e09380406dad.png
ImageView.configureBounds()
其中其中 dwith/dheight是图片的实际宽度/高度; vwidth/vheight是ImageView的宽度/高度。下面分别描述下各种ScaleType的图片是如何展示的。

1、MATRIX

该模式下ImageView用户设置的比例缩放图片,经过MATRIX缩放后的图片将从ImageView的左上角开始绘制。如果缩放后的图片大于ImageView,那么多余的部分则剪裁掉,如果小于ImageView,则不作做任何处理。因此可能出现如下的图片展示形式,其中实线框表示ImageView,虚线表示图片

img_3e25dec6af5488b77c508d662dd9ba78.png
MATRIX模式下图片的展示形式

该模式下图片从ImageView的左上角开始绘制,但不会超出ImageView,超出的部分不再显示。

2、CENTER

img_e5835ff674de1a31e7a07d072b2ee1d7.png
CENTER的代码实现

该模式按图片的原有的尺寸居中显示,当图片长/宽超过View的长/宽,则截取图片的居中部分显示,分为以下四种场景:

img_5597655d13ece3d2b605705353bb4eae.png
dwidth>vwidth,dheight

当dwidth>vwidth,dheight<vheight时,其实就是将图片左移和向下移动到ImageView的中央位置展示,展示图片的中间区域。

img_da3d24c75e07b8ef40a1f6e6cd669ca2.png
dwidth

当dwidth<vwidth,dheight<vheight时,其实就是将图片向右和向上移动到ImageView的中央位置展示。

img_4100ed7a9d495eba0b027c28e05c39af.png
dwidth>vwidth,dheight>vheight

当dwidth>vwidth,dheight>vheight时,其实就是将图片向左和向上移动到ImageView的中央位置展示,展示图片中间内容。

img_5b7fa9840417cadda43b8af63536b2b3.png
dheight>vheight,dwidth

当dheight>vheight,dwidth<vwidth,其实就是将图片向右和向上移动到ImageView的中央位置展示,展示图片中间内容。

3、CENTER_CROP

img_9032d8f2a97b0094799dd7766e05eda2.png
CENTER_CROP代码实现

该模式按比例扩大图片的尺寸并居中显示,使得图片长(宽)等于或大于View的长(宽)。

如果dwidth/dheight>vwidth/vheight(图片的宽高比大于ImageView的宽高比),即vheight/dheight>vwidth/dwidth,也就是说ImageView和图片高度比小于ImageView和图片的宽度比,这时候取vheight/dheight的比例进行图片缩放,这样就能保证图片宽度在进行同等比例缩放的时候,图片宽度大于或等于ImageView的宽度,因为(vheight/dheight)* dwidth>vwidth。

同理,如果vwidth/dwidth>vheight/dheight时,取vwidth/dwidth作为图片的缩放比例,可以保证缩放完成后图片宽度等于ImageView的宽度,图片的高度大于或等于ImageView的高度,因为(vwidth/dwidth)*dheight>vheight。图片在缩放之后再进行CENTER操作即可。

img_f68c5802b840624482bb2fb05744ad6d.png
vwidth/dwidth>vheight/dheight

上图所示,vwidth/dwidth>vheight/dheight,图片先按照vwidth/dwidth进行缩放,缩放后的图片高度>=vheight,然后再进行向上移位。

img_ea98db75c4bb6e61d88bf4df49290098.png
vheight/dheight>vwidth/dwidth

上图所示,vheight/dheight>vwidth/dwidth,图片先按照vheight/dheight进行缩放,缩放后的图片宽度>=vwidth,然后再进行想左移位。

4、CENTER_INSIDE

img_d8afc22380320eebdb0ccbd5ed0de17a.png
CENTER_INSIDE的代码实现

该模式将图片的内容完整居中显示,通过按比例缩小或原图片的尺寸,使得图片长或者宽等于或小于ImageView的长或者宽,这种方式允许图片不塞满整个ImageView。如果图片宽度dwidth小于ImageView的宽度vwidth,且图片高度dheight小于ImageView高度vheight,则图片的显示如下:

img_0300c14b5435ecaff8b0a111885ead97.png
dheight

CENTER_INSIDE和CENTER_CROP选择缩放比例的策略正好相反,CENTER_INSIDE始终选择较小的比例进行缩放,保证缩放后的一个边(宽或高)小于ImageView的宽或高。下图所示为vheight/dheight>vwidth/dwidth的场景,取vwidth/dwidth作为图片的缩放比例,保证了缩放后图片高度小于或等于ImageView的高度(vwidth/dwidth)*dheight<=vheight。

img_b8810e1574b259cff1dce31792ec5c81.png
vheight/dheight>vwidth/dwidth

下图所示为vwidth/dwidth>vheight/dheight的场景,取vheight/dheight作为图片的缩放比例,保证了缩放后图片宽度小于或等于ImageView的宽度,(vheight/dheight)*dwidth<=vwidth。

img_dab6e1280e397990d7db1766bdab0b54.png
vwidth/dwidth>vheight/dheight

5、FIT_XY、FIT_CENTER、FIT_START、FIT_END

当ImageView设置了这四种ScaleType后,ImageView采用Matrit.ScaleToFit来进行图片的展示。

img_45af0194e38714869359f93c8b611b49.png
FIT_XY、FIT_CENTER、FIT_START、FIT_END
img_58599a39bf77dcf2f6774f1b577d5294.png
根据ScaleType获取ScaleTypeFit
img_87e0fa201a42187adaacd5cc5dab93e2.png
ScaleToFit枚举类

可以看出ScaleToFit有如下类型:

FILL:相当于ScaleType.FIT_XY,图片宽度和高度有独立的缩放比例,保证图片能够塞满整个ImageView。这种场景下图片宽度的缩放比例为vwidth/dwidth,高度的缩放比例为vheight/dheight。,

FIT_START,FIT_CENTER,FIT_END采用的缩放策略一样,如果dheight> dwidth,则使用vwidth/dwidth作为缩放比例,反之使用vheight/dheight作为缩放比例。

START:相当于ScaleType.FIT_START。把图片按比例扩大/缩小到View的宽度或高度,显示在View的left和top位置(图片会完整显示)。如下图所示:

img_7a08e86562ba3668f8b677635491170e.png
FIT_START

CENTER:相当于ScaleType.FIT_CENTER,把图片按比例扩大/缩小到View的宽度或高度,居中显示(图片会完整显示)。如下图所示:

img_fd9c4b75f97155b8611a1ab52df2407b.png
FIT_CENTER

END:相当于ScaleType.FIT_END,把图片按比例扩大/缩小到View的宽度或高度,显示在View的right和bottom位置(图片会完整显示)。如下图所示:

img_caa3693d0e654824ca2a32c1d9f1d383.png
FIT_END
目录
相关文章
|
Android开发
Android ImageView视图的七种图片缩放类型
Android ImageView视图的七种图片缩放类型
297 0
|
Android开发
Android ImageView scaleType 属性详细介绍与使用
Android ImageView scaleType 属性详细介绍与使用
130 0
|
Android开发
Android关于Bitmap的缩放方法
最近要将图片传给服务器,但是服务器限制了图片的大小,所以我查询了许多相关文章,现在将其罗列出来。
1005 0
|
缓存 Android开发
Android RecyclerView 绘制流程及Recycler缓存(上)
RecyclerView 源码一万多行,想全部读懂学会挺麻烦的,感兴趣的可以自己去瞅瞅,这篇文章重点来看下 RecyclerView是如何一步步将每一个 ItemView 显示到屏幕上,然后再分析在显示和滑动过程中,是如何通过缓存复用来提升整体性能的。 RecyclerView本质上也是一个 自定义控件 ,因此我们可以沿着分析其 onMeasure -> onLayout -> onDraw 这 3 个方法的路线来深入研究。
237 0
Android RecyclerView 绘制流程及Recycler缓存(上)
|
缓存 Android开发 容器
Android RecyclerView 绘制流程及Recycler缓存(下)
缓存复用原理 Recycler 缓存复用是 RecyclerView 中另一个非常重要的机制,这套机制主要实现了 ViewHolder 的缓存以及复用。
412 0
|
XML Java Android开发
Android CircleImageView圆形ImageView
 Android CircleImageView圆形ImageView CircleImageView是github上一个第三方开源的实现圆形ImageView的项目。
1605 0