我做了2个定制画家
1.
class DrawTriangle1 extends CustomPainter {
DrawTriangle1() {
painter = Paint()
..shader =
LinearGradient(colors: [Colors.red, Colors.white]).createShader(rect)
..style = PaintingStyle.fill;
}
@override
void paint(Canvas canvas, Size size) {
var path = Path();
path.moveTo(0, 0);
path.lineTo(size.width, 0);
path.lineTo(size.width, size.height / 2);
path.close();
canvas.drawPath(path, painter);
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
return true;
}
}
class DrawTriangle2 extends CustomPainter {
DrawTriangle2() {
painter = Paint()
..shader = LinearGradient(colors: [
Color(0xfffff),
Color(0xff076585),
]).createShader(rect)
..style = PaintingStyle.fill;
}
@override
void paint(Canvas canvas, Size size) {
var path = Path();
path.lineTo(size.width / 2, size.height / 4);
path.lineTo(0, size.height / 2);
path.close();
canvas.drawPath(path, painter);
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
return true;
}
}
如果我使用自定义画家来制作单个形状。画家从页面的开头开始绘制。
ListView(
children: <Widget>[
CustomPaint(
painter: DrawTriangle1(),
size: Size(MediaQuery.of(context).size.width,
MediaQuery.of(context).size.height), ,
)
],
)
但是如果我像这样向列表视图添加另一个。第二个三角形从第一个屏幕的底部开始。
ListView(
children: <Widget>[
CustomPaint(
painter: DrawTriangle1(),
size: Size(MediaQuery.of(context).size.width,
MediaQuery.of(context).size.height),
),
CustomPaint(
painter: DrawTriangle2(),
size: Size(MediaQuery.of(context).size.width,
MediaQuery.of(context).size.height),
)
],
),
如何使两者具有相同的起点?
ListView 逐个构建它的每个子级,因此如果您想在堆栈小部件方便的同一位置做一些工作,这是预期的行为。它将允许您在同一位置绘制两个自定义画家。
因此,将 ListView 小部件替换为 stack Widget 将解决您的问题。
Stack( //change
children: <Widget>[
CustomPaint(
painter: DrawTriangle1(),
size: Size(MediaQuery.of(context).size.width,
MediaQuery.of(context).size.height),
),
CustomPaint(
painter: DrawTriangle2(),
size: Size(MediaQuery.of(context).size.width,
MediaQuery.of(context).size.height),
)
],
),
使用堆栈。
@override
Widget build(BuildContext context) {
return Stack(children: [
CustomPaint(
painter: DrawTriangle1(),
size: Size(MediaQuery.of(context).size.width,
MediaQuery.of(context).size.height),
),
CustomPaint(
painter: DrawTriangle2(),
size: Size(MediaQuery.of(context).size.width,
MediaQuery.of(context).size.height),
)
]);
}
要组合两个 CustomPainter,您需要创建一个新类,将它们作为输入,然后在其重写的 Paint(Canvas, Size) 函数中绘制它们。
我没有设法解决的唯一问题是 shouldRepaint() 函数,所以我总是在那里返回 true,因为在我的情况下,它需要在每一帧中重新绘制。
这是我的实现:
import 'package:flutter/material.dart';
class CombinedPainter extends CustomPainter {
const CombinedPainter(this.customPainters, this.customPainter2);
final CustomPainter customPainter1;
final CustomPainter customPainter2;
@override
void paint(Canvas canvas, Size size) {
customPainter1.paint(canvas, size);
customPainter2.paint(canvas, size);
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
// Change this depending on your needs
return true;
}
}
您还可以使其能够处理无数的 CustomPainter:
import 'package:flutter/material.dart';
class CombinedPainter extends CustomPainter {
const CombinedPainter(this.customPainters);
final List<CustomPainter> customPainters;
@override
void paint(Canvas canvas, Size size) {
for (customPainter in customPainters) {
customPainter.paint(canvas, size);
}
}
@override
bool shouldRepaint(covariant CustomPainter oldDelegate) {
// Change this depending on your needs
return true;
}
}