为什么我的队列值在Flutter中最终相同?

时间:2019-03-06 02:07:50

标签: model flutter queue listener

这涉及更新队列中一项的值,但会影响队列的其余部分。

我有一个Queue,其中包含一些FancyNumber小部件,每3秒添加一次。 FancyNumber小部件具有一个对每个数字+1的函数(fancyFunction())(尽管在现实生活中,它可以对它进行一些有用的计算)。调用此方法后,它会通知其侦听器(FancyNumber类)。 根据数字是奇数还是偶数,我为数字设置了不同的背景。

有两个问题:

  1. 如果我在fancyFunction()中进行任何形式的数学运算,我所有的数字都将结束 一样。如果运行以下代码,您将看到 最终,队列中的所有项目都具有相同的值。如果你 注释掉number += 1;,您会看到它们分别增加 (如预期)。
  2. 背景颜色不变-最近添加的 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],
        );
      },
    );
  }
}

0 个答案:

没有答案