【问题标题】:Flutter - iterate over an asynchrous/future listFlutter - 迭代异步/未来列表
【发布时间】:2020-11-06 00:33:09
【问题描述】:

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

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'.

【问题讨论】:

    标签: flutter asynchronous dart future


    【解决方案1】:

    为什么会导致这个问题?

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

    上面的代码不是一个可以直接渲染列表的简单列表。它返回Future&lt;List&gt;,必须作为后台工作获取。 所以请使用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(),
                           
                        );
                  }
                })
    

    【讨论】:

    • 获取这样的数据 List list = snapshot.data;
    【解决方案2】:

    你需要像这样使用FutureBuilder..

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

    【讨论】:

      【解决方案3】:

      只需使用 FutureBuilder 小部件。

      在下面的例子中,我的异步函数被称为getSportsList(),它返回一个future List of Strings(这可以从SharedPreferences、一个API等获得。只要确保它是一个future )。

      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 告诉我们 future 是否返回一个值,还有一些其他有用的方法,如用于错误处理的 snapshot.connectionState 或 snapshot.hasError。

      如需更多资源,请查看 Flutter 团队的 this video。另请查看the documentation 了解更多信息

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-08-12
        • 1970-01-01
        • 1970-01-01
        • 2014-02-04
        • 1970-01-01
        • 2021-10-22
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多