在以下代码中,我尝试模拟画布上的小部件。
当小部件/按钮被触摸时,它会在两种颜色之间翻转。
我了解到需要使用
我还了解到需要通过
相关链接: 1, 2.
import 'package:flutter/material.dart';
void main() { runApp(MyApp()); }
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Diagram',
theme: ThemeData(
appBarTheme: AppBarTheme(color: Colors.blueAccent,),
),
home: Diagram(),
);
}
}
class Diagram extends StatefulWidget {
@override
_DiagramState createState() => new _DiagramState();
}
class _DiagramState extends State<Diagram> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Canvas Widgets'),
centerTitle: true,
),
body: Center(
child: GestureDetector(
onTapUp: (TapUpDetails details) {
setState(() {
;
});
},
child: AspectRatio(
aspectRatio: 1.0,
child: Container(
child: CustomPaint(
painter: DiagramPainter(),
),
),
),
),
),
);
}
}
class DiagramPainter extends CustomPainter {
// class DiagramPainter extends ChangeNotifier implements CustomPainter {
DiagramPainter() {
for(int i=0; i<_numberOfButtons; i++) {
state.add(false);
}
}
static final int _numberOfButtons = 3;
static final double _margin = 60;
static final double _gap = _margin / 2.0 / _numberOfButtons.toDouble();
double width;
double y;
static Canvas currentCanvas;
var buttons = [];
var state = [];
final bluePaint = Paint()
..color = Colors.blue;
final yellowPaint = Paint()
..color = Colors.yellow;
@override
void paint(Canvas canvas, Size size) {
currentCanvas = canvas;
width = (size.width - _margin) /_numberOfButtons.toDouble();
y = size.height / 2.0 - width / 2.0;
Iterable<int>.generate(_numberOfButtons).toList().forEach((index) {
buttons.add(drawButton(canvas, index));
});
}
Rect drawButton(Canvas canvas, int index) {
double left = _gap + index * (width + _gap * 2.0);
var rect = Rect.fromLTWH(left, y, width, width);
var paint = state[index] ? yellowPaint : bluePaint;
canvas.drawOval(rect, paint);
return rect;
}
@override
bool hitTest(Offset position) {
for(int i=0; i<_numberOfButtons; i++) {
if (buttons[i].contains(position)) {
state[i] = !state[i];
// trigger redraw
// notifyListeners();
return true;
}
}
return false;
}
@override
bool shouldRepaint(CustomPainter oldDelegate) => true;
}
我了解到需要使用
class DiagramPainter extends ChangeNotifier implements CustomPainter
而不是 class DiagramPainter extends CustomPainter
。我还了解到需要通过
notifyListeners()
触发重绘。在这种情况下,谁被通知了?仍然是 DiagramPainter
,对吗?我错过了什么吗?相关链接: 1, 2.
ChangeNotifier
mixin的存在,如何使notifyListeners()
调用paint()
方法呢?例如,paint()
是否以某种方式声明为CustomPainter
的变化通知代理呢? - undefinedvoid addListener(listener) {
方法,并调用print(listener);
来查看传递的参数。 - undefined