[关闭]
@myron-lee 2015-03-13T09:03:39.000000Z 字数 2377 阅读 1541

从源码角度分析 ImageView的ScaleType属性

Blog


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把图像的右下角显示到视图上。

2.源码分析

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

  1. private void configureBounds() {
  2. if (mDrawable == null || !mHaveFrame) {
  3. return;
  4. }
  5. int dwidth = mDrawableWidth;
  6. int dheight = mDrawableHeight;
  7. int vwidth = getWidth() - mPaddingLeft - mPaddingRight;
  8. int vheight = getHeight() - mPaddingTop - mPaddingBottom;
  9. boolean fits = (dwidth < 0 || vwidth == dwidth) &&
  10. (dheight < 0 || vheight == dheight);
  11. if (dwidth <= 0 || dheight <= 0 || ScaleType.FIT_XY == mScaleType) {
  12. /* If the drawable has no intrinsic size, or we're told to
  13. scaletofit, then we just fill our entire view.
  14. */
  15. mDrawable.setBounds(0, 0, vwidth, vheight);
  16. mDrawMatrix = null;
  17. } else {
  18. // We need to do the scaling ourself, so have the drawable
  19. // use its native size.
  20. mDrawable.setBounds(0, 0, dwidth, dheight);
  21. if (ScaleType.MATRIX == mScaleType) {
  22. // Use the specified matrix as-is.
  23. if (mMatrix.isIdentity()) {
  24. mDrawMatrix = null;
  25. } else {
  26. mDrawMatrix = mMatrix;
  27. }
  28. } else if (fits) {
  29. // The bitmap fits exactly, no transform needed.
  30. mDrawMatrix = null;
  31. } else if (ScaleType.CENTER == mScaleType) {
  32. // Center bitmap in view, no scaling.
  33. mDrawMatrix = mMatrix;
  34. mDrawMatrix.setTranslate((int) ((vwidth - dwidth) * 0.5f + 0.5f),
  35. (int) ((vheight - dheight) * 0.5f + 0.5f));
  36. } else if (ScaleType.CENTER_CROP == mScaleType) {
  37. mDrawMatrix = mMatrix;
  38. float scale;
  39. float dx = 0, dy = 0;
  40. if (dwidth * vheight > vwidth * dheight) {
  41. scale = (float) vheight / (float) dheight;
  42. dx = (vwidth - dwidth * scale) * 0.5f;
  43. } else {
  44. scale = (float) vwidth / (float) dwidth;
  45. dy = (vheight - dheight * scale) * 0.5f;
  46. }
  47. mDrawMatrix.setScale(scale, scale);
  48. mDrawMatrix.postTranslate((int) (dx + 0.5f), (int) (dy + 0.5f));
  49. } else if (ScaleType.CENTER_INSIDE == mScaleType) {
  50. mDrawMatrix = mMatrix;
  51. float scale;
  52. float dx;
  53. float dy;
  54. if (dwidth <= vwidth && dheight <= vheight) {
  55. scale = 1.0f;
  56. } else {
  57. scale = Math.min((float) vwidth / (float) dwidth,
  58. (float) vheight / (float) dheight);
  59. }
  60. dx = (int) ((vwidth - dwidth * scale) * 0.5f + 0.5f);
  61. dy = (int) ((vheight - dheight * scale) * 0.5f + 0.5f);
  62. mDrawMatrix.setScale(scale, scale);
  63. mDrawMatrix.postTranslate(dx, dy);
  64. } else {
  65. // Generate the required transform.
  66. mTempSrc.set(0, 0, dwidth, dheight);
  67. mTempDst.set(0, 0, vwidth, vheight);
  68. mDrawMatrix = mMatrix;
  69. mDrawMatrix.setRectToRect(mTempSrc, mTempDst, scaleTypeToScaleToFit(mScaleType));
  70. }
  71. }
  72. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注