android matrix 简书,Android高级UI——PathMeasure和Matrix

需求是做一个箭头转圈圈的动画

0c27bf581df2

image

0c27bf581df2

image.png

public class PathMeasureView extends View {

private float currentValue = 0; // 用于纪录当前的位置,取值范围[0,1]映射Path的整个长度

private Bitmap mBitmap; // 箭头图片

private Matrix mMatrix; // 矩阵,用于对图片进行一些操作

private Paint mDeafultPaint;

private int mViewWidth;

private int mViewHeight;

private Paint mPaint;

public PathMeasureView(Context context) {

super(context);

init(context);

}

private void init(Context context) {

BitmapFactory.Options options = new BitmapFactory.Options();

options.inSampleSize = 8; // 缩放图片

mBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.arrow, options);

mMatrix = new Matrix();

mDeafultPaint = new Paint();

mDeafultPaint.setColor(Color.RED);

mDeafultPaint.setStrokeWidth(5);

mDeafultPaint.setStyle(Paint.Style.STROKE);

mPaint = new Paint();

mPaint.setColor(Color.DKGRAY);

mPaint.setStrokeWidth(2);

mPaint.setStyle(Paint.Style.STROKE);

}

@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);

canvas.drawColor(Color.WHITE);

// 平移坐标系

canvas.translate(mViewWidth/2,mViewHeight/2);

// 画坐标线

canvas.drawLine(-canvas.getWidth(),0,canvas.getWidth(),0,mPaint);

canvas.drawLine(0,-canvas.getHeight(),0,canvas.getHeight(),mPaint);

Path path = new Path(); // 创建 Path

/**

* Path.Direction.CCW 逆时针

* Path.Direction.CW 顺时针

*/

path.addCircle(0, 0, 200, Path.Direction.CCW); // 添加一个圆形

PathMeasure measure = new PathMeasure(path, false); // 创建 PathMeasure

// currentValue += 0.005; // 计算当前的位置在总长度上的比例[0,1]

// if (currentValue >= 1) {

// currentValue = 0;

// }

// 获取当前位置的坐标以及趋势的矩阵

measure.getMatrix(measure.getLength() * currentValue, mMatrix,

PathMeasure.TANGENT_MATRIX_FLAG | PathMeasure.POSITION_MATRIX_FLAG);

// 将图片绘制中心调整到与当前点重合(偏移加旋转)

// mMatrix.preTranslate(-mBitmap.getWidth() / 2, -mBitmap.getHeight() / 2);

canvas.drawPath(path, mDeafultPaint);

canvas.drawBitmap(mBitmap, mMatrix, mDeafultPaint);

invalidate();

}

}

画好坐标轴之后把图片加入到圆圈起点,发现图片选择旋转了90度

0c27bf581df2

image.png

mMatrix.preTranslate(-mBitmap.getWidth() / 2, 0);

使图片进行dx的反方向偏移,偏移量是图片宽一半。

0c27bf581df2

19964945-03afaa49fa74d9a2.webp.jpg

里面的dx和dy是Matrix的方向,dy表示的是该点偏离圆心的方向,dx表示逆时针切线方向,以dx方向为x轴,dy方向为y轴绘制图片,这也就说明了为啥一开始图片就旋转了90度

mMatrix.preTranslate(-mBitmap.getWidth() / 2, -mBitmap.getHeight() / 2);

再对dy进行偏移就把箭头移动到轨迹上面了。

path.addCircle(0, 0, 200, Path.Direction.CCW);

其中如果将方向改为逆时针Path.Direction.CW,那么Matrix的dx和dy就是,在ccw的基础上改变方向,也就是dy是指向圆心的,dx是顺时针的切线方向,有兴趣的同学自己试一下。

currentValue += 0.005; // 计算当前的位置在总长度上的比例[0,1]

if (currentValue >= 1) {

currentValue = 0;

}

...

invalidate();//提示系统下一次刷新界面要重新调用一次onDrow

Android 每隔 16.6ms 会刷新一次屏幕,所以每隔16.6ms,currentValue就会增加一次,measure.getLength() * currentValue为一段圆弧的长度,箭头的位置为和起点的距离就是这段圆弧,圆弧不断变长,所以箭头位置就改变一次,

该部分代码就是不断的调整箭头的位置,也就是让箭头转动起来。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值