Flutter: как отображать плавающийActionButton только после завершения FutureBuilder

Я хотел бы отображать floatActionButton только после того, как мое будущее загрузит данные (ConnectionState.done).

Просто отображается во время ожидания и это не круто. Я бы хотел, чтобы он отображался после будущей обработки (ConnectionState.done).

Кто-нибудь дает чаевые?

Мой код:

 @override
  void initState() {
    _future = getFuture();
    super.initState();
  }

  Future<List<Associated>> getFuture() async {
    return _webClient.findAll();
  }

 //@override
  Widget build(BuildContext context) {
    return Scaffold(
      body: FutureBuilder<List<Associated>>(

        future: _future, 

        builder: (context, snapshot) {
          switch (snapshot.connectionState) {
            case ConnectionState.none:
              break;
            case ConnectionState.waiting:
              return Progress();
              break;
            case ConnectionState.active:
              break;
              case ConnectionState.done:
               if (snapshot.hasData) {
                final List<Associated> associateds = snapshot.data;
                if (associateds.isNotEmpty) {
                  return Container(

                    child: Form(
                      child: SingleChildScrollView(
                        child: associatedWidgets(associateds),
                      ),
                    ),
                  );
                }
              }
              return CenteredMessage(
                'Not found.',
                icon: Icons.warning,
              );
              break;
          }

        },
      ),
      floatingActionButton: Button(
        Icons.save,
        onClick: () {
          _update(context);
        },
      ),
    );
  }

3 ответа

Насколько я понимаю ваш вопрос, я хотел бы на него ответить.
Сделайте это просто вот так.

Также мы не должны звонить setState() внутри FutureBuilder.

Итак, учитывая эту ситуацию, мы можем сделать что-то вроде этого.
Определить переменнуюbool isLoading = true;

@override
  void initState() {
    getFuture().then((value){
        setState(() { 
          _future = value;
          isLoading = false;
        });
    }).catch((e) {
     // Some Error Handling
    });
    super.initState();
  }

и в назначении FloatingActionButton, сделай что-нибудь вроде этого.

  floatingActionButton: isLoading? null : Button(
        Icons.save,
        onClick: () {
          _update(context);
        },
      ),

Но в этом случае вам придется использовать другие виджеты. FutureBuilder, как это.

Scaffold(
   body: isLoading ? Progress(): ListView()
);

Совет: вы можете просто использоватьFloatingActionButton виджет с onPressed вместо того Button

Извините , но я не понял вашу точку зрения, когда вы сказали:

Но в этом случае вы должны использовать другие виджеты FutureBuilder, подобные этому.

Scaffold(
   body: isLoading ? Progress(): ListView()
);

Этот оператор setState(() { isLoading = false; }); вызывает ошибку:

Следующее утверждение было выдано при построении FutureBuilder(dirty, state: _FutureBuilderState# c72c4): setState() или markNeedsBuild(), вызванных во время сборки.

Этот виджет AssociatedUpdate нельзя пометить как нуждающийся в сборке, поскольку структура уже находится в процессе создания виджетов. Виджет может быть отмечен как требующий создания на этапе сборки, только если один из его предков в настоящее время строит. Это исключение разрешено, потому что фреймворк строит родительские виджеты раньше дочерних, что означает, что всегда будет построен грязный потомок. В противном случае платформа может не посещать этот виджет на этапе сборки. Виджет, для которого был вызван setState() или markNeedsBuild(), был: Состояние AssociatedUpdate: _AssociatedUpdateState#2d43d Виджет, который в настоящее время создавался, когда был сделан оскорбительный вызов, был: FutureBuilderгрязное состояние: _FutureBuilderState# c72 соответствующий виджет, вызывающий ошибку, был: FutureBuilder file:///home/adalbertojr/IdeaProjects/hcslzapp/lib/pages/associated/associated.update.dart:84:13 Когда было создано исключение, это был стек: #0 Element.markNeedsBuild. (пакет:flutter/src/widgets/framework.dart:4167:11) #1 Element.markNeedsBuild (пакет:flutter/src/widgets/framework.dart:4182:6) #2 State.setState (пакет:flutter/src/widgets/framework.dart:1253:14) #3 _AssociatedUpdateState.build. (пакет:hcslzapp/pages/ connected/associated.update.dart:102:15) #4 _FutureBuilderState.build (пакет:flutter/src/widgets/async.dart:732:55) ...6) # 2 State.setState (пакет: flutter / src / widgets / framework.dart: 1253: 14) # 3 _AssociatedUpdateState.build. (пакет:hcslzapp/pages/ connected/associated.update.dart:102:15) #4 _FutureBuilderState.build (пакет:flutter/src/widgets/async.dart:732:55) ...6) # 2 State.setState (пакет: flutter / src / widgets / framework.dart: 1253: 14) # 3 _AssociatedUpdateState.build. (пакет:hcslzapp/pages/ connected/associated.update.dart:102:15) #4 _FutureBuilderState.build (пакет:flutter/src/widgets/async.dart:732:55) ...

Другие вопросы по тегам