构造方法
Matrix ()
Matrix (Matrix src)
基本方法
-
equals():比较两个Matrix的数值是否相同。 -
hashCode():获取Matrix的哈希值。 -
toString():将Matrix转换为字符串:Matrix{[1.0, 0.0, 0.0][0.0, 1.0, 0.0][0.0, 0.0, 1.0]}。 -
toShortString():将Matrix转换为短字符串:[1.0, 0.0, 0.0][0.0, 1.0, 0.0][0.0, 0.0, 1.0]。
数值操作
set
没有返回值,有一个参数,作用是将参数Matrix的数值复制到当前Matrix中。如果参数为空,则重置当前Matrix,相当于reset()。
void set (Matrix src)
reset
重置当前Matrix(将当前Matrix重置为单位矩阵)。
void reset ()
setValues
setValues()的参数是浮点型的一维数组,长度需要大于9,拷贝数组中的前9位数值赋值给当前Matrix。
void setValues(float[] values)
getValues
参数是浮点型的一维数组,长度需要大于9,将Matrix中的数值拷贝进参数的前9位中。
void getValues(float[] values)
数值计算
mapPoints
计算一组点基于当前Matrix变换后的位置,(由于是计算点,所以参数中的float数组长度一般都是偶数的,若为奇数,则最后一个数值不参与计算)。
void mapPoints(float[] pts)
void mapPoints(float[] dst, float[] src)
void mapPoints(float[] dst, int dstIndex,float[] src, int srcIndex, int pointCount)
方法一
void mapPoints (float[] pts) 方法仅有一个参数,pts数组作为参数传递原始数值,计算结果仍存放在pts中。
方法二
void mapPoints (float[] dst, float[] src) ,src作为参数传递原始数值,计算结果存放在dst中,src不变。
方法三
void mapPoints (float[] dst, int dstIndex,float[] src, int srcIndex, int pointCount) 可以指定只计算一部分数值。
| 参数 | 摘要 |
|---|---|
| dst | 目标数据 |
| dstIndex | 目标数据存储位置起始下标 |
| src | 源数据 |
| srcIndex | 源数据存储位置起始下标 |
| pointCount | 计算的点个数 |
mapRadius
测量半径,由于圆可能会因为画布变换变成椭圆,所以此处测量的是平均半径。
方法
float mapRadius(float radius)
示例
float radius = 100;
float result = 0;
// 构造一个matrix,x坐标缩放0.5
Matrix matrix = new Matrix();
matrix.setScale(0.5f, 1f);
Log.i(TAG, "mapRadius: "+radius);
result = matrix.mapRadius(radius);
Log.i(TAG, "mapRadius: "+result);
mapRadius: 100.0
mapRadius: 70.71068
mapRect
测量矩形变换后位置,返回值是判断矩形经过变换后是否仍为矩形,非90度倍数的旋转也会变成非矩形。
boolean mapRect(RectF rect)
boolean mapRect(RectF dst, RectF src)
方法一
boolean mapRect (RectF rect) 测量rect并将测量结果放入rect中。
方法二
boolean mapRect (RectF dst, RectF src) 测量src并将测量结果放入dst中。
mapVectors
测量向量,mapVectors 与 mapPoints 基本上是相同的,可以直接参照上面的mapPoints使用方法。两者唯一的区别就是mapVectors不会受到位移的影响,这符合向量的定律。
void mapVectors(float[] vecs)
void mapVectors(float[] dst, float[] src)
void mapVectors(float[] dst, int dstIndex, float[] src, int srcIndex, int vectorCount)
set、pre 与 post
| 方法 | 简介 |
|---|---|
| set | 设置,会覆盖掉之前的数值,导致之前的操作失效。 |
| pre | 前乘,构造矩阵乘式时,往前端压入乘式因子。 |
| post | 后乘,构造矩阵乘式时,往后端压入乘式因子。 |
特殊方法
setPolyToPoly
简介
Poly 全称是 Polygon ,多边形的意思。setPolyToPoly()最多可以支持4个点。
boolean setPolyToPoly (
float[] src, // 原始数组 src [x,y],存储内容为一组点
int srcIndex, // 原始数组开始位置
float[] dst, // 目标数组 dst [x,y],存储内容为一组点
int dstIndex, // 目标数组开始位置
int pointCount) // 测控点的数量 取值范围是: 0到4
| pointCount | 摘要 |
|---|---|
| 0 | 相当于reset
|
| 1 | 可以进行 平移 |
| 2 | 可以进行 缩放、旋转、平移 变换 |
| 3 | 可以进行 缩放、旋转、平移、错切 变换 |
| 4 | 可以进行 缩放、旋转、平移、错切以及任何形变 |

示例
public class MatrixSetPolyToPolyTest extends View {
private Bitmap mBitmap; // 要绘制的图片
private Matrix mPolyMatrix; // 测试setPolyToPoly用的Matrix
public MatrixSetPolyToPolyTest(Context context) {
super(context);
initBitmapAndMatrix();
}
private void initBitmapAndMatrix() {
mBitmap = BitmapFactory.decodeResource(getResources(),
R.drawable.poly_test);
mPolyMatrix = new Matrix();
float[] src = {0, 0, // 左上
mBitmap.getWidth(), 0, // 右上
mBitmap.getWidth(), mBitmap.getHeight(), // 右下
0, mBitmap.getHeight()}; // 左下
float[] dst = {0, 0, // 左上
mBitmap.getWidth(), 400, // 右上
mBitmap.getWidth(), mBitmap.getHeight() - 200, // 右下
0, mBitmap.getHeight()}; // 左下
// 核心要点
mPolyMatrix.setPolyToPoly(src, 0, dst, 0, src.length >> 1); // src.length >> 1 为位移运算 相当于处以2
// 此处为了更好的显示对图片进行了等比缩放和平移(图片本身有点大)
mPolyMatrix.postScale(0.26f, 0.26f);
mPolyMatrix.postTranslate(0,200);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// 根据Matrix绘制一个变换后的图片
canvas.drawBitmap(mBitmap, mPolyMatrix, null);
}
}

