因此,我尝试使用Flutter创建一个绘图应用程序,遵循“签名画布”方法。但是,我在更改CustomPaint对象的颜色时遇到了问题,因为它在更改之前已经更改了每个线条绘制的颜色,如下所示:
正如你所看到的,一旦页面小部件的状态改变,颜色就会发生变化(无论是通过点击主FAB还是再次在画布上绘制)。下面是我的DrawPage代码:
class DrawPage extends StatefulWidget {
@override
DrawPageState createState() => new DrawPageState();
}
class DrawPageState extends State<DrawPage> with TickerProviderStateMixin {
AnimationController controller;
List<Offset> points = <Offset>[];
Color color = Colors.black;
StrokeCap strokeCap = StrokeCap.round;
double strokeWidth = 5.0;
@override
void initState() {
super.initState();
controller = new AnimationController(
vsync: this,
duration: const Duration(milliseconds: 500),
);
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child: GestureDetector(
onPanUpdate: (DragUpdateDetails details) {
setState(() {
RenderBox object = context.findRenderObject();
Offset localPosition =
object.globalToLocal(details.globalPosition);
points = new List.from(points);
points.add(localPosition);
});
},
onPanEnd: (DragEndDetails details) => points.add(null),
child: CustomPaint(
painter: Painter(
points: points,
color: color,
strokeCap: strokeCap,
strokeWidth: strokeWidth),
size: Size.infinite,
),
),
),
floatingActionButton:
Column(mainAxisSize: MainAxisSize.min, children: <Widget>[
Container(
height: 70.0,
width: 56.0,
alignment: FractionalOffset.topCenter,
child: ScaleTransition(
scale: CurvedAnimation(
parent: controller,
curve: Interval(0.0, 1.0 - 0 / 3 / 2.0, curve: Curves.easeOut),
),
child: FloatingActionButton(
mini: true,
child: Icon(Icons.clear),
onPressed: () {
points.clear();
},
),
),
),
Container(
height: 70.0,
width: 56.0,
alignment: FractionalOffset.topCenter,
child: ScaleTransition(
scale: CurvedAnimation(
parent: controller,
curve: Interval(0.0, 1.0 - 1 / 3 / 2.0, curve: Curves.easeOut),
),
child: FloatingActionButton(
mini: true,
child: Icon(Icons.lens),
onPressed: () {},
),
),
),
Container(
height: 70.0,
width: 56.0,
alignment: FractionalOffset.topCenter,
child: ScaleTransition(
scale: CurvedAnimation(
parent: controller,
curve:
Interval(0.0, 1.0 - 2 / 3 / 2.0, curve: Curves.easeOut),
),
child: FloatingActionButton(
mini: true,
child: Icon(Icons.color_lens),
onPressed: () async {
Color temp;
temp = await showDialog(
context: context,
builder: (context) => ColorDialog());
if (temp != null) {
setState(() {
color = temp;
});
}
}))),
FloatingActionButton(
child: AnimatedBuilder(
animation: controller,
builder: (BuildContext context, Widget child) {
return Transform(
transform: Matrix4.rotationZ(controller.value * 0.5 * math.pi),
alignment: FractionalOffset.center,
child: Icon(Icons.brush),
);
},
),
onPressed: () {
if (controller.isDismissed) {
controller.forward();
} else {
controller.reverse();
}
},
),
]),
);
}
}
到目前为止我尝试过的:
我尝试过如何将点添加到我的偏移列表中,因为这个列表在每个“绘制”手势之后都会重新创建,例如只是添加到当前列表而不重新创建它,但这会破坏“绘制”手势:
setState(() {
RenderBox object = context.findRenderObject();
Offset localPosition =
object.globalToLocal(details.globalPosition);
points = new List.from(points);
points.add(localPosition);
});
我尝试在build()作用域之外引用CustomPaint对象或我的Painter对象,并以这种方式更新color属性,但这也破坏了“绘制”手势。
任何帮助将不胜感激!
另外,这里是我的Painter类的代码,以防人们希望看到它:
class Painter extends CustomPainter {
List<Offset> points;
Color color;
StrokeCap strokeCap;
double strokeWidth;
Painter({this.points, this.color, this.strokeCap, this.strokeWidth});
@override
void paint(Canvas canvas, Size size) {
Paint paint = new Paint();
paint.color = color;
paint.strokeCap = strokeCap;
paint.strokeWidth = strokeWidth;
for (int i = 0; i < points.length - 1; i++) {
if (points[i] != null && points[i + 1] != null) {
canvas.drawLine(points[i], points[i + 1], paint);
}
}
}
@override
bool shouldRepaint(Painter oldPainter) => oldPainter.points != points;
}
3条答案
按热度按时间mo49yndu1#
我认为,对于不同的颜色,你必须使用不同的油漆。我对你的代码做了一些小的修改,它工作了。
1yjd4xko2#
2020年,我有一个很好的解决方案,因为实际选择的对我不起作用,我看到一些冗余的调用。
所以,我开始创建一个小类:
接下来,我像这样声明我的
CustomPainter
:在我的widget上:
在这种方式下,我们可以使用多个绘制点与各自的颜色。希望这可以帮助任何人。
mwg9r5ms3#
根据Flutter架构,整个绘图是单个路径。
所以当我们改变其他画的颜色时,整个画的颜色也会改变。
在每次绘图结束后使用“path.reset()”。