gpt4 book ai didi

android - 更改 CustomPaint 的颜色会更改所有先前的点

转载 作者:IT王子 更新时间:2023-10-29 06:43:36 26 4
gpt4 key购买 nike

因此,我正在尝试按照“签名 Canvas ”方法使用 Flutter 创建一个绘图应用程序。但是,我无法更改 CustomPaint 对象的颜色,而它在更改之前已经更改了每条线条绘制的颜色,如下所示: enter image description here

如您所见,一旦页面小部件的状态发生变化(通过单击主 FAB 或再次在 Canvas 上绘制),颜色就会发生变化。下面是我的 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 对象并以这种方式更新颜色属性,但这也会破坏“绘制”手势。

任何帮助将不胜感激!

此外,这里是我的 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;
}

最佳答案

我认为,对于不同的颜色,您必须使用不同的 Paints。我对您的代码进行了一些小改动,效果很好。

class DrawPageState extends State<DrawPage> with TickerProviderStateMixin {
...
List<Painter> painterList = [];

@override
Widget build(BuildContext context) {
...
child: CustomPaint(
painter: Painter(
points: points, color: color, strokeCap: strokeCap, strokeWidth: strokeWidth, painters: painterList),
size: Size.infinite,
),
...
onPressed: () async {
Color temp;
temp = await showDialog(
context: context,
builder: (context) => ColorDialog());
if (temp != null) {
setState(() {
painterList
.add(Painter(points: points.toList(), color: color, strokeCap: strokeCap, strokeWidth: strokeWidth));
points.clear();
strokeCap = StrokeCap.round;
strokeWidth = 5.0;
color = temp;
});
}
...
}
}

class Painter extends CustomPainter {
List<Offset> points;
Color color;
StrokeCap strokeCap;
double strokeWidth;
List<Painter> painters;

Painter({this.points, this.color, this.strokeCap, this.strokeWidth, this.painters = const []});

@override
void paint(Canvas canvas, Size size) {
for (Painter painter in painters) {
painter.paint(canvas, size);
}

Paint paint = new Paint()
..color = color
..strokeCap = strokeCap
..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 oldDelegate) => oldDelegate.points != points;
}

关于android - 更改 CustomPaint 的颜色会更改所有先前的点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53186525/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com