【问题标题】:How to use a variable value outside a Future function in Flutter?如何在 Flutter 中的 Future 函数之外使用变量值?
【发布时间】:2021-12-26 19:27:33
【问题描述】:

我想访问items 以在小部件内部使用以生成项目列表。我该怎么做?我是新来的。这是将生成列表的小部件的完整代码。这是我从昨天开始就无法弄清楚的问题。我希望得到启发。

class Breakfast extends StatefulWidget {
      Breakfast({
    Key? key,
  }) : super(key: key);


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

class _BreakfastState extends State<Breakfast> {

  Future<String> _loadloadBreakfastAsset() async {
    return await rootBundle.loadString('assets/breakfast.json');
  }

  Future<List<Breakfast>> loadBreakfast() async{
    String jsonAddress = await _loadloadBreakfastAsset();
    Map<String,dynamic> map = json.decode(jsonAddress);
    List<dynamic> items = map["items"];
    // This return value is thrown away, but this line is necessary to 
    // resolve the Future call that FutureBuilder is waiting on.
    return Future<List<Breakfast>>.value();
  }

  @override
Widget build(BuildContext context) {


      return FutureBuilder(
      future: loadBreakfast(),
      builder: (BuildContext, AsyncSnapshot<dynamic>snapshot){
        return Column(
          children: [
            Padding(
              padding:
                  EdgeInsets.symmetric(horizontal: getProportionateScreenWidth(20)),
              child: SectionTitle(title: "Choices", press: () {}),
            ),
            SizedBox(height: getProportionateScreenWidth(20)),
            SingleChildScrollView(
              scrollDirection: Axis.horizontal,
              child: Row(
                children: [
                  ...List.generate(
                          
                    snapshot.data![index].length,
                    (index) {
                      if (items[index].isPopular) {
                        return BreakfastCard(breakfast: items[index]); 
                      }
                      return const SizedBox
                          .shrink(); // here by default width and height is 0
                    },
                  ),
                  SizedBox(width: getProportionateScreenWidth(20)),
                ],
              ),
            )
          ],
        );
      });
  }
}

这是 JSON 数据 ....

{
    "items": [{

            "id": 1,
            "rating": "4.7",
            "images": [
                "assets/images/egg.png"
            ],
            "title": "Fried Egg",
            "description": "Sunny",
            "isFavorite": false,
            "isPopular": true,
            "serving": 1

        }, {

            "id": 2,
            "rating": "4.0",
            "images": [
                "assets/images/longanisa.png"
            ],
            "title": "Longanisa",
            "description": "Yum",
            "isFavorite": false,
            "isPopular": false,
            "serving": 3

        }

    ]
}

【问题讨论】:

  • 您是否将其用作FutureBuilder 的未来?然后不是返回Future&lt;Breakfast&gt;.value();,而是返回items
  • 当我尝试退货时,错误是这样的:A value of type 'List&lt;dynamic&gt;' can't be returned from the method 'loadBreakfast' because it has a return type of 'Future&lt;Breakfast&gt;'.
  • 可以加入Breakfast模型吗?

标签: flutter dart jsonparser flutter-futurebuilder


【解决方案1】:

您需要一个 FutureBuilder 来获取值并构建一个包含数据的列表,只需对您的 Future 函数进行一些更改

Future<List> loadBreakfast() async {
    String jsonAddress = await _loadloadBreakfastAsset();
    Map<String, dynamic> map = json.decode(jsonAddress);
    List<dynamic> items = map["items"]; 
   
    return items;
  }

并立即使用 FutureBuilder

FutureBuilder(
        future: loadBreakfast(),
        builder: (context, AsyncSnapshot<List> snapshot) => ListView.builder(
            itemCount: snapshot.data!.length,
            itemBuilder: (context, index) => Text("${snapshot.data![index]}")));

【讨论】:

    【解决方案2】:

    尝试删除三个点 ...List.generate(),这样你就可以保留 List.generate()

    【讨论】:

    • 谢谢.. 我试过这个,但似乎我不能让它工作。我已经编辑了我的问题。有空可以看看。
    【解决方案3】:

    您正在使用Future&lt;Breakfast&gt;,它返回 List&lt;Breakfast&gt;

