2 回答
TA贡献1801条经验 获得超8个赞
fun test() {
Canvas().bindPaintDrawPoints(Paint())(
arrayOf(PointF(1f, 2f),
PointF(2f, 2f),
PointF(3f, 2f),
PointF(4f, 2f))
)
}
fun Canvas.bindPaintDrawPoints(paint: Paint): (Array<PointF>) -> Unit {
return {
drawPoints(paint, it)
}
}
fun Canvas.drawPoints(paint: Paint, points: Array<PointF>) {
for (p in points) {
this.drawPoint(p.x, p.y, paint)
}
}
TA贡献1815条经验 获得超13个赞
完美符合你要求的方式肯定是没有的,因为 bind 函数不可能改变另一个函数内部的局部变量。
折中的方式也有很多,比如定义一个包级属性:
var drawPaint: Paint? = null
然后原来的函数改为:
inline fun Canvas.drawPoint( point: PointF, paint: Paint) { paint?.let { drawPoint(point.x, point.y, it) } }
方便使用还可以再定义一个函数来确保 drawPaint 能被准确的赋值和释放:
fun bindPaint(paint: Paint, action: () -> Unit) { drawPaint = paint action() drawPaint = null}
这样使用时就是:
// Canvas().apply {bindPaint(somePaint) { drawPoint(x, y) }
还有一种方式是定义一个包装类,并在其中定义一个包含带接收者 Lambda 表达式的参数的函数(接收者为 Canvas),然后将扩展函数定义到这个类中:
class PointPainter(private val paint: Paint) { fun Canvas.drawPoint(rect: RectF) { drawPoint(rect.x, rect.y, paint) } }
然后定义含有接收者为这个包装对象 Lambda 参数的函数:
fun bindPointPainter(paint: Paint, drawAction: PointPainter.() -> Unit) { PointPainter(paint).drawAction() }
这样用时更方便一些:
// in canvas.apply blockbindPointPainter(somePaint) { drawPoint(rect1) drawPoint(rect2) // ...}
- 2 回答
- 0 关注
- 1268 浏览
添加回答
举报