Flutter导航到新页面时抛出错误
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Flutter导航到新页面时抛出错误相关的知识,希望对你有一定的参考价值。
我已经通过JSON数据创建了Gridview构建器,但是当我导航到新页面时,出现错误:在此SingleItemScreen窗口小部件上方找不到正确的提供程序
要解决,请:
- 确保提供者是此SingleItemScreen小部件的祖先
- 向提供者提供类型
- 向消费者提供类型
- 将类型提供给Provider.of()
- 确保使用正确的
context
。
我不确定这是哪里出了问题。
List<Product> productFromJson(String str) => List<Product>.from(json.decode(str).map((x) => Product.fromJson(x)));
String productToJson(List<Product> data) => json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
class Product
String productId;
String sku;
String itemName;
String listPrice;
String publishedPrice;
String onsale;
String stockQuantity;
StockStatus stockStatus;
String ratingCount;
String averageRating;
String totalSales;
String imagePath;
String category;
Product(
this.productId,
this.sku,
this.itemName,
this.listPrice,
this.publishedPrice,
this.onsale,
this.stockQuantity,
this.stockStatus,
this.ratingCount,
this.averageRating,
this.totalSales,
this.imagePath,
this.category,
);
factory Product.fromJson(Map<String, dynamic> json) => Product(
productId: json["product_id"],
sku: json["sku"],
itemName: json["item_name"],
listPrice: json["list_price"],
publishedPrice: json["published_price"],
onsale: json["onsale"],
stockQuantity: json["stock_quantity"],
stockStatus: stockStatusValues.map[json["stock_status"]],
ratingCount: json["rating_count"],
averageRating: json["average_rating"],
totalSales: json["total_sales"],
imagePath: json["image_path"],
category: json["category"],
);
Map<String, dynamic> toJson() =>
"product_id": productId,
"sku": sku,
"item_name": itemName,
"list_price": listPrice,
"published_price": publishedPrice,
"onsale": onsale,
"stock_quantity": stockQuantity,
"stock_status": stockStatusValues.reverse[stockStatus],
"rating_count": ratingCount,
"average_rating": averageRating,
"total_sales": totalSales,
"image_path": imagePath,
"category": category,
;
enum StockStatus INSTOCK
final stockStatusValues = EnumValues(
"instock": StockStatus.INSTOCK
);
class EnumValues<T>
Map<String, T> map;
Map<T, String> reverseMap;
EnumValues(this.map);
Map<T, String> get reverse
if (reverseMap == null)
reverseMap = map.map((k, v) => new MapEntry(v, k));
return reverseMap;
Future<List<Product>> fetchPhotos(http.Client client) async
final response =
await client.get('http://flutter.bizsupplier.in/product.php');
return compute(parsePhotos, response.body);
Future<List<Product>> parsePhotos(String responseBody) async
final parsed = jsonDecode(responseBody).cast<Map<String, dynamic>>();
return parsed.map<Product>((json) => Product.fromJson(json)).toList();
class MyHomePage extends StatelessWidget
@override
Widget build(BuildContext context)
return FutureBuilder<List<Product>>(
future: fetchPhotos(http.Client()),
builder: (context, snapshot)
if (snapshot.hasError) print(snapshot.error);
if (snapshot.hasData)
return PhotosList(product: snapshot.data);
else
return Center(child: CircularProgressIndicator());
,
);
class PhotosList extends StatelessWidget
final List<Product> product;
PhotosList(Key key, this.product) : super(key: key);
@override
Widget build(BuildContext context)
return GridView.builder(
shrinkWrap: true,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
),
itemCount: product.length,
itemBuilder: (context, index)
return Card(
child: Column(
children: <Widget>[
Container(
height: 150,
child: GestureDetector(
onTap: ()
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => SingleItemScreen(),
settings: RouteSettings(
arguments: product[index]
)
)
);
,
child: Image.network(product[index].imagePath)),
),
Expanded(
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
RaisedButton(
onPressed: () ,
child: Text('Buy Now'),
color: Colors.redAccent,
),
],
),
)
],
),
);
,
);
class SingleItemScreen extends StatelessWidget
final List<Product> product;
SingleItemScreen(Key key, this.product) : super(key: key);
@override
Widget build(BuildContext context)
final Product product = Provider.of<Product>(context, listen: false);
return Scaffold(
appBar: AppBar(
title: Text('Test PhP Navigation'),
actions: <Widget>[
new IconButton(
icon: Icon(
Icons.search,
color: Colors.white,
),
onPressed: () ),
new IconButton(
icon: Icon(
Icons.shopping_cart,
color: Colors.white,
),
onPressed: () ),
],
),
body: SingleChildScrollView(
child: Column(
children: <Widget>[
Container(
height: 300,
child: Image.network(product.imagePath),
),
Container(
child: Text(product.productId),
),
],
),
),
bottomNavigationBar: Container(
width: MediaQuery.of(context).size.width,
height: 50.0,
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Flexible(
fit: FlexFit.tight,
flex: 1,
child: RaisedButton(
onPressed: () ,
color: Colors.grey,
child: Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(
Icons.list,
color: Colors.white,
),
SizedBox(
width: 4.0,
),
Text(
"SAVE",
style: TextStyle(color: Colors.white),
),
],
),
),
),
),
Flexible(
flex: 2,
child: RaisedButton(
onPressed: (),
color: Colors.greenAccent,
child: Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(
Icons.card_travel,
color: Colors.white,
),
SizedBox(
width: 4.0,
),
Text(
"ADD TO BAG",
style: TextStyle(color: Colors.white),
),
],
),
),
),
),
],
),
));
答案
您可以在下面复制粘贴运行完整代码
步骤1:注释settings
并使用SingleItemScreen(product: product[index])
MaterialPageRoute(
builder: (context) =>
SingleItemScreen(product: product[index]),
/*settings: RouteSettings(
arguments: product[index]
)*/
));
步骤2:修改SingleItemScreen
以接受product
class SingleItemScreen extends StatelessWidget
final Product product;
SingleItemScreen(Key key, this.product) : super(key: key);
步骤3:备注Provider
//final Product product = Provider.of<Product>(context, listen: false);
工作演示
完整代码
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'dart:convert';
import 'package:http/http.dart' as http;
List<Product> productFromJson(String str) =>
List<Product>.from(json.decode(str).map((x) => Product.fromJson(x)));
String productToJson(List<Product> data) =>
json.encode(List<dynamic>.from(data.map((x) => x.toJson())));
class Product
String productId;
String sku;
String itemName;
String listPrice;
String publishedPrice;
String onsale;
String stockQuantity;
StockStatus stockStatus;
String ratingCount;
String averageRating;
String totalSales;
String imagePath;
String category;
Product(
this.productId,
this.sku,
this.itemName,
this.listPrice,
this.publishedPrice,
this.onsale,
this.stockQuantity,
this.stockStatus,
this.ratingCount,
this.averageRating,
this.totalSales,
this.imagePath,
this.category,
);
factory Product.fromJson(Map<String, dynamic> json) => Product(
productId: json["product_id"],
sku: json["sku"],
itemName: json["item_name"],
listPrice: json["list_price"],
publishedPrice: json["published_price"],
onsale: json["onsale"],
stockQuantity: json["stock_quantity"],
stockStatus: stockStatusValues.map[json["stock_status"]],
ratingCount: json["rating_count"],
averageRating: json["average_rating"],
totalSales: json["total_sales"],
imagePath: json["image_path"],
category: json["category"],
);
Map<String, dynamic> toJson() =>
"product_id": productId,
"sku": sku,
"item_name": itemName,
"list_price": listPrice,
"published_price": publishedPrice,
"onsale": onsale,
"stock_quantity": stockQuantity,
"stock_status": stockStatusValues.reverse[stockStatus],
"rating_count": ratingCount,
"average_rating": averageRating,
"total_sales": totalSales,
"image_path": imagePath,
"category": category,
;
enum StockStatus INSTOCK
final stockStatusValues = EnumValues("instock": StockStatus.INSTOCK);
class EnumValues<T>
Map<String, T> map;
Map<T, String> reverseMap;
EnumValues(this.map);
Map<T, String> get reverse
if (reverseMap == null)
reverseMap = map.map((k, v) => new MapEntry(v, k));
return reverseMap;
Future<List<Product>> fetchPhotos(http.Client client) async
final response =
await client.get('http://flutter.bizsupplier.in/product.php');
return compute(parsePhotos, response.body);
Future<List<Product>> parsePhotos(String responseBody) async
final parsed = jsonDecode(responseBody).cast<Map<String, dynamic>>();
return parsed.map<Product>((json) => Product.fromJson(json)).toList();
class MyHomePage extends StatelessWidget
@override
Widget build(BuildContext context)
return FutureBuilder<List<Product>>(
future: fetchPhotos(http.Client()),
builder: (context, snapshot)
if (snapshot.hasError) print(snapshot.error);
if (snapshot.hasData)
return PhotosList(product: snapshot.data);
else
return Center(child: CircularProgressIndicator());
,
);
class PhotosList extends StatelessWidget
final List<Product> product;
PhotosList(Key key, this.product) : super(key: key);
@override
Widget build(BuildContext context)
return GridView.builder(
shrinkWrap: true,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
),
itemCount: product.length,
itemBuilder: (context, index)
return Card(
child: Column(
children: <Widget>[
Container(
height: 150,
child: GestureDetector(
onTap: ()
Navigator.push(
context,
MaterialPageRoute(
builder: (context) =>
SingleItemScreen(product: product[index]),
/*settings: RouteSettings(
arguments: product[index]
)*/
));
,
child: Image.network(product[index].imagePath)),
),
Expanded(
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
RaisedButton(
onPressed: () ,
child: Text('Buy Now'),
color: Colors.redAccent,
),
],
),
)
],
),
);
,
);
class SingleItemScreen extends StatelessWidget
final Product product;
SingleItemScreen(Key key, this.product) : super(key: key);
@override
Widget build(BuildContext context)
//final Product product = Provider.of<Product>(context, listen: false);
return Scaffold(
appBar: AppBar(
title: Text('Test PhP Navigation'),
actions: <Widget>[
new IconButton(
icon: Icon(
Icons.search,
color: Colors.white,
),
onPressed: () ),
new IconButton(
icon: Icon(
Icons.shopping_cart,
color: Colors.white,
),
onPressed: () ),
],
),
body: SingleChildScrollView(
child: Column(
children: <Widget>[
Container(
height: 300,
child: Image.network(product.imagePath),
),
Container(
child: Text(product.productId),
),
],
),
),
bottomNavigationBar: Container(
width: MediaQuery.of(context).size.width,
height: 50.0,
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Flexible(
fit: FlexFit.tight,
flex: 1,
child: RaisedButton(
onPressed: () ,
color: Colors.grey,
child: Center(
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
以上是关于Flutter导航到新页面时抛出错误的主要内容,如果未能解决你的问题,请参考以下文章
Android Studio 在运行 Flutter App 时抛出异常
Gradle 在从网络下载工件时抛出错误.. 异常:Gradle 任务 assembleDebug 失败,退出代码为 1