Flutter:如何将数组数据从 json Future< 传递到 Widget
Flutter: How to pass array data from json Future< to Widget
作为 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,),
),
),
),
),
);
}
}
上码与下码如何连接?
提前致谢。
首先,看看你的'items'变量的范围:它是在getItems()函数中定义的,在函数外是不可见的。所以,第一件事:让它达到 class 级别 属性.
接下来 - 您的 initState 将调用您的方法。方法是异步的,在 initState 中处理它的方法是在方法返回的 Future 上使用“.then”。你想在这里做的是:一旦未来完成,你想设置你的 class 级别变量来保存 _getProduct() 函数返回的值。
最后 - 理解这一点非常重要:您不会自己调用构建方法 - Flutter Framework 会为您完成。现在,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];
});
}
}
作为 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,),
),
),
),
),
);
}
}
上码与下码如何连接? 提前致谢。
首先,看看你的'items'变量的范围:它是在getItems()函数中定义的,在函数外是不可见的。所以,第一件事:让它达到 class 级别 属性.
接下来 - 您的 initState 将调用您的方法。方法是异步的,在 initState 中处理它的方法是在方法返回的 Future 上使用“.then”。你想在这里做的是:一旦未来完成,你想设置你的 class 级别变量来保存 _getProduct() 函数返回的值。
最后 - 理解这一点非常重要:您不会自己调用构建方法 - Flutter Framework 会为您完成。现在,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];
});
}
}