Обновление виджета при изменении глобальной переменной (Asyn c) во Flutter - PullRequest
1 голос
/ 25 мая 2020

Я новичок во Flutter и оказываюсь в яме, которую выкопал.

То, что я хочу выполнить sh, довольно просто. У меня есть глобальная переменная. Допустим, var PlayerPointsToAdd. Затем у меня есть этот виджет с отслеживанием состояния, который должен обновляться каждый раз, когда эта глобальная переменная не равна нулю. Я хочу иметь возможность вызывать addPointsToPlayer() из другого виджета.

Пока мое понимание виджетов с отслеживанием состояния заканчивается на setState((){}), который я могу вызывать только внутри самого виджета с отслеживанием состояния.

Код ниже находится внутри контейнера внутри виджета с отслеживанием состояния. Каждый раз, когда эта кнопка нажимается, он вызывает setState в соответствии с новым списком, возвращаемым PlayerScoreBoard.add().

...
child: RaisedButton(
                        onPressed: () {
                          setState(() {
                            if (PointsToAddPlayer != 0) {
                              for (int i = 0; i < PointsToAddPlayer; i++) {
                                PlayerScoreBoard.add(new Icon(
                                    Icons.check_circle_outline,
                                    size: 11));
                              }
                              PointsToAddPlayer = 0;
                            }

Я читал документацию и смотрел видео Flutter на YouTube, поэтому, пожалуйста, не отклоняйте вопрос. Мне действительно трудно это понять.

Я полагаю, мне нужно использовать Streams для этого. Они кажутся немного сложными, но если это единственный способ, я буду их использовать. Означает ли это, что я должен создать глобальную переменную, предпочтительно класс с переменными в нем, и заставить его передавать переменные всем другим виджетам, которые должны обновляться при обновлении переменных. Таким образом, этот виджет ScoreBoard должен прослушивать поток, исходящий от глобального класса, и обновлять себя. Позволит ли это мне изменять переменные в глобальном классе и автоматически обновлять соответствующие виджеты до их новых состояний? И означает ли это, что каждый виджет, который полагается на внешние переменные, должен прослушивать потоки? Я был бы очень признателен за ELI5 для взаимосвязи между виджетами с отслеживанием состояния и потоками.

И поскольку эти глобальные данные будут обновляться много раз снова и снова, использование Future невозможно.

Большое спасибо.

Я ошибочно сказал глобальный переменная класса. Я хотел сказать что-то вроде карты, где у меня может быть что-то вроде gameData.PlayerPoints или gameData.turn.

1 Ответ

2 голосов
/ 25 мая 2020

Вы можете попробовать ValueListenableBuilder .

import 'package:flutter/material.dart';

final playerPointsToAdd =
    ValueNotifier<int>(0); //TODO 1st: ValueNotifier declaration

void main() => runApp(TestApp());

class TestApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) => MaterialApp(
        routes: {
          '/': (context) => HomePage(),
        },
      );
}

//TODO you can use StatelessWidget either
class HomePage extends StatefulWidget {
  @override
  _HomePageState createState() => _HomePageState();
}

class _HomePageState extends State<HomePage> {
  @override
  Widget build(BuildContext context) => Scaffold(
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              RaisedButton(
                // TODO 3rd: change the value
                onPressed: () => playerPointsToAdd.value++,
                child: Text('Increase'),
              ),
              ValueListenableBuilder(
                //TODO 2nd: listen playerPointsToAdd
                valueListenable: playerPointsToAdd,
                builder: (context, value, widget) {
                  //TODO here you can setState or whatever you need
                  return Text(
                      //TODO e.g.: create condition with playerPointsToAdd's value
                      value == 0
                          ? 'playerPointsToAdd equals 0 right now'
                          : value.toString());
                },
              ),
              RaisedButton(
                onPressed: () => playerPointsToAdd.value--,
                child: Text('Decrease'),
              ),
            ],
          ),
        ),
      );
}


...