网络测速全解析之一:自定义View基础知识(六)

一、PathMeasure讲解:

PathMeasure是一个用来测量Path的类,主要方法如下

构造方法

方法名释义
PathMeasure()创建一个空的PathMeasure
PathMeasure(Path path, boolean forceClosed)创建 PathMeasure 并关联一个指定的Path(Path需要已经创建完成)。

公共方法

返回值方法名释义
voidsetPath(Path path, boolean forceClosed)关联一个Path
booleanisClosed()是否闭合
floatgetLength()获取Path的长度
booleannextContour()跳转到下一个轮廓
booleangetSegment(float startD, float stopD, Path dst, boolean startWithMoveTo)截取片段
booleangetPosTan(float distance, float[] pos, float[] tan)获取指定长度的位置坐标及该点切线值
booleangetMatrix(float distance, Matrix matrix, int flags)获取指定长度的位置坐标及该点Matrix

PathMeasure的使用需要关联相应的Path,两种构造函数都要实现这个,只是第二个参数中要求有需要关联的path,所以第一个需要在创建一个空的PathMeasure之前调用setPath来进行关联。

 

 

getSegment:

获取Path的一个片段

参数作用备注
返回值(boolean)判断截取是否成功true 表示截取成功,结果存入dst中,false 截取失败,不会改变dst中内容
startD开始截取位置距离 Path 起点的长度取值范围: 0 <= startD < stopD <= Path总长度
stopD结束截取位置距离 Path 起点的长度取值范围: 0 <= startD < stopD <= Path总长度
dst截取的 Path 将会添加到 dst 中注意: 是添加,而不是替换
startWithMoveTo起始点是否使用 moveTo用于保证截取的 Path 第一个点位置不变

【dst注意:这里是添加到dst中,而不是替换dst】

 

nextContour

我们知道 Path 可以由多条曲线构成,但不论是 getLength , getgetSegment 或者是其它方法,都只会在其中第一条线段上运行,而这个 nextContour 就是用于跳转到下一条曲线到方法,如果跳转成功,则返回 true, 如果跳转失败,则返回 false。

canvas.translate(mViewWidth / 2, mViewHeight / 2); // 平移坐标系

Path path = new Path();

path.addRect(-100, -100, 100, 100, Path.Direction.CW); // 添加小矩形
path.addRect(-200, -200, 200, 200, Path.Direction.CW); // 添加大矩形

canvas.drawPath(path,mDeafultPaint); // 绘制 Path

PathMeasure measure = new PathMeasure(path, false); // 将Path与PathMeasure关联

float len1 = measure.getLength(); // 获得第一条路径的长度

measure.nextContour(); // 跳转到下一条路径

float len2 = measure.getLength(); // 获得第二条路径的长度

Log.i("LEN","len1="+len1); // 输出两条路径的长度
Log.i("LEN","len2="+len2);

 

getPosTan

boolean getPosTan (float distance, float[] pos, float[] tan)

参数作用备注
返回值(boolean)判断获取是否成功

true表示成功,数据会存入 pos 和 tan 中,

false 表示失败,pos 和 tan 不会改变

distance距离 Path 起点的长度取值范围: 0 <= distance <= getLength
pos该点的坐标值当前点在画布上的位置,有两个数值,分别为x,y坐标。
tan该点的正切值当前点在曲线上的方向,使用 Math.atan2(tan[1], tan[0]) 获取到正切角的弧度值。

定义变量:

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

private float[] pos; // 当前点的实际位置
private float[] tan; // 当前点的tangent值,用于计算图片所需旋转的角度
private Bitmap mBitmap; // 箭头图片
private Matrix mMatrix; // 矩阵,用于对图片进行一些操作

初始化变量:

private void init(Context context) {
pos = new float[2];
tan = new float[2];
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize = 2; // 缩放图片
mBitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.arrow, options);
mMatrix = new Matrix();
}

具体绘制:

canvas.translate(mViewWidth / 2, mViewHeight / 2); // 平移坐标系

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); // 获取当前位置的坐标以及趋势

mMatrix.reset(); // 重置Matrix
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); // 将图片绘制中心调整到与当前点重合

canvas.drawPath(path, mDeafultPaint); // 绘制 Path
canvas.drawBitmap(mBitmap, mMatrix, mDeafultPaint); // 绘制箭头

invalidate(); // 重绘页面

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值