颤抖如何在初始化状态下使用未来的异步方法

时间:2020-06-29 13:42:00

标签: list firebase flutter future

当屏幕加载时,我希望初始化状态使用通过有状态窗口小部件传递的Future 填充列表。但是,从将来开始,我的方法将崩溃并且不起作用。

我的代码

  @override
  void initState() async {
    FutureBuilder(
      future: widget.imageList,
      builder: (context, snapshot) {
        switch (snapshot.connectionState) {
          case ConnectionState.none:
            print('NONE');
            break;
          case ConnectionState.active:
          case ConnectionState.waiting:
            print("WAITING");
            break;
          case ConnectionState.done:
            print("DONE");
            setState(() {
              imgList = widget.imageList as List<String>;
            });
            break;
        }
      },
    );
    super.initState();
  }

产生错误


════════ Exception caught by widgets library ═══════════════════════════════════
_BottomSheetWidgetState.initState() returned a Future.
The relevant error-causing widget was
    MaterialApp 

状态小部件,列表通过该小部件

List<String> imgList = List<String>();

class BottomSheetWidget extends StatefulWidget {
  BottomSheetWidget({Key key, this.name, this.imageList}) : super(key: key);

  String name;
  Future<List<String>> imageList;

整个编辑的代码:

List<String> imgList = List<String>();

class BottomSheetWidget extends StatefulWidget {
  BottomSheetWidget({Key key, this.name, this.imageList}) : super(key: key);

  String name;
  Future<List<String>> imageList;

  @override
  _BottomSheetWidgetState createState() => _BottomSheetWidgetState();
}

class _BottomSheetWidgetState extends State<BottomSheetWidget> {
  int _current = 0;

  final List<Widget> imageSliders = imgList
      .map((item) => Container(
            child: Container(
              margin: EdgeInsets.all(5.0),
              child: ClipRRect(
                  borderRadius: BorderRadius.all(Radius.circular(5.0)),
                  child: Stack(
                    children: <Widget>[
                      Image.network(item,
                          fit: BoxFit.cover, height: 1000.0, width: 1000.0),
                      Positioned(
                        bottom: 0.0,
                        left: 0.0,
                        right: 0.0,
                        child: Container(
                          decoration: BoxDecoration(
                            gradient: LinearGradient(
                              colors: [
                                Color.fromARGB(200, 0, 0, 0),
                                Color.fromARGB(0, 0, 0, 0)
                              ],
                              begin: Alignment.bottomCenter,
                              end: Alignment.topCenter,
                            ),
                          ),
                        ),
                      ),
                    ],
                  )),
            ),
          ))
      .toList();

  @override
  Widget build(BuildContext context) {
    return FutureBuilder(
      future: widget.imageList,
      builder: (context, snapshot) {
        switch (snapshot.connectionState) {
          case ConnectionState.none:
            print('NONE');
            break;
          case ConnectionState.active:
          case ConnectionState.waiting:
            print("WAITING");
            break;
          case ConnectionState.done:
            print("DONNE");
            setState(() async {
                imgList = snapshot.data as List<String>;

            });

            return Container(
              decoration: BoxDecoration(
                color: Colors.red,
                borderRadius: BorderRadius.circular(25),
              ),
              height: MediaQuery.of(context).size.height * 0.85,
              width: MediaQuery.of(context).size.width,
              child: Column(
                mainAxisAlignment: MainAxisAlignment.center,
                mainAxisSize: MainAxisSize.max,
                children: <Widget>[
                  Padding(
                    padding: EdgeInsets.symmetric(horizontal: 15),
                    child: Column(
                      crossAxisAlignment: CrossAxisAlignment.start,
                      mainAxisAlignment: MainAxisAlignment.end,
                      children: <Widget>[
                        CarouselSlider(
                          items: imageSliders,
                          options: CarouselOptions(
                              enlargeCenterPage: true,
                              enlargeStrategy: CenterPageEnlargeStrategy.height,
                              height: MediaQuery.of(context).size.height - 500,
                              aspectRatio: 2.0,
                              onPageChanged: (index, reason) {
                                setState(() {
                                  _current = index;
                                });
                              }),
                        ),
                        Row(
                          mainAxisAlignment: MainAxisAlignment.center,
                          children: imgList.map((url) {
                            int index = imgList.indexOf(url);
                            return Container(
                              width: 8.0,
                              height: 8.0,
                              margin: EdgeInsets.symmetric(
                                  vertical: 10.0, horizontal: 2.0),
                              decoration: BoxDecoration(
                                shape: BoxShape.circle,
                                color: _current == index
                                    ? Color.fromRGBO(0, 0, 0, 0.9)
                                    : Color.fromRGBO(0, 0, 0, 0.4),
                              ),
                            );
                          }).toList(),
                        ),
                        Text(widget.name,
                            style: TextStyle(
                                fontSize: 30,
                                color: Colors.white,
                                fontWeight: FontWeight.bold)),
                        Text("United Kingdom",
                            style: TextStyle(
                              fontSize: 18,
                              color: Colors.white,
                            )),
                      ],
                    ),
                  )
                ],
              ),
            );
            break;
        }
      },
    );
  }
}

控制台出现新错误:

flutter: WAITING

════════ Exception caught by widgets library ═══════════════════════════════════
A build function returned null.
The relevant error-causing widget was
    FutureBuilder<List<String>> 
lib/common_widget/bottom_sheet.dart:54
════════════════════════════════════════════════════════════════════════════════
flutter: DONNE

════════ Exception caught by widgets library ═══════════════════════════════════
setState() callback argument returned a Future.
The relevant error-causing widget was
    FutureBuilder<List<String>> 
lib/common_widget/bottom_sheet.dart:54
════════════════════════════════════════════════════════════════════════════════

1 个答案:

答案 0 :(得分:1)

initState方法在设计上是同步的。您可以在覆盖的FutureBuilder方法中返回initState小部件,而不是在FutureBuilder方法中创建build小部件。随时查看FutureBuilder小部件here的文档,以获取有关其工作方式的示例。

似乎setState回调函数中的代码也有问题。您可能想将imgList = widget.imageList as List<String>;替换为imgList = snapshot.data as List<String>;,以便使用已完成的将来的数据。

在所有情况下,build方法似乎都没有返回窗口小部件也存在问题。我已经获取了更新的代码示例,并进行了如下修改:

import 'package:flutter/material.dart';

class BottomSheetWidget extends StatefulWidget {
  BottomSheetWidget({Key key, this.name, this.imageList}) : super(key: key);

