一、CustomPaint自绘(类似自定义View):
1.API说明:
(1)CustomPaint说明:
CustomPaint(
painter: ..., //背景绘制,在自定义CustomPainter中绘制背景
foregroundPainter: ..., //前景绘制,在自定义CustomPainter中绘制前景
size: Size(宽, 高), //child为空时指定画布宽高,child不为空时忽略此参
isComplex: false, //是否复杂绘制,是时用缓存策略(提高性能),否时不用
willChange: false, //true时下一帧绘制会改变,false时不改变。isComplex=true时生效
child: ... //子布局,可以为空
)
(2)Canvas画布:
canvas.drawLine(开始点Offset, 结束点Offset, 画笔Paint); //画线
canvas.drawPoint(画笔Paint); //画点
canvas.drawPath(路径Path, 画笔Paint); //画路径
canvas.drawImage(图片Image, 左上角Offset, 画笔Paint); //画图像
canvas.drawRect(Rect矩形, Paint画笔); //画矩形
canvas.drawCircle(圆心Offset, 半径数值, 画笔Paint); //画圆
canvas.drawOval(Rect矩形, Paint画笔); //画椭圆
canvas.drawArc(Rect矩形, 开始角度, 持续角度, true扇区或false圆环, 画笔Paint); //画圆弧
(3)Paint画笔:
Paint paint = Paint()
..isAntiAlias = true //true抗锯齿,false有锯齿
..style = PaintingStyle.stroke //画笔样式
..strokeWidth = 2 //画笔粗细
..color = Colors.red; //画笔颜色
(4)RepaintBoundary能提高性能:
RepaintBoundary(//使用RepaintBoundary包裹CustomPaint,使自定义绘制不受Widget树影响,减少CustomPaint重绘
child: ...
)
2.实现CustomPaint自绘:
(1)实现自定义CustomPainter,绘制图形:
class MyCustomPainter extends CustomPainter {
@override
void paint(Canvas canvas, Size size) {
//...在此处绘制自定义图形,例画路径
Path path = Path()
..moveTo(0, 150)
..lineTo(100, 0)
..lineTo(200, 120)
..lineTo(300, 50);
canvas.drawPath(path, mPaint); //画路径
}
@override
bool shouldRepaint(CustomPainter oldDelegate) => false; //false不会重绘, true会重绘
}
(2)创建CustomPaint,并传入自定义CustomPainter:
RepaintBoundary( //使用RepaintBoundary包裹CustomPaint,使自定义绘制不受Widget树影响,减少CustomPaint重绘
child: CustomPaint(
painter: MyCustomPainter(), //背景绘制,在自定义CustomPainter中绘制背景
foregroundPainter: MyCustomPainter(), //前景绘制,在自定义CustomPainter中绘制前景
size: Size(200, 100) //指定画布宽高
)
);
二、RenderObject自绘:
1.实现自定义RenderObjectWidget类:
class MyRenderObjectWidget extends LeafRenderObjectWidget{ //LeafRenderObjectWidget为RenderObjectWidget子类
@override
RenderObject createRenderObject(BuildContext context) {
return MyRenderObject(); //此处创建自定义RenderObject
}
@override
void updateRenderObject(context, MyRenderObject renderObject) {
//...此处更新自定义RenderObject状态
}
}
2.实现自定义RenderObject类:
class MyRenderObject extends RenderBox{ //RenderBox为RenderObject子类
int pointer = 0;
@override
bool get isRepaintBoundary => true;
//测绘方式1,size由本组件决定
@override
void performLayout() {
//父Widget有固定宽高时使用父的,没有则此处指定默认值
size = constraints.constrain(constraints.isTight ? Size.infinite : Size(100, 100));
}
//测绘方式2,size由parent组件决定,必须sizedByParent返回true
// @override
// void performResize() {
// size = constraints.biggest;
// }
// @override
// bool get sizedByParent => true;
@override
void paint(PaintingContext context, Offset offset) {//paint方法实现自定义绘图
//...绘图逻辑
}
@override
bool hitTestSelf(Offset position) => true; //true时响应点击事件,false忽略点击事件
@override
void handleEvent(PointerEvent event, covariant BoxHitTestEntry entry) { //处理点击事件
if (event.down) {
pointer = event.pointer;
return;
}
if (event.pointer == pointer && size.contains(event.localPosition)) { //判断点击是否在本组件内
log("触发点击了 handleEvent >> pointer: ${event.pointer} localPosition: ${event.localPosition}");
}
}
}