Почему мои значения в очереди совпадают во Flutter? - PullRequest
0 голосов
/ 06 марта 2019

Это касается обновления значения одного элемента в очереди, но его влияние на остальную часть очереди.

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