pointCount为0
pointCount()为0和reset()是等价的。

pointCount为1
pointCount()为1和translate是等价的,平移的距离是dst - src。

pointCount为2
当pointCount为2的时候,可以做缩放、平移和旋转。

pointCount为3
当pointCount为3的时候,可以做缩放、平移、旋转和错切。

pointCount为4
当pointCount为4的时候,你可以将图像拉伸为任意四边形。

setRectToRect
简介
将源矩形的内容填充到目标矩形中。
boolean setRectToRect (RectF src, // 源区域
RectF dst, // 目标区域
Matrix.ScaleToFit stf) // 缩放适配模式
Matrix.ScaleToFit:
| 模式 | 摘要 |
|---|---|
| CENTER | 居中,对src等比例缩放,将其居中放置在dst中。 |
| START | 顶部,对src等比例缩放,将其放置在dst的左上角。 |
| END | 底部,对src等比例缩放,将其放置在dst的右下角。 |
| FILL | 充满,拉伸src的宽和高,使其完全填充满dst。 |
图示
| src(原始状态) | ![]() |
|---|---|
| CENTER | ![]() |
| START | ![]() |
| END | ![]() |
| FILL | ![]() |
示例
展示居中例子:
public class MatrixSetRectToRectTest extends View {
private static final String TAG = "MatrixSetRectToRectTest";
private int mViewWidth, mViewHeight;
private Bitmap mBitmap; // 要绘制的图片
private Matrix mRectMatrix; // 测试etRectToRect用的Matrix
public MatrixSetRectToRectTest(Context context) {
super(context);
mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.rect_test);
mRectMatrix = new Matrix();
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
mViewWidth = w;
mViewHeight = h;
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
RectF src= new RectF(0, 0, mBitmap.getWidth(), mBitmap.getHeight() );
RectF dst = new RectF(0, 0, mViewWidth, mViewHeight );
// 核心要点
mRectMatrix.setRectToRect(src,dst, Matrix.ScaleToFit.CENTER);
// 根据Matrix绘制一个变换后的图片
canvas.drawBitmap(mBitmap, mRectMatrix, new Paint());
}
}

rectStaysRect
判断矩形经过变换后是否仍为矩形,假如Matrix进行了平移、缩放则画布仅仅是位置和大小改变,矩形变换后仍然为矩形,但Matrix进行了非90度倍数的旋转或者错切,则矩形变换后就不再是矩形了。
setSinCos
简介
设置sinCos值,这个是控制Matrix旋转的,由于Matrix已经封装好了Rotate方法,所以这个并不常用。
// 方法一
void setSinCos (float sinValue, // 旋转角度的sin值
float cosValue) // 旋转角度的cos值
// 方法二
void setSinCos (float sinValue, // 旋转角度的sin值
float cosValue, // 旋转角度的cos值
float px, // 中心位置x坐标
float py) // 中心位置y坐标
示例
Matrix matrix = new Matrix();
// 旋转90度
// sin90=1
// cos90=0
matrix.setSinCos(1f, 0f);
Log.i(TAG, "setSinCos:"+matrix.toShortString());
// 重置
matrix.reset();
// 旋转90度
matrix.setRotate(90);
Log.i(TAG, "setRotate:"+matrix.toShortString());
setSinCos:[0.0, -1.0, 0.0][1.0, 0.0, 0.0][0.0, 0.0, 1.0]
setRotate:[0.0, -1.0, 0.0][1.0, 0.0, 0.0][0.0, 0.0, 1.0]
矩阵相关
| 方法 | 摘要 |
|---|---|
| invert | 求矩阵的逆矩阵 |
| isAffine | 判断当前矩阵是否为仿射矩阵,API21(5.0)才添加的方法。 |
| isIdentity | 判断当前矩阵是否为单位矩阵。 |
invert
求矩阵的逆矩阵,简而言之就是计算与之前相反的矩阵,如果之前是平移200px,则求的矩阵为反向平移200px,如果之前是缩小到0.5f,则结果是放大到2倍。
boolean invert(Matrix inverse)
isAffine
判断是否是仿射矩阵最重要的一点就是,直线是否仍为直线,简单想一下就知道,不论平移,旋转,错切,缩放,直线变换后最终仍为直线,要想让isAffine()的结果变为false,除非你能把直线掰弯。
boolean isAffine()
isIdentity
判断是否为单位矩阵。

实用技巧
获取View在屏幕上的绝对位置。

@Override
protected void onDraw(Canvas canvas) {
// 方式一:
float[] values = new float[9];
int[] location1 = new int[2];
Matrix matrix = canvas.getMatrix();
matrix.getValues(values);
location1[0] = (int) values[2];
location1[1] = (int) values[5];
Log.i(TAG, "location1 = " + Arrays.toString(location1));
// 方式二:
int[] location2 = new int[2];
this.getLocationOnScreen(location2);
Log.i(TAG, "location2 = " + Arrays.toString(location2));
}
location1 = [0, 243]
location2 = [0, 243]
利用setPolyToPoly制造3D效果
Android FoldingLayout 折叠布局 原理及实现(一)
Android FoldingLayout 折叠布局 原理及实现(二)