    将方法返回类型List&lt;Breakfast&gt; items改为

    Future&lt;List&lt;Breakfast&gt;&gt; loadBreakfast() async{..}.


    如果检查 JSON 文件,它包含单个键 items,其值为 List&lt;Breakfast&gt;

    了解更多关于ackground-parsing

    为了简化 JSON 过程,创建一个包含解析器的模型类。

    
    class Breakfast {
      int id;
      String rating;
      List<String> images;
      String title;
      String description;
    
      bool isFavorite;
      bool isPopular;
      int serving;
    
      Breakfast({
        required this.id,
        required this.rating,
        required this.images,
        required this.title,
        required this.description,
        required this.isFavorite,
        required this.isPopular,
        required this.serving,
      });
    
      Map<String, dynamic> toMap() {
        return {
          'id': id,
          'rating': rating,
          'images': images,
          'title': title,
          'description': description,
          'isFavorite': isFavorite,
          'isPopular': isPopular,
          'serving': serving,
        };
      }
    
      factory Breakfast.fromMap(Map<String, dynamic> map) {
        return Breakfast(
          id: map['id'],
          rating: map['rating'],
          images: List<String>.from(map['images']),
          title: map['title'],
          description: map['description'],
          isFavorite: map['isFavorite'],
          isPopular: map['isPopular'],
          serving: map['serving'],
        );
      }
    
      String toJson() => json.encode(toMap());
    
      factory Breakfast.fromJson(String source) =>
          Breakfast.fromMap(json.decode(source));
    }
    
    

    您可以检查my short note 格式化不同类型的 JSON。

    import 'dart:convert';
    
    import 'package:flutter/material.dart';
    import 'package:flutter/services.dart';
    import 'package:flutter/widgets.dart';
    
    
    void main() {
      runApp(
        App(),
      );
    }
    class App extends StatelessWidget {
      const App({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return const MaterialApp(
          debugShowCheckedModeBanner: false,
          home: BreakfastView(),
        );
      }
    }
    
    class BreakfastView extends StatefulWidget {
      const BreakfastView({Key? key}) : super(key: key);
    
      @override
      State<BreakfastView> createState() => _BreakfastViewState();
    }
    
    class _BreakfastViewState extends State<BreakfastView> {
      Future<List<Breakfast>> loadBreakfast() async {
        String jsonAddress =
            await rootBundle.loadString('assets/json/breakfast.json');
        final jsonString = json.decode(jsonAddress)['items'] as List;
    
        final List<Breakfast> items =
            jsonString.map((s) => Breakfast.fromMap(s)).toList();
    
        return items;
      }
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: FutureBuilder<List<Breakfast>>(
              future: loadBreakfast(),
              builder: (context, snapshot) {
                if (snapshot.connectionState == ConnectionState.waiting) {
                  return const CircularProgressIndicator();
                } else if (snapshot.hasError) {
                  return Text("${snapshot.error}");
                } else if (snapshot.hasData) {
                  return ListView.builder(
                    itemCount: snapshot.data!.length,
                    itemBuilder: (context, index) {
                      return ListTile(
                        title: Text(snapshot.data![0].title),
                      );
                    },
                  );
                }
    
                return const Text("handle others");
              }),
        );
      }
    }
    
    

    早餐小部件和模型类不同。

    我建议你从基础开始。 访问 flutter.dev 了解更多信息。

    【讨论】:

    • items 在这个“List.generate”中没有被读取.......children: [ ...List.generate( items[0].length, (index) { if (items[index].isPopular) { return BreakfastCard(breakfast: items[index]); } return const SizedBox .shrink(); // here by default width and height is 0 }, ),
    • 你正在使用FutureBuilder,这个数据将来自snapshot,就像snapshot.data![index]一样,你能不能把完整的小部件包括在内,这样每个人都可以得到它。
    • 非常感谢。我已经包含了完整的小部件。我已经尝试过使用setState,但仍然无法使用。
    • 你能把breakfast.json也包括进来吗,这将是测试UI的简单而正确的方法
    • 是的。我已经包含了 JSON。
    猜你喜欢
    • 2022-01-21
    • 1970-01-01
    • 1970-01-01
    • 2020-11-21
    • 2022-08-21
    • 2013-08-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多