Это касается обновления значения одного элемента в очереди, но его влияние на остальную часть очереди.
У меня есть Queue
, который содержит некоторые FancyNumber
виджеты, которые добавляются каждый3 секундыВиджет FancyNumber имеет функцию (fancyFunction()
), которая +1 к каждому числу (хотя в реальной жизни, скажем, он делает некоторые полезные вычисления с ним).Как только это вызывается, он уведомляет своего слушателя (класс FancyNumber
).Исходя из того, является ли число нечетным или четным, я поставил другой фон для номера.
Есть две проблемы:
- Если я выполню какую-либо математическую операцию в
fancyFunction()
все мои номера в конечном итоге одинаковы.Если вы запустите приведенный ниже код, вы увидите, что в конечном итоге все элементы в очереди имеют одинаковое значение.Если вы закомментируете number += 1;
, вы увидите, что они увеличиваются индивидуально (как и ожидалось). - Цвет фона не меняется - последний добавленный FancyNumber всегда зеленый, а остальные всегда красные.
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],
);
},
);
}
}