ImageView的ScaleType的属性,一共有八个,一般都是自己看着来用,最近开发时,需要修改图片的缩放,理解了一波ScaleType的属性,总结一下。
属性值 | 作用 |
---|
MATRIX | 使用setImageMatrix(Matrix),允许用户自定义缩放、平移、透视来变形 | FIT_XY | 缩小或放大图片,充满控件,不裁剪,可能会改变图片纵横比 | FIT_START | 缩小或放大图片,未充满控件,保证纵横比,从原点开始,保证长宽有一个是完整的 | FIT_CENTER | 缩小或放大图片,未充满控件,保证纵横比,保证长宽有一个是完整的,显示在中间 | FIT_END | 缩小或放大图片,未充满控件,保证纵横比,从底部右边开始,保证长宽有一个是完整 | CENTER | 不缩放,充满控件,会裁剪,保证纵横比,显示在中央 | CENTER_CROP | 缩放图片,保证纵横比,使长宽等于或大于视图的尺寸,显示在中央,会剪裁 也就是说保证图片的短边能显示出来,而长边不会完整的显示 | CENTER_INSIDE | 缩放图片,保证纵横比,,使长宽等于或小于视图的尺寸,显示在中央 |
? 矩阵的乘法是只有左乘的概念,需要(m*n)*(n*m) ,但是由于mMartix是一个3*3的矩阵,因此可以左乘和右乘,这种概念毫无用处,只是因为它提供的Api中有post 和pre ,post 是指当前矩阵左乘参数矩阵,pre 是指参数矩阵乘以当前矩阵,因此如果你的变化是连续的,需要分清先后顺序。
if (ScaleType.MATRIX == mScaleType) {
if (mMatrix.isIdentity()) {
mDrawMatrix = null;
} else {
mDrawMatrix = mMatrix;
}
由此可以见到,其是将参数矩阵mMatrix 给了mDrawMatrix ,然后在Draw() 时调用mDrawMatrix .
使用时,需要先将矩阵填入,再使用类型
setScaleType(ScaleType.MATRIX);
setImageMatrix(mMatrix);
setScaleType时会重新刷新。
-
FIT_XY -
FIT_START -
FIT_CENTER -
FIT_END 以上方法时,使用了JNI,没有查到源码 -
CENTER
if (ScaleType.CENTER == mScaleType) {
mDrawMatrix = mMatrix;
mDrawMatrix.setTranslate(Math.round((vwidth - dwidth) * 0.5f),
Math.round((vheight - dheight) * 0.5f));
由源码可知,只是将其进行了平移,移动到控件的中间。 -
CENTER_CROP 这个我理解了很久,使用代数法进行了一波实验,保证有一边是可以完全展示出来的,另一边是超过控件大小的,最后再平移到控件中间,但是它对于宽高比的处理,是通过图片宽高比和控件的宽高比进行比较,得到哪个是短边。
if (ScaleType.CENTER_CROP == mScaleType) {
mDrawMatrix = mMatrix;
float scale;
float dx = 0, dy = 0;
if (dwidth * vheight > vwidth * dheight) {
scale = (float) vheight / (float) dheight;
dx = (vwidth - dwidth * scale) * 0.5f;
} else {
scale = (float) vwidth / (float) dwidth;
dy = (vheight - dheight * scale) * 0.5f;
}
mDrawMatrix.setScale(scale, scale);
mDrawMatrix.postTranslate(Math.round(dx), Math.round(dy));
可以这么理解,图片宽高比>控件宽高比,图片高度是可以保证通过缩放完全显示,宽边会超过控件宽度,反之则是图片宽度是可以保证通过缩放完全显示,高度会超过控件高度。 -
CENTER_INSIDE
- 当图片宽高都小于控件的宽高时,则不会缩放
- 当图片宽高有一边大于控件的宽高时,则会选择长边的缩放比例,保证长边充满控件,而短边完全显示却不充满控件
- 最后平移到中间
if (ScaleType.CENTER_INSIDE == mScaleType) {
mDrawMatrix = mMatrix;
float scale;
float dx;
float dy;
if (dwidth <= vwidth && dheight <= vheight) {
scale = 1.0f;
} else {
scale = Math.min((float) vwidth / (float) dwidth,
(float) vheight / (float) dheight);
}
dx = Math.round((vwidth - dwidth * scale) * 0.5f);
dy = Math.round((vheight - dheight * scale) * 0.5f);
mDrawMatrix.setScale(scale, scale);
mDrawMatrix.postTranslate(dx, dy);
|