【问题标题】:Get length of Future var in Flutter在 Flutter 中获取 Future var 的长度
【发布时间】:2019-11-02 12:39:40
【问题描述】:

我正在使用shared_preferences package 来保存我的对象。当我加载我的应用程序时,我会得到我之前创建的团队。如果我没有得到任何东西(第一次),我会创建 2 个默认团队 这就是我所拥有的:

Future<Null> _getTeams() async {
  final prefs = await SharedPreferences.getInstance();
  return prefs.get("teams") ??
      [
        {"name": "Team 2", "avatar": "assets/images/draw1.jpg"},
        {"name": "Team 3", "avatar": "assets/images/draw2.jpg"},
      ];
}

class MyState extends State<TeamsPage> {
  final _listKey = GlobalKey<AnimatedListState>();
  Future<List<Map>> _teams = _getTeams();

当我的小部件需要动态显示这些团队时,问题就出现了。它们还没有准备好成为Future 变量,所以我收到长度和索引错误:

child: AnimatedList(
                key: _listKey,
                initialItemCount: _teams.length,
                itemBuilder:
                    (BuildContext context, int index, Animation animation) {
                  return _buildItem(_teams[index], index, animation);
                },
              ),

index 我得到这个错误:

没有为类“Future>”定义运算符“[]”。尝试 定义运算符'[]'

length:

没有为类“Future>”定义吸气剂“长度”

【问题讨论】:

    标签: flutter flutter-dependencies


    【解决方案1】:

    您必须返回 Future> 或任何类型的团队。 由于此方法是异步的,因此您必须使用 await 来处理其结果。

    Future<List<Team>> _getTeams() async {
      final prefs = await SharedPreferences.getInstance();
      return prefs.get("teams") ??
          [
            {"name": "Team 2", "avatar": "assets/images/draw1.jpg"},
            {"name": "Team 3", "avatar": "assets/images/draw2.jpg"},
          ];
    }
    
    var teams = await _getTeams();
    

    如果您没有为团队定义类型,请使用 List> 将来作为泛型类型。然后,您可以通过以下方式访问其内容:

    var teams = await _getTeams();
    var firstTeamName = teams[0]['name'];
    

    【讨论】:

    • 不确定如何使类异步:class MyState extends State&lt;TeamsPage&gt; { final _listKey = GlobalKey&lt;AnimatedListState&gt;(); var teams = await _getTeams();
    • 不要在字段初始化时获取您的状态。方法 initState() 完全适用于此用例。覆盖它并使其异步。
    • 抱歉这些菜鸟问题(我刚刚跳入 Flutter),但 initState() 不是在创建小部件时触发的方法吗?如果是这样,加载这个之前我的小部件加载不是更好吗?
    • initState 用于状态的初始创建。恕我直言,这是加载存储的首选项或默认初始化状态的正确位置。如果您想提前加载它,您必须创建一个作用域模型来保存您的数据并在数据更改时触发小部件的重新加载。
    • 这么想...我正在阅读这篇文章,显然之前没有加载任何内容:flutterbyexample.com/stateful-widget-lifecycle 但是当我将initState 转换为异步时我也遇到了一个问题:it's must be a void method without an async keyword `` ` class MyState extends State { final _listKey = GlobalKey();列表 _teams = []; initState() async { Future> _getTeams() async { final prefs = await SharedPreferences.getInstance(); ... } _teams = 等待 _getTeams(); } ```
    【解决方案2】:

    以上答案对我不起作用。我从官网发现this doc很有用。
    解决此问题的一种策略是使用FutureBuilder Widget

    所以你会得到这样的东西

    child: FutureBuilder<List<Map>>(
      future: _teams,
      builder: (context, snapshot) {
        if (snapshot.hasData) {
          return AnimatedList(
                key: _listKey,
                initialItemCount: snapshot.data.length,
                itemBuilder:
                    (BuildContext context, int index, Animation animation) {
                  return _buildItem(snapshot.data[index], index, animation);
                },
              );
        } else if (snapshot.hasError) {
          return Text("${snapshot.error}");
        }
    
        // By default, show a loading spinner.
        return CircularProgressIndicator();
      },
    );
    

    您可以将“_team”作为“snapshot.data”传递给需要列表才能工作的子小部件。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-07-01
      • 2022-10-24
      • 2021-10-23
      • 2021-01-17
      • 1970-01-01
      相关资源
      最近更新 更多