ImageView的ScaleType属性浅析

来源:互联网 发布:java的日志框架 编辑:程序博客网 时间:2024/04/30 12:13

1.关注重点

  • 图像能否完全显示(是否裁剪了)
  • 视图有无空白(视图是否被图像充满)
  • 图像是否变形(图像宽高比是否变化)

2.结论

ScaleType 图像能否完全显示 视图有无空白 图像是否变形 FIT_XY 能 无 可能 FIT_CENTER 不一定 无 否 FIT_START 不一定 无 否 FIT_END 不一定 无 否 CENTER 不一定 可能 否 CENTER_CROP 不一定 无 否 CENTER_INSIDE 能 可能 否

CENTER_CROP、FIT_CENTER、FIT_START、FIT_END 均先做相同的scale(按比例缩放,使得缩放后,图像的长宽之一与视图相同,另一边比视图大),区别在于之后平移变换——FIT_CENTER 与 CENTER_CROP 相同,把此时比视图大的图像的中间部分显示到视图上;FIT_START把图像的左上角显示到视图上;FIT_END把图像的右下角显示到视图上。

3.源码分析

mDrawMatrix是关键。它决定 drawable 绘制的位置(相对于视图坐标系)与大小。

    private void configureBounds() {        if (mDrawable == null || !mHaveFrame) {            return;        }        int dwidth = mDrawableWidth;        int dheight = mDrawableHeight;        int vwidth = getWidth() - mPaddingLeft - mPaddingRight;        int vheight = getHeight() - mPaddingTop - mPaddingBottom;        boolean fits = (dwidth < 0 || vwidth == dwidth) &&                       (dheight < 0 || vheight == dheight);        if (dwidth <= 0 || dheight <= 0 || ScaleType.FIT_XY == mScaleType) {            /* If the drawable has no intrinsic size, or we're told to                scaletofit, then we just fill our entire view.            */            mDrawable.setBounds(0, 0, vwidth, vheight);            mDrawMatrix = null;        } else {            // We need to do the scaling ourself, so have the drawable            // use its native size.            mDrawable.setBounds(0, 0, dwidth, dheight);            if (ScaleType.MATRIX == mScaleType) {                // Use the specified matrix as-is.                if (mMatrix.isIdentity()) {                    mDrawMatrix = null;                } else {                    mDrawMatrix = mMatrix;                }            } else if (fits) {                // The bitmap fits exactly, no transform needed.                mDrawMatrix = null;            } else if (ScaleType.CENTER == mScaleType) {                // Center bitmap in view, no scaling.                mDrawMatrix = mMatrix;                mDrawMatrix.setTranslate((int) ((vwidth - dwidth) * 0.5f + 0.5f),                                         (int) ((vheight - dheight) * 0.5f + 0.5f));            } else 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((int) (dx + 0.5f), (int) (dy + 0.5f));            } else 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 = (int) ((vwidth - dwidth * scale) * 0.5f + 0.5f);                dy = (int) ((vheight - dheight * scale) * 0.5f + 0.5f);                mDrawMatrix.setScale(scale, scale);                mDrawMatrix.postTranslate(dx, dy);            } else {                // Generate the required transform.                mTempSrc.set(0, 0, dwidth, dheight);                mTempDst.set(0, 0, vwidth, vheight);                mDrawMatrix = mMatrix;                mDrawMatrix.setRectToRect(mTempSrc, mTempDst, scaleTypeToScaleToFit(mScaleType));            }        }    }
0 0
原创粉丝点击