Flutter: FlatButton не меняет ребенка на onPressed - PullRequest
0 голосов
/ 18 апреля 2020

Я хотел изменить значение в firestore кнопкой onPressed. Я знаю, что может быть задержка в секундах, и я хотел показать CircularProgressIndicator виджет во время ожидания. Но это не работает.

Вот мой виджет:

Widget save(String id) {
    return new FutureBuilder(
      future: PostController().isAlreadySaved(id),
      builder: (BuildContext context, AsyncSnapshot<bool> snapshot) {
        if (snapshot.hasData) {
          if (snapshot.data) {
            return FlatButton(
              onPressed: () {
                setState(() {
                  isSaveLoading = true;
                });

                PostController().deleteSaved(id);

                setState(() {
                  isSaveLoading = false;
                });
              },
              child: !isSaveLoading
                  ? Icon(
                      MyFlutterApp.star,
                      size: 30,
                      color: Colors.redAccent,
                    )
                  : SizedBox(
                      height: 15,
                      width: 15,
                      child: CircularProgressIndicator(
                        strokeWidth: 1,
                      ),
                    ),
            );
          } else {
            return FlatButton(
              onPressed: () {
                setState(() {
                  isSaveLoading = true;
                });

                PostController().save(context, id);

                setState(() {
                  isSaveLoading = false;
                });
              },
              child: !isSaveLoading
                  ? Icon(
                      MyFlutterApp.star,
                      size: 30,
                      color: Colors.grey,
                    )
                  : SizedBox(
                      height: 15,
                      width: 15,
                      child: CircularProgressIndicator(
                        strokeWidth: 1,
                      ),
                    ),
            );
          }
        } else {
          return Container(
            //color: Colors.white,
            width: Adapt.screenW(),

            child: Column(
              mainAxisSize: MainAxisSize.min,
              children: <Widget>[
                Flexible(
                  child: Shimmer.fromColors(
                    baseColor: Colors.grey[400],
                    highlightColor: Colors.grey[50],
                    enabled: true,
                    child: Row(
                      children: <Widget>[
                        Padding(
                          padding: const EdgeInsets.fromLTRB(5, 0, 0, 0),
                          child: new Icon(
                            MyFlutterApp.star,
                            size: 30,
                            color: Colors.white,
                          ),
                        ),
                      ],
                    ),
                  ),
                ),
              ],
            ),
          );
        }
      },
    );
  }

Вот моя isAlreadySaved() функция:

Future<bool> isAlreadySaved(String id) async {
    bool isSaved = false;

    QuerySnapshot snapshot =
        await databaseReference.collection('saved').getDocuments();

    snapshot.documents.forEach((a) async {
      if (a.data['postID'] == id&&
          a.data['saver'] == globals.currentUser.uid) {
        isSaved = true;
      }
    });
    return isSaved;
  }

Функция удаления фактически удаляет документ из моей сохраненной коллекции в firestore, а функция сохранения создает документ и сохраняет.

Заранее спасибо!

1 Ответ

0 голосов
/ 18 апреля 2020

Я думаю, что проблема в том, что вы слишком быстро обновляете дерево виджетов или поток пользовательского интерфейса блокируется, ожидая завершения задания PostController до sh ...

В этих строках:

onPressed: () {
 setState(() {
   isSaveLoading = true;
 });

 PostController().deleteSaved(id);

 setState(() {
   isSaveLoading = false;
 });
},

Здесь я вижу, что вы хотите обновить состояние кнопки loading . Но проблема в том, что когда вы устанавливаете isSaveLoading в true, вы не ждете, пока PostController().deleteSaved(id) в fini sh, прежде чем сбросить isSaveLoading в false.

С другой стороны, если PostController().deleteSaved() выполняет долгую работу, поскольку он не асинхронный c, он может на время заблокировать поток пользовательского интерфейса, поэтому вы никогда не увидите круговой индикатор выполнения.

Вы можете сделать onPressed обратный вызов asyn c и ожидание задания PostController.

onPressed: () async {
 setState(() {
   isSaveLoading = true;
 });

 // The deleteSaved function have to be async too
 await PostController().deleteSaved(id);

 setState(() {
   isSaveLoading = false;
 });
},

Надеюсь, это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...