Flutter - 遍历 asynchrous/future 列表

Flutter - iterate over an asynchrous/future list

我正在尝试创建一个列表,其中包含通过 SharedPreferences 获得的值。但是,如果我想使用 SharedPreference,我必须使用异步方法/未来类型,但我不知道如何使用它们。我尝试遍历 sports 列表,但它是 asynchronous/future。那么我该如何迭代它(使用地图)?

class _MyHomePageState extends State<MyHomePage> {

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        Center(
          child: Align(
            alignment: Alignment.bottomCenter,
            child: CarouselSlider(
              options: CarouselOptions(
                height: 565,
                aspectRatio: 16/9,
                enlargeCenterPage: true,
                viewportFraction: .8,
              ),
              items: sportsList.map((i) {
                return Builder(builder: (BuildContext context) {
                  return Container(
                    .......
                    .........
                    .......
}


  static Future<bool> initSharedPreference(String key) async {
    final SharedPreferences prefs = await SharedPreferences.getInstance();
    
    return prefs.getBool(key) ?? false;
  }


  Future<List> sportsList() async {
    List sports=[
      await initSharedPreference("test")), 
        ....,
        ....,
        ....
    ];
  }

此代码无效,原因如下:

The method 'map' isn't defined for the type 'Future'.

只需使用 FutureBuilder 小部件。

在下面的示例中,我的异步函数称为 getSportsList(),其中 returns 一个 未来的字符串列表 (这可以从 SharedPreferences 中获取,一个API,等等。只要确保它是一个未来)。

class FutureList extends StatelessWidget {
  @override
  Widget build(BuildContext context) {

    // THE FUTURE WIDGET

    return FutureBuilder<List<String>>(
      future: getSportsList(), // Add your asynchronous function here
      builder: (context, AsyncSnapshot<List<String>> snapshot){

        List<String> sports = snapshot.data;
        // If there is no data in the snapshot, it is probably loading.
        if(!snapshot.hasData) return CircularProgressIndicator(); 
        // Now add the widget you want to return
        else return CarouselSlider(
          options: CarouselOptions(
            height: 565,
            aspectRatio: 16/9,
            enlargeCenterPage: true,
            viewportFraction: .8,
          ),
          items: sportsList.map((String item) {
            return Builder(builder: (BuildContext context) {
              return Container(
                .......
                .........
                .......
      },
    );
  }
}

快照基本上提供了有关未来的信息。 snapshot.data是从未来得到的结果。 snapshot.hasData 告诉我们未来是否返回值,还有一些其他有用的方法,如 snapshot.connectionState 或 snapshot.hasError 用于错误处理。

如需更多资源,请查看 this video by the flutter team. Also check out the documentation 以了解更多信息

你需要像这样使用FutureBuilder..

FutureBuilder(
            future: sportsList(),
            builder: (context, snapshot) {
              if (!snapshot.hasData) {
                return CircularProgressIndicator();
              } else {
                return CarouselSlider(
                       items: snapshot.data.map(.....).toList(),
                       //other code
                    );
              }
            })

为什么会出现这个问题?

Future<List> sportsList() async {
    List sports=[
      await initSharedPreference("test")), 
        ....,
        ....,
        ....
    ];
  }

上面的代码不是一个简单的列表,这里可以直接渲染列表。它返回 Future<List> 必须作为后台工作获取。 所以使用FutureBuilder

FutureBuilder 是一次性调用,在其生命周期内将 运行 仅调用一次。所以你可以放心。

FutureBuilder(
            future: sportsList(),
            builder: (context, snapshot) {
              if (!snapshot.hasData) {
                return CircularProgressIndicator();
              } else {
                List<Widget> list = snapshot.data;
                return CarouselSlider(
                     options: CarouselOptions(
                     height: 565,
                     aspectRatio: 16/9,
                     enlargeCenterPage: true,
                     viewportFraction: .8,
                    ),
                      items: list.map(.....).toList(),
                       
                    );
              }
            })