问题描述
在用户点击后,我希望画布重绘,但它从来没有。我尝试使用 setState 并返回不同的画家,但似乎没有任何效果。如果我翻转屏幕或用它自己替换页面,它会重新粉刷,但这确实效率低下并且看起来不太好。我尝试自己研究这个,但所有潜在的答案都太令人困惑而无法理解或根本不起作用。任何帮助将不胜感激。
以下是代码的相关部分:
import 'package:Flutter/material.dart';
class Playpage extends MaterialPageRoute<Null> {
Playpage() : super(builder: (BuildContext ctx) {
return Scaffold(
appBar:PreferredSize(
preferredSize: Size.fromHeight(40.0),child:AppBar(
title: Text('Level!'),centerTitle: true,),body: Container(
color: Colors.white,padding: EdgeInsets.symmetric(horizontal: 50,vertical: 0),child: LayoutBuilder(
// Inner yellow container
builder: (_,constraints) => Container(
width: constraints.widthConstraints().maxWidth,height: constraints.heightConstraints().maxHeight,color: Colors.yellow,child:
GestureDetector(
onTap: () {
//Navigator.pushReplacement(ctx,Playpage());
},onTapDown: (TapDownDetails details) => _onTapDown(details),child: new CustomPaint (painter: new BoardPainter()),);
}
);
}
Color colour= Colors.white;
class BoardPainter extends CustomPainter {
@override
bool shouldRepaint(CustomPainter oldDelegate){
return true;}
@override
// Todo: draw something with canvas
void paint(Canvas canvas,Size size){
canvas.drawRRect(
RRect.fromrectAndRadius(Rect.fromLTWH(200,200,100,100),Radius.circular(20)),Paint() ..color = colour,);
}
}
_onTapDown(TapDownDetails details) {
//setState() {
colour = Colors.blue;
BoardPainter();
//}
}
解决方法
如documentation中所述:
触发重绘的最有效方法是: 扩展此类并向 CustomPainter 的构造函数提供重绘参数,该对象在需要重绘时通知其侦听器。 扩展 Listenable(例如通过 ChangeNotifier)并实现 CustomPainter,以便对象本身直接提供通知。
在 CustomPainter
中触发重绘的两种推荐方式之一,也是最简单的路径是通过 Listenable
。
我们可以这样做:
class Playpage extends MaterialPageRoute<Null> {
...
final _counter = ValueNotifier<int>(0);
BoardPainter painter;
@override
void initState() {
super.initState();
painter = BoardPainter(repaint: _counter);
}
...
child: CustomPaint(
painter: painter,),...
...
bool repaint() {
_counter.value++;
return true;
}
...
}
class BoardPainter extends CustomPainter {
BoardPainter({Listenable repaint}): super(repaint: repaint);
@override
void paint(Canvas canvas,Size size) {
// Draw
}
@override
bool shouldRepaint(CustomPainter oldDelegate) {
return true;
}
}