ImageView中有个很重要也很经常使用的属性android:scaleType
,相信你们都应该不陌生,主要用于控制图片在ImageView中显示的样式,好比显示大小、显示位置、显示内容区域。固然也能够在代码中设置: setScaleType(ImageView.ScaleType.xxx);
ScaleType的取值一共有8种:fitCenter
,fitEnd
,center
,centerCrop
,centerInside
,matrix
,fitXY
,fitStart
。其中默认值是fitCenter。 咱们先来看比较简单的center
吧,一个60dp*40dp的ImageView(为了显示效果,背景设成蓝色)里面放了张20dp*20dp的图片。上图看看效果:java
center
的含义是:保持原图的大小,显示在ImageView的中心。当原图的size大于ImageView的size,超过部分裁剪处理。 再来看比较“暴力”的fitXY
:android
fitXY
的含义:拉伸显示图片,不保持原比例,填满ImageView.嗯,果真很暴力。canvas
嗯,接下来咱们...什么?难道你觉得我要把剩下的6种样式都贴张图出来,而后愉快地水一篇博客吗? ide
因此接下来我放大招了,开始分析源码!工具
上面设置了这么多种ScaleType
,那么最终生效的位置在哪呢?答案就在 configureBounds()
方法里,限于篇幅我贴了上面两种样式的法,其余的样式实现也都相似。post
private void configureBounds() {
//图片宽高
final int dwidth = mDrawableWidth;
final int dheight = mDrawableHeight;
//Imageview宽高
final int vwidth = getWidth() - mPaddingLeft - mPaddingRight;//
final int vheight = getHeight() - mPaddingTop - mPaddingBottom;
final boolean fits = (dwidth < 0 || vwidth == dwidth)
&& (dheight < 0 || vheight == dheight);
if (dwidth <= 0 || dheight <= 0 || ScaleType.FIT_XY == mScaleType) {
mDrawable.setBounds(0, 0, vwidth, vheight);
mDrawMatrix = null;
} else {
mDrawable.setBounds(0, 0, dwidth, dheight);
if (ScaleType.MATRIX == mScaleType) {//样式应用自定义MATRIX
if (mMatrix.isIdentity()) {
mDrawMatrix = null;
} else {
mDrawMatrix = mMatrix;
}
}
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));
}
复制代码
能够看到最终的实现用到了Drawable类和Matrix类的方法。前者你们都很熟悉,就是咱们设置的要显示的图片,而Matrix叫作矩阵,是一个专门用来处理图形变换中的重要工具类,熟悉自定义View的同窗应该对它不陌生,canvas.setMatrix(matrix)
能够作出不少独特效果来。而咱们今天的主角是ImageView
,因此没错imageView
也有这个方法:spa
经过上述方法咱们就能将本身定义的Matrix应用到ImageView中。能够看到源码,要使这个方法生效,ScaleType必定要设为MATRIX,否则执行完本身的变换后仍是会执行样式本身的变换,至关于没执行。code
FIT_XY
的实现很简单,就用到了setBounds(int left, int top, int right, int bottom)
,这个四参数指的是drawable的绘制区域。 center
用到了postTranslate(float dx, float dy)
,将Drawable
移到ImageView中间,由于没有其余处理,图片若是比ImageView大,那么多余的区域就会被裁剪掉,不显示了。cdn
说了这么多来个小栗子来加深理解吧: 仍是上面那张图片,scaleType设为matrix,咱们再加一个按钮,点击事件以下:blog
int m = 20;
//平移
private void onClick(View v) {
Matrix matrix = new Matrix();
matrix.postTranslate(m, m);
imageView.setImageMatrix(matrix);
m = m + 3;
}
复制代码
来看看效果:
经过改变postTranslate
参数的值咱们就能改变图片在View中绘制的起始位置。 固然不会这么简单。Matrix还有其余方法: postRotate(float degrees, float px, float py)
//旋转: 咱们仿照center的处理将图片移到ImageView中心,而后进行旋转:
int m = 20;
//旋转
private void onClick(View v) {
Matrix matrix = new Matrix();
int width = imageView.getDrawable().getIntrinsicWidth();
int height = imageView.getDrawable().getIntrinsicHeight();
final int vwidth = imageView.getWidth();
final int vheight = imageView.getHeight();
matrix.setTranslate(Math.round((vwidth - width) * 0.5f),
Math.round((vheight - height) * 0.5f));
matrix.postRotate(m, vwidth * 0.5f, vheight * 0.5f);
imageView.setImageMatrix(matrix);
m = m + 3;
}
复制代码
看看效果:
还有一种是错切,将图片的形状改变: void setSkew(float kx, float ky)
实际用到的比较少,就不贴代码了,直接看效果吧:
说了这么多,这篇文章就是给你们介绍了android:scaleType
的自定义用法,当遇到Imageview预设的显示模式不能知足咱们现有需求的时候(好比我就遇到原图按照原来的大小居底部显示,若是原图的大小超过了ImageView的大小,那么就剪裁掉多余部分,保留底部,和centerCrop裁剪四周有所不一样),咱们就能够动态设置本身的matrix来自定义显示效果。固然若是你常常要用到这种方式的时候,能够继承Imageview,封装这些自定义样式。