栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Android ImageView属性ScaleType的源码解析

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Android ImageView属性ScaleType的源码解析

ImageView的ScaleType的属性,一共有八个,一般都是自己看着来用,最近开发时,需要修改图片的缩放,理解了一波ScaleType的属性,总结一下。

属性值作用
MATRIX使用setImageMatrix(Matrix),允许用户自定义缩放、平移、透视来变形
FIT_XY缩小或放大图片,充满控件,不裁剪,可能会改变图片纵横比
FIT_START缩小或放大图片,未充满控件,保证纵横比,从原点开始,保证长宽有一个是完整的
FIT_CENTER缩小或放大图片,未充满控件,保证纵横比,保证长宽有一个是完整的,显示在中间
FIT_END缩小或放大图片,未充满控件,保证纵横比,从底部右边开始,保证长宽有一个是完整
CENTER不缩放,充满控件,会裁剪,保证纵横比,显示在中央
CENTER_CROP缩放图片,保证纵横比,使长宽等于或大于视图的尺寸,显示在中央,会剪裁
也就是说保证图片的短边能显示出来,而长边不会完整的显示
CENTER_INSIDE缩放图片,保证纵横比,,使长宽等于或小于视图的尺寸,显示在中央

MATRIX

MATRIX是一个矩阵类,是用来对图片进行缩放、平移、旋转等操作,主要有:

translate 平移

mMaritx.setTranslate(float dx,float dy)

Rotate 旋转

mMaritx.setRotate(float degrees, float px, float py)//旋转角度,旋转中心

scale 缩放

mMartix.setScale(float sx, float sy,float px,float py) //

skew 倾斜

mMartix.setSkew(float sx, float sy,float px,float py) //

​ 矩阵的乘法是只有左乘的概念,需要(m*n)*(n*m),但是由于mMartix是一个3*3的矩阵,因此可以左乘和右乘,这种概念毫无用处,只是因为它提供的Api中有post和pre,post是指当前矩阵左乘参数矩阵,pre是指参数矩阵乘以当前矩阵,因此如果你的变化是连续的,需要分清先后顺序。

//源码解析
if (ScaleType.MATRIX == mScaleType) {
  // Use the specified matrix as-is.
  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

//vwidth 控件宽  vheight 控件高 //dwidth 图片宽 //dheight 图片高
if (ScaleType.CENTER == mScaleType) {
                // Center bitmap in view, no scaling.
                mDrawMatrix = mMatrix;
                mDrawMatrix.setTranslate(Math.round((vwidth - dwidth) * 0.5f),
                                         Math.round((vheight - dheight) * 0.5f));

由源码可知,只是将其进行了平移,移动到控件的中间。

CENTER_CROP

这个我理解了很久,使用代数法进行了一波实验,保证有一边是可以完全展示出来的,另一边是超过控件大小的,最后再平移到控件中间,但是它对于宽高比的处理,是通过图片宽高比和控件的宽高比进行比较,得到哪个是短边。

//vwidth 控件宽  vheight 控件高 //dwidth 图片宽 //dheight 图片高
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);
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/720004.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号