Path
-
path常用api
moveTo(float x, float y) | 移动下一次操作的起点位置 |
lineTo(float x, float y) | 添加上一个点到当前点之间的直线到Path |
addRect, addRoundRect, addOval, addCircle, addPath, addArc, arcTo | 添加(矩形, 圆角矩形, 椭圆, 圆, 路径, 圆弧) 到当前Path |
close() | 连接第一个点连接到最后一个点,形成一个闭合区域 |
quadTo, cubicTo | 分别为二次和三次贝塞尔曲线的方法 |
reset,rewind | 清除Path中的内容(reset相当于重置到new Path阶段,rewind会保留Path的数据结构) |
.....就不列完了,以上就是Path基本上在开发中是用的次数较多的api
PathMeasure
-
pathMeasure 常用Api
getLength() | 返回当前轮廓的总长度,如果没有路径与此度量对象关联,则返回0。 |
getSegment(float startD, float stopD, Path dst, boolean startWithMoveTo) | 给定起点和终点的距离,返回截取的中间段 |
setPath(Path path, boolean forceClosed) | 将新的测量路径分配给一个新Path,如果null 则不显示。 |
这是最常用的测量PathMeasure Api
以下是结合项目中对Path 和 PathMeasure 的使用实例:
项目背景: 要求一个光标块在 矩形上移动,移动速度可更加手机充电速度变化,如下图
相关API: addRoundRect(绘制矩形)、setPath(赋值path路径)
reset(清除Path中的内容,清除之前的路径)、getLength(获取路径的长度)
getSegment(截取一段path路径)
-
关键代码
初始化矩形path并且测量这个path
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
segmentPath = new Path();
path = new Path();
path.addRoundRect(
getPaddingLeft() + strokeWidth,
getPaddingTop() + strokeWidth,
getMeasuredWidth() - strokeWidth,
getMeasuredHeight() - strokeWidth,
100, 100, Path.Direction.CCW);
pathMeasure.setPath(path, true);
}
计算startD(截取片段开始位置) stopD(截取片段结束位置),截取到片段后赋值给新的Path(光标移动path)
@SuppressLint("DrawAllocation")
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
segmentPath.reset();
canvas.drawPath(path, paint);
float length = pathMeasure.getLength();
float stopD = mFloatPos * length;
float startD = 0f;
if (stopD < lineLength) {
startD = 0;
} else {
startD = stopD - lineLength;
}
//截取片段
pathMeasure.getSegment(startD, stopD, segmentPath, true);
canvas.drawPath(segmentPath, segmentPaint);
if (stopD < lineLength) {
float mStart2 = length - (lineLength - stopD);
pathMeasure.getSegment(mStart2, length, segmentPath, true);
canvas.drawPath(segmentPath, segmentPaint);
}
}
开始动画,通过valueAnimator 动画,可以试试获取当前位置的信息 mFloatPost,然后通过mFloatPost
去计算StopD 的位置。
public void startAnim() {
if (valueAnimator == null) {
valueAnimator = ValueAnimator.ofFloat(0, 1);
valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
mFloatPos = (float) animation.getAnimatedValue();
invalidate();
}
});
valueAnimator.setDuration(4000);
valueAnimator.setRepeatCount(ValueAnimator.INFINITE);
valueAnimator.setInterpolator(new LinearInterpolator());
valueAnimator.start();
}
}
public void stopAnim() {
if (valueAnimator != null) {
valueAnimator.cancel();
valueAnimator = null;
}
}
..... 以上就关键代码
-
使用方式
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
roundPathView = findViewById(R.id.round_path);
roundPathView.startAnim();
}
@Override
protected void onDestroy() {
super.onDestroy();
if (roundPathView!=null){
roundPathView.stopAnim();
}
}