需求是做一个箭头转圈圈的动画
imageimage.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度
image.png
mMatrix.preTranslate(-mBitmap.getWidth() / 2, 0);
使图片进行dx的反方向偏移,偏移量是图片宽一半。
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为一段圆弧的长度,箭头的位置为和起点的距离就是这段圆弧,圆弧不断变长,所以箭头位置就改变一次,
该部分代码就是不断的调整箭头的位置,也就是让箭头转动起来。
网友评论