目录
一. ScaleType属性的八种缩放规则说明
二. ScaleType属性的八种缩放效果图演示
三. ImageView.ScaleType自定义缩放规则,等比缩放,完整显示,拒绝变形
四. ImageView.setImageBitmap动态缩放图片,等比缩放,完整显示,拒绝变形
属性 | 说明 |
center | 使得图像居中显示,不进行任何缩放。 当图片比控件大时,图片会有部分被裁剪掉,显示不全; 当图片比控件小时,虽然图片会完整显示出来,但是控件会有部分空间没有被图片填充而显示空白。 |
centerCrop | 保持图像的宽高比,进行缩放图像,直到图像的宽和高都等于或大于控件的宽高,然后居中显示; 当图片和控件的宽高比例不相等时,图片会有部分被裁剪掉,显示不全。 |
centerInside | 当图像的宽高大于控件的宽高时,保持图像的宽高比,进行缩放图像,直到图像的宽和高都等于或小于控件的宽高,然后居中显示; 当图像的宽高都小于控件的宽高时,使得图像中居中显示,不进行任何缩放。 |
fitCenter |
保持图像的宽高比,进行缩放图像,直到图像的宽和高都等于或小于控件的宽高,然后居中显示; 当图片和控件的宽高比例不相等时,虽然图片会完整显示出来,但是控件会有部分空间没有被图片填充而显示空白。 fitCenter是ImageView的默认缩放方式。 |
fitEnd | 保持图像的宽高比,进行缩放图像,直到图像的宽和高都等于或小于控件的宽高,然后居右侧或底部显示; 当图片和控件的宽高比例不相等时,虽然图片会完整显示出来,但是控件会有部分空间没有被图片填充而显示空白。 |
fitStart | 保持图像的宽高比,进行缩放图像,直到图像的宽和高都等于或小于控件的宽高,然后居左侧或顶部显示; 当图片和控件的宽高比例不相等时,虽然图片会完整显示出来,但是控件会有部分空间没有被图片填充而显示空白。 |
fitXY | 可以不用保持图像的宽高比,从控件的左上角分别对图片的宽和高进行缩放,使得图片的宽高等于控件的宽高;这种方式虽然图像可以完整显示,但是在原图和控件的宽高比不一致的情况下,图像是会被拉伸变形的。 |
matrix | 不改变原图的宽高,不进行任何缩放,从控件的左上角开始绘制原图,原图超过控件的部分作裁剪处理。 当图片比控件大时,图片会有部分显示不全; 当图片比控件小时,虽然图片会完整显示出来,但是控件会有部分空间没有被图片填充而显示空白。 这个属性可以支持自定义图片缩放规则。 |
1. center:使得图像居中显示,不进行任何缩放
2. centerCrop:保持图像的宽高比,进行缩放图像,直到图像的宽和高都等于或大于控件的宽高,然后居中显示
3. centerInside:当图像的宽高大于控件的宽高时,保持图像的宽高比,进行缩放图像,直到图像的宽和高都等于或小于控件的宽高,然后居中显示
4. fitCenter:保持图像的宽高比,进行缩放图像,直到图像的宽和高都等于或小于控件的宽高,然后居中显示
5. fitEnd:保持图像的宽高比,进行缩放图像,直到图像的宽和高都等于或小于控件的宽高,然后居右侧或底部显示
6. fitStart:保持图像的宽高比,进行缩放图像,直到图像的宽和高都等于或小于控件的宽高,然后居左侧或顶部显示
7. fitXY:可以不用保持图像的宽高比,从控件的左上角分别对图片的宽和高进行缩放,使得图片的宽高等于控件的宽高
8. matrix:不改变原图的宽高,不进行任何缩放,从控件的左上角开始绘制原图,原图超过控件的部分作裁剪处理
附上原图:(720x720)
附上原图:(320x320)
(需求案例:控件的宽度固定,将图片完整显示出来,不要让图片变形,也不要有裁剪的部分,控件的高度允许不固定,控件的高度保持跟图像的高度一致即可)
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Matrix;
import android.os.Looper;
import android.support.annotation.Nullable;
import android.util.AttributeSet;
import android.view.ViewGroup;
import android.widget.ImageView;
@SuppressLint("AppCompatCustomView")
public class ScaleImageView extends ImageView {
// 是否需要刷新,避免多次调用
private boolean isRefresh = true;
public ScaleImageView(Context context) {
super(context);
}
public ScaleImageView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
}
public ScaleImageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@Override
protected boolean setFrame(int l, int t, int r, int b) {
boolean flag = super.setFrame(l, t, r, b);
// 如果允许刷新,并且控件宽度大于0
if (isRefresh && getWidth() > 0) {
isRefresh = false;
setImageMatrix();
}
return flag;
}
/**
* 方法描述:重置刷新状态,在ImageView重新设置了图片之前,需要调用此方法
**/
public void resetRefreshStatus() {
isRefresh = true;
}
/**
* 方法描述:设置矩阵
**/
private void setImageMatrix() {
// 判断如果缩放类型等于MATRIX
if (getScaleType() == ScaleType.MATRIX) {
Matrix matrix = getImageMatrix();
// 获取控件的宽度(单位px)
final float width = getWidth();
// 获取图像的宽度(单位dp)
float intrinsicWidth = getDrawable().getIntrinsicWidth();
// 获取图像的高度(单位dp)
float intrinsicHeight = getDrawable().getIntrinsicHeight();
// 宽度缩放比例
float widthScale = width / intrinsicWidth;
// 控件最终应该设置的高度(即原图缩放后的高度)
final float lastHeight = intrinsicHeight * widthScale;
// 高度跟宽度同比缩放,这样图片不会变形,使得图片的宽的在控件内完整显示,图片的高度再通过动态设置控件的高度使得图片的高度也跟着完整显示
matrix.setScale(widthScale, widthScale);
// 设置矩阵
setImageMatrix(matrix);
// 如果是主线程
if (Looper.myLooper() == Looper.getMainLooper()) {
// 动态设置布局大小(这里主要是把布局的高度设置成“缩放后的图片”的高度)
setLayoutSize((int) width, (int) lastHeight);
} else {
post(new Runnable() {
@Override
public void run() {
// 动态设置布局大小(这里主要是把布局的高度设置成“缩放后的图片”的高度)
setLayoutSize((int) width, (int) lastHeight);
}
});
}
}
}
/**
* 重新设置布局参数
*
* @param width
* @param height
**/
private void setLayoutSize(int width, int height) {
ViewGroup.LayoutParams params = getLayoutParams();
params.width = width;
params.height = height;
setLayoutParams(params);
}
}
(需求案例:控件的宽度固定,将图片完整显示出来,不要让图片变形,也不要有裁剪的部分,控件的高度允许不固定,控件的高度保持跟图像的高度一致即可)
import android.graphics.Bitmap;
import android.graphics.Matrix;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.widget.ImageView;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/**
* 需求案例:控件的宽度固定,将图片完整显示出来,不要有裁剪的部分,控件的高度不固定(保持跟图像的高度一致即可)
*/
// 找到控件(这里的控件高度属性设置为:wrap_content)
ImageView imageView = findViewById(R.id.image_view);
// 原图 (这里需要获取自己的bitmap)
Bitmap bitmap = null;
// 获取缩放后的新图片
Bitmap newBitmap = getZoomBitmap(bitmap, imageView.getWidth());
// 设置位图(将图片完整显示出来)
imageView.setImageBitmap(newBitmap);
}
/**
* 方法描述:获取缩放后的图片
*
* @param bitmap 这里传入原图
* @param newWidth 这里传入控件的宽度
**/
private Bitmap getZoomBitmap(Bitmap bitmap, int newWidth) {
// 获得图片的宽高
int width = bitmap.getWidth();
int height = bitmap.getHeight();
// 计算缩放比例
float scaleWidth = ((float) newWidth) / width;
float scaleHeight = ((float) newWidth) / height;
// 取得想要缩放的matrix参数
Matrix matrix = new Matrix();
matrix.postScale(scaleWidth, scaleHeight);
// 得到新的图片
return Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true);
}
}
如何做到图片不变形?
思路:保持图片的宽高比不变,使得控件的宽高比保持与图片的宽高比一致。
运行效果图: