在下面的代码中,我尝试在画布上模拟小部件。
当触摸小部件/按钮时,它会在两种颜色之间翻转。
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;
}
Run Code Online (Sandbox Code Playgroud)
我认为我需要class DiagramPainter extends ChangeNotifier implements CustomPainter而不是class DiagramPainter extends CustomPainter。
我还认为我需要通过 触发重绘notifyListeners()。在这种情况下,谁会收到通知?仍然如此DiagramPainter,不是吗?我缺少什么?
您可以在第 1 步下面复制粘贴运行完整代码:DiagramPainter({Listenable repaint}) : super(repaint: repaint)
第 2 步:传递ValueNotifier<int>(0);到DiagramPainter(repaint: _counter)
第 4 步:onTapUp调用中_counter.value++;
代码片段
class _DiagramState extends State<Diagram> {
final _counter = ValueNotifier<int>(0);
@override
Widget build(BuildContext context) {
...
child: GestureDetector(
onTapUp: (TapUpDetails details) {
_counter.value++;
},
child: ...
child: CustomPaint(
painter: DiagramPainter(repaint: _counter),
),
),
),
),
),
);
}
}
class DiagramPainter extends CustomPainter {
DiagramPainter({Listenable repaint}) : super(repaint: repaint) {
Run Code Online (Sandbox Code Playgroud)
工作演示
完整代码
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> {
final _counter = ValueNotifier<int>(0);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Canvas Widgets'),
centerTitle: true,
),
body: Center(
child: GestureDetector(
onTapUp: (TapUpDetails details) {
_counter.value++;
/*setState(() {
;
});*/
},
child: AspectRatio(
aspectRatio: 1.0,
child: Container(
child: CustomPaint(
painter: DiagramPainter(repaint: _counter),
),
),
),
),
),
);
}
}
class DiagramPainter extends CustomPainter {
// class DiagramPainter extends ChangeNotifier implements CustomPainter {
DiagramPainter({Listenable repaint}) : super(repaint: repaint) {
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;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3298 次 |
| 最近记录: |