ImageView的ScaleType决定了图片在ImageView中的缩放形式。本文从ImageView的源码角度,结合图表展示不同ScaleType状态下图片的展示形式。下图所示为Android给ImageView定义的ScaleType枚举类,包含了八种ScaleType类型:
当用户在设置了ImageView的ScaleType后,ImageView会根据ScaleType的值进行图片的缩放,代码实现在ImageView.java类的private void configureBounds()函数中:
1、MATRIX
该模式下ImageView用户设置的比例缩放图片,经过MATRIX缩放后的图片将从ImageView的左上角开始绘制。如果缩放后的图片大于ImageView,那么多余的部分则剪裁掉,如果小于ImageView,则不作做任何处理。因此可能出现如下的图片展示形式,其中实线框表示ImageView,虚线表示图片。
该模式下图片从ImageView的左上角开始绘制,但不会超出ImageView,超出的部分不再显示。
2、CENTER
该模式按图片的原有的尺寸居中显示,当图片长/宽超过View的长/宽,则截取图片的居中部分显示,分为以下四种场景:
当dwidth>vwidth,dheight<vheight时,其实就是将图片左移和向下移动到ImageView的*位置展示,展示图片的中间区域。
当dwidth<vwidth,dheight<vheight时,其实就是将图片向右和向上移动到ImageView的*位置展示。
当dwidth>vwidth,dheight>vheight时,其实就是将图片向左和向上移动到ImageView的*位置展示,展示图片中间内容。
当dheight>vheight,dwidth<vwidth,其实就是将图片向右和向上移动到ImageView的*位置展示,展示图片中间内容。
3、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操作即可。
上图所示,vwidth/dwidth>vheight/dheight,图片先按照vwidth/dwidth进行缩放,缩放后的图片高度>=vheight,然后再进行向上移位。
上图所示,vheight/dheight>vwidth/dwidth,图片先按照vheight/dheight进行缩放,缩放后的图片宽度>=vwidth,然后再进行想左移位。
4、CENTER_INSIDE
该模式将图片的内容完整居中显示,通过按比例缩小或原图片的尺寸,使得图片长或者宽等于或小于ImageView的长或者宽,这种方式允许图片不塞满整个ImageView。如果图片宽度dwidth小于ImageView的宽度vwidth,且图片高度dheight小于ImageView高度vheight,则图片的显示如下:
CENTER_INSIDE和CENTER_CROP选择缩放比例的策略正好相反,CENTER_INSIDE始终选择较小的比例进行缩放,保证缩放后的一个边(宽或高)小于ImageView的宽或高。下图所示为vheight/dheight>vwidth/dwidth的场景,取vwidth/dwidth作为图片的缩放比例,保证了缩放后图片高度小于或等于ImageView的高度(vwidth/dwidth)*dheight<=vheight。
下图所示为vwidth/dwidth>vheight/dheight的场景,取vheight/dheight作为图片的缩放比例,保证了缩放后图片宽度小于或等于ImageView的宽度,(vheight/dheight)*dwidth<=vwidth。
5、FIT_XY、FIT_CENTER、FIT_START、FIT_END
当ImageView设置了这四种ScaleType后,ImageView采用Matrit.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位置(图片会完整显示)。如下图所示:
CENTER:相当于ScaleType.FIT_CENTER,把图片按比例扩大/缩小到View的宽度或高度,居中显示(图片会完整显示)。如下图所示:
END:相当于ScaleType.FIT_END,把图片按比例扩大/缩小到View的宽度或高度,显示在View的right和bottom位置(图片会完整显示)。如下图所示: