Path
方法介绍
- computeBounds(RectF, Boolean)
- 计算Path边界,结果存在RectF中,第二个参数是否精确获取
fun computeBounds(Path path): RectF {
val rectF = RectF()
path.computeBounds(rectF, true)
return rectF
}
// 相对精确
fun computeBounds(Path path): RectF {
val rectF = RectF()
path.computeBounds(rectF, true)
val figureLocation = Rect(floor(rectF.left).toInt(), floor(rectF.top).toInt() , ceil(rectF.right).toInt(), ceil(rectF.bottom).toInt())
val bounds = Rect()
val region = Region()
region.setPath(path, new Region(figureLocation)); region.getBounds(bounds)
return RectF(bounds)
}
- Path.addPath优于Path.addRoundRect
两条Path是否有交集
fun checkInterEraser(Path path1, Path path2): Boolean {
val wh = ResTool.windowWH()
Region clip = new Region(0, 0, wh[0], wh[1])
Region eRegion = new Region()
eRegion.setPath(path1, clip)
Region sRegion = new Region()
sRegion.setPath(path, clip)
if (!eRegion.quickReject(sRegion) && eRegion.op(sRegion, Region.Op.INTERSECT)) {
return true
}
return false
}
fun getPath(points: List<Point>): Path {
if (points.isNullOrEmpty()) {
return null
}
final int size = points.size()
Path tempPath = new Path()
tempPath.moveTo(points.get(0).x, points.get(0).y)
PointF preP
PointF curP
for (int index = 0; index < size - 1; index++) {
preP = points.get(index)
curP = points.get(index + 1)
tempPath.quadTo(preP.x, preP.y, (preP.x + curP.x) / 2, (preP.y + curP.y) / 2)
}
return tempPath
}
PathMeasure实现路径动画
- PathMeasure可计算出指定路径信息:路径总长度、指定长度对应坐标
// 方式一
val pathMeasure = PathMeasure()
val path = Path()
// forceClosed:true,强制闭合计算终点到起点的距离,forceClosed仅对测量有影响,不会影响关联的path
pathMeasure.setPath(path, true)
// 方式二
val path = Path()
val pathMeasure = PathMeasure(path, true)
- 常用方法
// 获取路径长度:forceClosed:true强制闭合,true > false
fun getLength(): Float
// 是否闭合
fun isClosed(): Boolean
// path由多条曲线构成(addXxx()),用于跳转下一个线段,true:跳转成功
fun nextContour(): Boolean
// 线段截取:[startD, stopD] in [0, pathLength],截取线段添加至dst
// startWithMoveTo:true新线段移动至dst起点,false新线段移动至dst终点(上一线段终点)
// 注意:使用该方法需禁用硬件加速setLayerType(View.LAYER_TYPE_SOFTWARE, null)
fun getSegment(startD: Float, stopD: Float, dst: Path, startWithMoveTo: Boolean)
- 路径实现加载动画
package com.dcxing.draw.tool
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.Path
import android.graphics.PathMeasure
object ProgressTool {
private val paint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
color = Color.BLUE
style = Paint.Style.STROKE
strokeCap = Paint.Cap.ROUND
strokeJoin = Paint.Join.ROUND
strokeWidth = 6f
}
private val circlePath = Path()
private val dstPath = Path()
private val pathMeasure = PathMeasure()
var curAnimValue = 0f
init {
circlePath.addCircle(90f, 90f, 45f, Path.Direction.CW)
pathMeasure.setPath(circlePath, true)
}
fun render(canvas: Canvas) {
canvas.save()
canvas.translate(300f, 0f)
val length = pathMeasure.length
val stop = length * curAnimValue
val start =
if (curAnimValue > 0.75f)
(2 * curAnimValue - 1f) * length
else if (curAnimValue > 0.25f)
stop - 0.25f * length
else
0f
dstPath.reset()
pathMeasure.getSegment(start, stop, dstPath, true)
canvas.drawPath(dstPath, paint)
canvas.restore()
}
}