SeniorUI_目录
SeniorUI1001_PathMeasure语法
一、效果图:
二、原理
- 先绘制一个圆的Path
- 定义一个currentValue 记录当前时刻箭头在圆的位置,currentValue 从0 到1,每次绘制自增0.005,到1后归零
- 通过PathMeasure取圆的对应currentValue 位置
- 利用PathMeasure的API获取对应位置的参数(坐标、斜率)
- 设置箭头图片的参数,并且绘制图片
- 不断重绘
三、Core Code
public class MyView1 extends View {
private float currentValue = 0; // 用于纪录当前的位置,取值范围[0,1]映射Path的整个长度
private float[] pos; // 当前点的实际位置
private float[] tan; // 当前点的tangent值,用于计算图片所需旋转的角度
private Bitmap mBitmap; // 箭头图片
private Matrix mMatrix; // 矩阵,用于对图片进行一些操作
private Paint mDeafultPaint;
private int mViewWidth;
private int mViewHeight;
private Paint mPaint;
public MyView1(Context context) {
this(context,null);
public MyView1(Context context, @Nullable AttributeSet attrs) {
this(context, attrs,0);
}
public MyView1(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(context);
}
private void init(Context context) {
pos = new float[2];
tan = new float[2];
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.addCircle(0, 0, 200, Path.Direction.CW); // 添加一个圆形
PathMeasure measure = new PathMeasure(path, false); // 创建 PathMeasure
currentValue += 0.005; // 计算当前的位置在总长度上的比例[0,1]
if (currentValue >= 1) {
currentValue = 0;
}
// 方案一
/*// 获取当前位置的坐标以及趋势
measure.getPosTan(measure.getLength() * currentValue, pos, tan);
// 重置Matrix
mMatrix.reset();
// 计算图片旋转角度
float degrees = (float) (Math.atan2(tan[1], tan[0]) * 180.0 / Math.PI);
// 旋转图片
mMatrix.postRotate(degrees, mBitmap.getWidth() / 2, mBitmap.getHeight() / 2);
// 将图片绘制中心调整到与当前点重合
mMatrix.postTranslate(pos[0] - mBitmap.getWidth() / 2, pos[1] - mBitmap.getHeight() / 2);*/
// 方案二
// 获取当前位置的坐标以及趋势的矩阵
measure.getMatrix(measure.getLength() * currentValue, mMatrix,
PathMeasure.TANGENT_MATRIX_FLAG | PathMeasure.POSITION_MATRIX_FLAG);
// 将图片绘制中心调整到与当前点重合(注意:此处是前乘pre)
mMatrix.preTranslate(-mBitmap.getWidth() / 2, -mBitmap.getHeight() / 2);
canvas.drawPath(path, mDeafultPaint);
canvas.drawBitmap(mBitmap, mMatrix, mDeafultPaint);
invalidate();
}
}