【问题标题】:Flutter: How to pass array data from json Future< to WidgetFlutter:如何将数组数据从 json Future< 传递到 Widget
【发布时间】:2021-06-21 08:11:49
【问题描述】:

作为 Flutter 的新手,我正在学习并在旅途中磕磕绊绊。

我正在尝试将从 json 接收到的数组传递到已经在等待的小部件结构中,但似乎无法获得连接。

示例代码如下:

class Products extends StatefulWidget {
  @override
  _ProductsState createState() => _ProductsState();
}

class _ProductsState extends State<Products> {
  @override
  void initState() {
    _getProducts();
  }

  Future<List<Single_prod>> _getProducts() async {
    var url = "";
    var data = await http.get(url);

    var jsonData = json.decode(data.body) as Map<String, dynamic>;
    //print(jsonData.toString());
    //jsonData.forEach((k, v) => print("Key : $k, Value : $v"));

    List<Single_prod> items = [];
    jsonData.forEach((k, v){
      Single_prod item = Single_prod(v["error"], v["id"], v["name"], v["price"], v["image"]);

      items.add(item);
    });
    //print(items.length);
    return items; <---Tring to pass this to Widget build but not recognized.....
  }

  @override
  Widget build(BuildContext context) {
    return GridView.builder(
        itemCount: items.length,
        gridDelegate: new SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3),
        itemBuilder: (BuildContext context, int index){
          return Single_prod(
            prod_err: items[index]['error'], <--- This items array is not recognized
            prod_id: items[index]['id'],
            prod_name: items[index]['name'],
            prod_price: items[index]['price'],
            prod_image: items[index]['image'],
          );
        });
  }

}

items 数组在小部件中无法识别

下面是剩下的代码:

class Single_prod extends StatelessWidget {
  final prod_err;
  final prod_id;
  final prod_name;
  final prod_price;
  final prod_image;

  Single_prod({
    this.prod_err,
    this.prod_id,
    this.prod_name,
    this.prod_price,
    this.prod_image,
  });

  @override
  Widget build(BuildContext context) {
    return Card(
      child: Hero(
        tag: prod_name,
        child: Material(
          child: InkWell(
            onTap: () => Navigator.of(context).push(new MaterialPageRoute(
              // here we are passing the values of the products to the details page
                builder: (context) => new ProductDetails(
                  prod_detail_name: prod_name,
                  prod_detail_image: prod_image,
                  prod_detail_id: prod_id,
                  prod_detail_price: prod_price,
                ))),
            child: GridTile(
              footer: Container(
                height: 40.0,
                color: Colors.white70,
                child: ListTile(
                  leading: Text(prod_name, style: TextStyle(fontWeight: FontWeight.bold),),
                  title: Text(
                    prod_price,
                    style: TextStyle(color: Colors.blue, fontWeight: FontWeight.w800, fontSize: 12),
                  ),
                  /*subtitle: Text(
                    prod_oldprice,
                    style: TextStyle(color: Colors.black, fontWeight: FontWeight.w800, fontSize: 11, decoration: TextDecoration.lineThrough),
                  ),*/
                ),
              ),
              child: Image.asset(prod_image,
                fit: BoxFit.cover,),
            ),
          ),
        ),
      ),
    );
  }
}

上面的代码和下面的代码是如何连接的? 提前致谢。

【问题讨论】:

    标签: arrays json flutter widget


    【解决方案1】:

    首先,查看“items”变量的范围:它在 getItems() 函数中定义,在函数外部不可见。所以,第一件事:让它成为类级别的属性。

    接下来 - 您的 initState 将调用您的方法。方法是异步的,并且在 initState 中处理它的方式是在您的方法返回的 Future 上使用“.then”。你在这里要做的是:一旦未来完成,你想设置你的类级别变量来保存 _getProduct() 函数返回的值。

    最后——理解这一点非常重要:你自己不会调用 build 方法——flutter 框架会为你做这件事。现在,flutter 没有一种神奇的方式来知道您何时更改了数据 - 它不会观察您的代码,因此您需要以某种方式告诉它您的状态对象已更改,并且需要重建。您可以通过调用 setState() 函数来完成。

    我认为您实际上还有另一个问题:您已经在 _getProduct() 中构建了 Single_prod 小部件,无需再次构建它。我也试图纠正这个问题。

    试试这个(我没有编译它,所以它可能有一些错误):

    class Products extends StatefulWidget {
      @override
      _ProductsState createState() => _ProductsState();
    }
    
    class _ProductsState extends State<Products> {
    
      List<Single_prod> items = [];
      @override
      void initState() {
        super.initState();
        _getProducts().then( (result) {
            setState(() {
               items=result;
            }
        });
      }
    
      Future<List<Single_prod>> _getProducts() async {
        var url = "";
        var data = await http.get(url);
    
        var jsonData = json.decode(data.body) as Map<String, dynamic>;
        //print(jsonData.toString());
        //jsonData.forEach((k, v) => print("Key : $k, Value : $v"));
    
        List<Single_prod> items = [];
        jsonData.forEach((k, v){
          Single_prod item = Single_prod(v["error"], v["id"], v["name"], v["price"], v["image"]);
    
          items.add(item);
        });
        //print(items.length);
        return items; 
      }
    
      @override
      Widget build(BuildContext context) {
        return GridView.builder(
            itemCount: items.length,
            gridDelegate: new SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3),
            itemBuilder: (BuildContext context, int index){
              return items[index];
            });
      }
    
    }
    

    【讨论】:

    • 我花了一段时间来连接和清理错误,但您的实现是正确的。非常感谢?
    猜你喜欢
    • 2020-02-27
    • 2020-01-21
    • 2020-07-30
    • 2020-12-17
    • 2021-05-26
    • 2020-07-08
    • 2018-05-26
    • 1970-01-01
    • 2017-01-14
    相关资源
    最近更新 更多