这涉及更新队列中一项的值,但会影响队列的其余部分。
我有一个Queue
,其中包含一些FancyNumber
小部件,每3秒添加一次。
FancyNumber小部件具有一个对每个数字+1的函数(fancyFunction()
)(尽管在现实生活中,它可以对它进行一些有用的计算)。调用此方法后,它会通知其侦听器(FancyNumber
类)。
根据数字是奇数还是偶数,我为数字设置了不同的背景。
有两个问题:
fancyFunction()
中进行任何形式的数学运算,我所有的数字都将结束
一样。如果运行以下代码,您将看到
最终,队列中的所有项目都具有相同的值。如果你
注释掉number += 1;
,您会看到它们分别增加
(如预期)。import 'dart:async';
import 'dart:collection';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
home: Scaffold(body: NumberPrinter()),
);
}
}
class FancyNumber extends StatefulWidget {
final numberModel;
const FancyNumber({this.numberModel});
@override
_FancyNumberState createState() => _FancyNumberState();
}
class _FancyNumberState extends State<FancyNumber> {
Color color;
@override
void initState() {
super.initState();
widget.numberModel.addListener(() {
print('notified listeners called');
if (widget.numberModel.number % 2 == 0) {
color = Colors.red;
} else {
color = Colors.green;
}
});
}
@override
Widget build(BuildContext context) {
print(widget.numberModel.number);
return Container(
color: color,
child: Text(
widget.numberModel.number.toString(),
style: TextStyle(fontSize: 40.0),
),
);
}
}
class FancyNumberModel extends ChangeNotifier {
int number = 0;
FancyNumberModel({this.number});
void fancyFunction() {
number += 1;
notifyListeners();
}
}
class NumberPrinter extends StatefulWidget {
NumberPrinter();
@override
_NumberPrinterState createState() => _NumberPrinterState();
}
class _NumberPrinterState extends State<NumberPrinter> {
int _counter = 3; // we already add the first two values
final queue = ValueNotifier<Queue<FancyNumber>>(Queue<FancyNumber>());
Timer _timer;
@override
void initState() {
super.initState();
queue.value
..addFirst(FancyNumber(numberModel: FancyNumberModel(number: 1)))
..addFirst(FancyNumber(numberModel: FancyNumberModel(number: 2)));
_updateQueue();
}
void _updateQueue() {
_timer = Timer.periodic(Duration(seconds: 2), (timer) {
// Set upcoming digit.
queue.value.addFirst(
FancyNumber(
numberModel: FancyNumberModel(number: _counter),
),
);
setState(() {
_counter += 1;
});
for (FancyNumber item in queue.value) {
item.numberModel.fancyFunction();
}
if (queue.value.length == 4) {
queue.value.removeLast();
}
});
}
@override
void dispose() {
_timer?.cancel();
queue.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return AnimatedBuilder(
animation: queue,
builder: (BuildContext context, Widget child) {
final stack = Center(
child: Stack(
children: queue.value.toList(),
),
);
final column = Column(
mainAxisAlignment: MainAxisAlignment.center,
children: queue.value.toList(),
);
return Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [stack, column],
);
},
);
}
}