  final String name;

  final Future<List<String>> imageList;

  @override
  _BottomSheetWidgetState createState() => _BottomSheetWidgetState();
}

class _BottomSheetWidgetState extends State<BottomSheetWidget> {
  int _current = 0;

  @override
  Widget build(BuildContext context) {
    return FutureBuilder<List<String>>(
      future: widget.imageList,
      builder: (context, snapshot) {
        if (snapshot.connectionState == ConnectionState.done) {
          final imgList = snapshot.data;

          return Container(
            decoration: BoxDecoration(
              color: Colors.red,
              borderRadius: BorderRadius.circular(25),
            ),
            height: MediaQuery.of(context).size.height * 0.85,
            width: MediaQuery.of(context).size.width,
            child: Column(
              mainAxisAlignment: MainAxisAlignment.center,
              mainAxisSize: MainAxisSize.max,
              children: <Widget>[
                Padding(
                  padding: EdgeInsets.symmetric(horizontal: 15),
                  child: Column(
                    crossAxisAlignment: CrossAxisAlignment.start,
                    mainAxisAlignment: MainAxisAlignment.end,
                    children: <Widget>[
                      CarouselSlider(
                        items: imgList.map(
                          (item) {
                            return Container(
                              child: Container(
                                margin: EdgeInsets.all(5.0),
                                child: ClipRRect(
                                  borderRadius:
                                      BorderRadius.all(Radius.circular(5.0)),
                                  child: Stack(
                                    children: <Widget>[
                                      Image.network(
                                        item,
                                        fit: BoxFit.cover,
                                        height: 1000.0,
                                        width: 1000.0,
                                      ),
                                      Positioned(
                                        bottom: 0.0,
                                        left: 0.0,
                                        right: 0.0,
                                        child: Container(
                                          decoration: BoxDecoration(
                                            gradient: LinearGradient(
                                              colors: [
                                                Color.fromARGB(200, 0, 0, 0),
                                                Color.fromARGB(0, 0, 0, 0)
                                              ],
                                              begin: Alignment.bottomCenter,
                                              end: Alignment.topCenter,
                                            ),
                                          ),
                                        ),
                                      ),
                                    ],
                                  ),
                                ),
                              ),
                            );
                          },
                        ).toList(),
                        options: CarouselOptions(
                          enlargeCenterPage: true,
                          enlargeStrategy: CenterPageEnlargeStrategy.height,
                          height: MediaQuery.of(context).size.height - 500,
                          aspectRatio: 2.0,
                          onPageChanged: (index, reason) {
                            setState(() {
                              _current = index;
                            });
                          },
                        ),
                      ),
                      Row(
                        mainAxisAlignment: MainAxisAlignment.center,
                        children: imgList.map((url) {
                          return Container(
                            width: 8.0,
                            height: 8.0,
                            margin: EdgeInsets.symmetric(
                                vertical: 10.0, horizontal: 2.0),
                            decoration: BoxDecoration(
                              shape: BoxShape.circle,
                              color: _current == imgList.indexOf(url)
                                  ? Color.fromRGBO(0, 0, 0, 0.9)
                                  : Color.fromRGBO(0, 0, 0, 0.4),
                            ),
                          );
                        }).toList(),
                      ),
                      Text(
                        widget.name,
                        style: TextStyle(
                          fontSize: 30,
                          color: Colors.white,
                          fontWeight: FontWeight.bold,
                        ),
                      ),
                      Text(
                        "United Kingdom",
                        style: TextStyle(
                          fontSize: 18,
                          color: Colors.white,
                        ),
                      ),
                    ],
                  ),
                )
              ],
            ),
          );
        } else {
          return CircularProgressIndicator();
        }
      },
    );
  }
}