如何修复FutureBuilder多次打开错误?

时间:2019-04-18 01:52:38

标签: dart flutter flutter-layout

这是我的两堂课(两页)。这两个类多次开放。 我将调试点放在futurebuilder中的两个类中。 调试点正在运行,

  1. MainCategory页面并转到下一页
  2. SubCategory页面并再次运行MainCategory页面(上一页)futurebuilder,并再次运行MainCategory页面futurefutureer
  3. 将子类别页面导航到运行子类别页面和主类别页面的第三页

我将我的两个类上传到GitHub,请让我知道问题所在。

MainCategory代码:https://github.com/bhanuka96/ios_login/blob/master/MainCategory.dart 子类别代码:https://github.com/bhanuka96/ios_login/blob/master/subCategory.dart

3 个答案:

答案 0 :(得分:0)

如文档中所述,您不应在小部件的构建事件期间获取Futurebuilder的Future。

https://docs.flutter.io/flutter/widgets/FutureBuilder-class.html

  

将来一定要早一些,例如中   State.initState,State.didUpdateConfig或   State.didChangeDependencies。不得在   构造状态时调用State.build或StatelessWidget.build方法   FutureBuilder。如果未来与   FutureBuilder,那么每次重新构建FutureBuilder的父项时,   异步任务将重新启动。

因此,尝试将对getRegister方法的调用移至build方法之外,并将其替换为返回的Future值。

答案 1 :(得分:0)

如果您碰巧使用了Provider,根据我的问题,这是一个更清晰的选择:

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return FutureProvider<List<String>>(
      create: (_) => MyApiHelper.getMyList(),
      child: Consumer<List<String>>(
        builder: (_, list, __) {
          if (list == null) return CircularProgressIndicator();
          return ListView.builder(
            itemCount: list.length,
            itemBuilder: (_, index) {
              //show your list item row here...
            },
          );
        };
      ),
    );
  }
}

这当然也可以通过其他答案建议的StatefulWidget来实现,或者甚至可以按照Why is my Future/Async Called Multiple Times?中的说明flutter_hooks来实现

答案 2 :(得分:0)

您可以创建新的Widget并将Function传递给 returnFuture

() {
 return YourFuture;
} 
import 'dart:developer';
import 'package:flutter/material.dart';

class MyFutureBuilder<T> extends StatefulWidget {
  final Future<T> Function() returnFuture;
  final AsyncWidgetBuilder<T> builder;
  final T initialData;
  MyFutureBuilder({
    this.returnFuture,
    @required this.builder,
    this.initialData,
    Key key,
  }) : super(key: key);

  @override
  _MyFutureBuilderState<T> createState() => _MyFutureBuilderState<T>();
}

class _MyFutureBuilderState<T> extends State<MyFutureBuilder<T>> {
  bool isLoading = false;
  Future<T> future;

  @override
  void initState() {
    super.initState();
    future = widget.returnFuture();
  }

  @override
  Widget build(BuildContext context) {
    return FutureBuilder(
      builder: widget.builder,
      initialData: widget.initialData,
      future: future,
    );
  }
}

示例

MyFutureBuilder<List<User>>(
                                  returnFuture: () {
                                    return moderatorUserProvider
                                        .getExecutorsAsModeratorByIds(val.users,
                                            save: true);
                                  },
                                  builder: (cont, asyncData) {

                                    if (asyncData.connectionState !=
                                        ConnectionState.done) {
                                      return Center(
                                        child: MyCircularProgressIndicator(
                                          color: ModeratorColor.executors.color,
                                        ),
                                      );
                                    }
                                    return Column(
                                        children: asyncData.data
                                            .map(
                                              (singlExecutor) =>
                                                  ChooseInfoButton(
                                                title:
                                                    '${singlExecutor.firstName} ${singlExecutor.secondName}',
                                                subTitle: 'Business analyst',
                                                middleText: '4.000 NOK',
                                                subMiddleText: 'full time',
                                                label: 'test period',
                                                subLabel: '1.5 month',
                                                imageUrl:
                                                    assetsUrl + 'download.jpeg',
                                                onTap: () {
                                                  Navigator.of(context).push(
                                                    MaterialPageRoute(
                                                      builder: (_) =>
                                                          ModeratorExecutorEditPage(),
                                                    ),
                                                  );
                                                },
                                              ),
                                            )
                                            .toList());
                                  },
                                )
    ```