Skip to content

Commit 00d6134

Browse files
committed
add pathmeasure customview
1 parent 48f7c35 commit 00d6134

File tree

2 files changed

+97
-0
lines changed

2 files changed

+97
-0
lines changed
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
# PathMeasure
2+
3+
PathMeasure是一个测量Path的路径的一个方法,我们今天的demo就是要做这样一个小东西,它会反复测量,运动的路径,并且沿着路径运行。
4+
5+
效果图:
6+
7+
![](https://ws3.sinaimg.cn/large/006tNc79ly1fh3i8c4k9ag309q0gagp9.gif)
8+
9+
实现的具体思路,就是,采用一个循环,反复的调用画图的方法,然后每当满一周之后,清零,再重新开始,为什么能沿着切线运动呢,是调用了一个参数,动态测量这个tan值。
10+
11+
代码:
12+
13+
```
14+
public class CustomView extends View {
15+
16+
private float currentValue = 0; // 用于纪录当前的位置,取值范围[0,1]映射Path的整个长度
17+
18+
private float[] pos; // 当前点的实际位置
19+
private float[] tan; // 当前点的tangent值,用于计算图片所需旋转的角度
20+
private Bitmap mBitmap; // 箭头图片
21+
private Matrix mMatrix; // 矩阵,用于对图片进行一些操作
22+
23+
private Paint mPaint;
24+
25+
private int mViewWidth;
26+
private int mViewHeight;
27+
28+
public CustomView(Context context) {
29+
this(context, null);
30+
}
31+
32+
public CustomView(Context context, @Nullable AttributeSet attrs) {
33+
super(context, attrs);
34+
init(context);
35+
mPaint = new Paint();
36+
mPaint.setColor(Color.BLACK);
37+
mPaint.setStrokeWidth(8);
38+
mPaint.setStyle(Paint.Style.STROKE);
39+
mPaint.setTextSize(60);
40+
41+
42+
}
43+
44+
private void init(Context context) {
45+
pos = new float[2];
46+
tan = new float[2];
47+
BitmapFactory.Options options = new BitmapFactory.Options();
48+
options.inSampleSize = 15; // 缩放图片
49+
mBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.arrowhead, options);
50+
mMatrix = new Matrix();
51+
}
52+
53+
54+
@Override
55+
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
56+
super.onSizeChanged(w, h, oldw, oldh);
57+
mViewHeight = h;
58+
mViewWidth = w;
59+
60+
}
61+
62+
@Override
63+
protected void onDraw(Canvas canvas) {
64+
super.onDraw(canvas);
65+
canvas.translate(mViewWidth / 2, mViewHeight / 2); // 平移坐标系
66+
67+
Path path = new Path(); // 创建 Path
68+
69+
path.addCircle(0, 0, 200, Path.Direction.CW); // 添加一个圆形
70+
71+
PathMeasure measure = new PathMeasure(path, false); // 创建 PathMeasure
72+
73+
currentValue += 0.005; // 计算当前的位置在总长度上的比例[0,1]
74+
if (currentValue >= 1) {
75+
currentValue = 0;
76+
}
77+
78+
measure.getPosTan(measure.getLength() * currentValue, pos, tan); // 获取当前位置的坐标以及趋势
79+
80+
mMatrix.reset(); // 重置Matrix
81+
float degrees = (float) (Math.atan2(tan[1], tan[0]) * 180.0 / Math.PI); // 计算图片旋转角度
82+
83+
mMatrix.postRotate(degrees, mBitmap.getWidth() / 2, mBitmap.getHeight() / 2); // 旋转图片
84+
mMatrix.postTranslate(pos[0] - mBitmap.getWidth() / 2, pos[1] - mBitmap.getHeight() / 2); // 将图片绘制中心调整到与当前点重合
85+
86+
canvas.drawPath(path, mPaint); // 绘制 Path
87+
canvas.drawBitmap(mBitmap, mMatrix, mPaint); // 绘制箭头
88+
89+
invalidate();
90+
}
91+
92+
}
93+
94+
```
95+
96+
代码地址:https://github.com/linsir6/mCustomView/tree/master/TestPathMeasure

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ Android-Note里面记录了有关Android的常用基础知识、面试中经常
4646
- [三阶贝塞尔曲线](/Android自定义View/三阶贝塞尔曲线.md)
4747
- [贝塞尔曲线Demo](https://github.com/linsir6/mCustomView/tree/master/BezierDemo)
4848
- [具有弹性的小球](https://github.com/linsir6/mCustomView/tree/master/MagicCircle)
49+
- [PathMeasure](/Android自定义View/PathMeasure.md)
4950

5051

5152
### 面试题

0 commit comments

Comments
 (0)