我是颤振的新手。我正在尝试将数据列表添加到视图中。数据列表具有不同长度的不同订单项集合。我正在从 API 获取数据,但由于订单数据的长度不同,我收到如下图所示的错误。我的 json api 如下:
{
"status":"success",
"message":"Data Fetched",
"data":{
"list":[
{
"id":27,
"order_code":"7wfelnkhuodlbvdseley1",
"chef_id":1,
"user_id":1,
"order_status":1,
"status":1,
"order_datetime":"2020-01-21 18:05:00",
"user_location_id":1,
"price":1600,
"coupon_id":null,
"use_coupon":0,
"discount":0,
"final_price":1600,
"vat_amt":208,
"delivery_charge_amt":0,
"payment_id":1,
"delivery_time":null,
"delivery_user_id":null,
"payment_status":0,
"payment_price":null,
"payment_time":null,
"reject_message":null,
"created_at":"2020-01-21 18:05:00",
"updated_at":"2020-01-21 18:07:46",
"orderdata":[
{
"id":30,
"order_code_id":27,
"chef_id":1,
"food_id":17,
"user_id":1,
"additional_info":null,
"food_qty":4,
"instruction":null,
"price":400,
"food":{
"id":17,
"name":"Prawns Chilli",
"description":"<p>Seared prawns smothered in a spicy, sticky Asian sauce,
these Asian Chilli Garlic Prawns will have you smacking your
lips in utter satisfaction, feeling like you’ve just dined at a fancy modern
Thai restaurant.<wbr /> </p>",
"ingredient_detail":null,
"price":500,
"discount_price":400,
"ribbon_text":null,
"image":"1576657695-prawn chilli3.jpg",
"banner_image":null,
"published_date":"2019-12-18",
"is_offer":1
}
}
]
},
{
"id":29,
"order_code":"lzquyrmthdahxmjm81ja1",
"chef_id":1,
"user_id":1,
"order_status":1,
"status":1,
"order_datetime":"2020-01-21 19:17:52",
"user_location_id":1,
"price":280,
"coupon_id":null,
"use_coupon":0,
"discount":0,
"final_price":280,
"vat_amt":36.4,
"delivery_charge_amt":50,
"payment_id":1,
"delivery_time":null,
"delivery_user_id":null,
"payment_status":0,
"payment_price":null,
"payment_time":null,
"reject_message":null,
"created_at":"2020-01-21 19:17:52",
"updated_at":"2020-01-21 19:18:30",
"orderdata":[
{
"id":33,
"order_code_id":29,
"chef_id":1,
"food_id":11,
"user_id":1,
"additional_info":null,
"food_qty":2,
"instruction":null,
"price":250,
"food":{
"id":11,
"name":"Chicken burger",
"description":"<p>The juicyness of the meat will make you feel heaven.</p>",
"ingredient_detail":null,
"price":300,
"discount_price":250,
"ribbon_text":null,
"image":"1576654603-chick burger.jpg",
"banner_image":null,
"published_date":"2019-12-18",
"is_offer":1
}
},
{
"id":34,
"order_code_id":29,
"chef_id":1,
"food_id":4,
"user_id":1,
"additional_info":null,
"food_qty":2,
"instruction":null,
"price":140,
"food":{
"id":4,
"name":"Momo",
"description":"<p>This juicy steamed momos are prepared from the ground water buffalo meat and are called \"Buff momo\". The wrappers are very thinly rolled and the filling is deliciously spicy and juicy, served along with tangy yellow chutney and classic spicy tomato sauce that compliments the taste of steamed momos.</p>",
"ingredient_detail":"<p>Tomato, Ground meat ,Flour, Chilli pepper, Garlic, Ginger, Scallion, Black pepper and Soy sauce</p>",
"price":150,
"discount_price":140,
"ribbon_text":null,
"image":"1576651666-momo.jpg",
"banner_image":null,
"published_date":"2019-11-18",
"is_offer":1
}
}
]
}
]
}
}
Run Code Online (Sandbox Code Playgroud)
我的完整小部件代码:
class OnProcessPage extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return _OnProcessTile();
}
}
class _OnProcessTile extends State<OnProcessPage> {
bool _isLoading = false;
List<ListD> foodData = [];
List<Orderdata> orderData = [];
SharedPreferences sharedPreferences;
@override
void initState() {
super.initState();
setState(() {
_isLoading = true;
});
getPrefs();
getOnProcessRequest();
}
@override
Widget build(BuildContext context) {
return Center(
child: Stack(
children: <Widget>[
Opacity(
opacity: _isLoading
? 0.3
: 1, // You can reduce this when loading to give different effect
child: AbsorbPointer(
absorbing: _isLoading,
child: _buildCardList(context),
),
),
Opacity(
opacity: _isLoading ? 1.0 : 0,
child: Center(
child: CircularProgressIndicator(
backgroundColor: Theme.of(context).primaryColor,
),
)),
],
));
}
Widget _buildCardList(BuildContext context) {
return ListView.builder(
itemCount: foodData == null ? 0 : foodData.length,
itemBuilder: (context, int index) {
return Wrap(
children: <Widget>[
Container(
margin: EdgeInsets.only(bottom: 10),
child: Card(
child: Column(
children: <Widget>[
_buildCardView(context, index),
_cardBottomView(context, index)
],
)))
],
);
});
}
Widget _buildCardView(BuildContext context, int index) {
return Wrap(
children: <Widget>[
Container(
child: Container(
margin: EdgeInsets.all(10.0),
child: Column(
children: <Widget>[
_cardTopSection(context, index),
_cardMiddleSection(context, index),
_cardTotalPrice(context, index),
Container(
height: 1,
color: Color.fromRGBO(232, 232, 232, 1),
),
],
),
),
),
],
);
}
Widget _cardTotalPrice(BuildContext context, int i) {
return Container(
margin: EdgeInsets.only(bottom: 5.0),
child: Padding(
padding: EdgeInsets.only(top: 3, bottom: 3),
child: Row(
children: <Widget>[
Expanded(
child: Text(""),
),
Expanded(
child: Text("Total",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18,
)),
),
Expanded(
child: Text(
"${foodData[i].finalPrice}",
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 18,
),
),
)
],
),
),
);
}
Widget _cardTopSection(BuildContext context, int index) {
return Container(
color: Color.fromRGBO(232, 232, 232, 1),
child: Row(
children: <Widget>[
_topLeftSection(index),
_topmiddleSection(index),
_toprightSection(index)
],
),
);
}
Widget _cardMiddleSection(BuildContext context, int i) {
return Container(
margin: EdgeInsets.only(top: 10.0),
child: ListView.builder(
shrinkWrap: true,
physics: const NeverScrollableScrollPhysics(),
itemCount:
foodData[i].orderdata == null ? 0 : foodData[i].orderdata.length,
itemBuilder: (context, i) {
print("Item Builder");
print(i);
print("Item Builder");
return _cardMiddleItems(i);
}),
);
}
Widget _cardMiddleItems(int i) {
print("Middle");
print(i);
print("Middle");
return Container(
margin: EdgeInsets.only(bottom: 5.0),
child: Padding(
padding: EdgeInsets.only(top: 3, bottom: 3),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
Expanded(
child: Text("${orderData[i].food.name}"),
),
Expanded(
child: Text("${orderData[i].foodQty}"),
),
Expanded(
child: Text("${orderData[i].price}"),
),
],
),
),
);
}
Widget _topLeftSection(int index) {
return Container(
child: CircleAvatar(
backgroundImage: AssetImage('assets/images/momo.jpg'),
backgroundColor: Colors.lightGreen,
radius: 24.0,
),
);
}
Widget _topmiddleSection(int i) {
return Expanded(
child: Container(
child: Column(
children: <Widget>[
Text("Coldplay "),
Text("${foodData[i].createdAt}")
// new Text("Hi whatsup?"),
],
),
),
);
}
Widget _toprightSection(int index) {
return Expanded(
child: Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Text(
"#" + "${foodData[index].id}",
style: TextStyle(color: Colors.black, fontSize: 18.0),
),
],
),
),
);
}
Widget _cardBottomView(BuildContext context, int index) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Text(
"Order Status",
style: TextStyle(fontSize: 18),
),
RaisedButton(
onPressed: () => {},
color: Colors.green,
child: Text(
"Cooking",
style: TextStyle(color: Colors.white),
),
),
RaisedButton(
onPressed: () => {
sharedPreferences.setBool('process', true),
sharedPreferences.setBool('new', false),
Navigator.push(
context,
MaterialPageRoute(
builder: (BuildContext context) => RequestDetails(),
settings: RouteSettings(
arguments: foodData[index],
),
))
},
color: Theme.of(context).primaryColor,
child: Text("Details", style: TextStyle(color: Colors.white)),
),
],
);
}
Future<NewRequestResponse> getOnProcessRequest() async {
print("OnProcess");
SharedPreferences sharedPreferences = await SharedPreferences.getInstance();
String token = sharedPreferences.getString("api_token");
Map<String, String> headers = {"Authorization": token};
var jsonResponse;
NewRequestResponse newRequestResponse;
var response = await http.post(
"url",
headers: headers);
if (response.statusCode == 200) {
print("Onprocess Inside 200");
jsonResponse = json.decode(response.body);
print(jsonResponse);
if (jsonResponse != null) {
newRequestResponse = new NewRequestResponse.fromJson(jsonResponse);
print(newRequestResponse);
setState(() {
foodData = newRequestResponse.data.list;
for (int i = 0; i < foodData.length; i++) {
orderData = foodData[i].orderdata;
}
});
setState(() {
_isLoading = false;
});
return newRequestResponse;
} else {
setState(() {
_isLoading = false;
});
return null;
}
} else {
setState(() {
_isLoading = false;
});
jsonResponse = json.decode(response.body.toString());
newRequestResponse = new NewRequestResponse.fromJson(jsonResponse);
print("onProcessRequest outside 200");
return newRequestResponse;
}
}
void getPrefs() async {
sharedPreferences = await SharedPreferences.getInstance();
}
}
Run Code Online (Sandbox Code Playgroud)
这有点棘手,所以我希望我能理解这个错误,但对我来说,问题似乎出在你的getOnProcessRequest这一行:
for (int i = 0; i < foodData.length; i++) {
orderData = foodData[i].orderdata;
}
Run Code Online (Sandbox Code Playgroud)
您在 foodData 的每个周期更新(并覆盖) orderData 。我认为这不是正确的做法。
据我了解,每个 foodData 应该发生什么,获取 orderData 列表。但 foodData 是一个列表,orderData 也是。我认为您应该链接这些项目,以便对于每个 foodData 您都可以访问其自己的 orderData 列表。
编辑:我无法提供完整的解决方案,因为老实说这会让我承受太多。但我想出了一个例子
final Map<String, dynamic> myApi = {
"list": [
{
"id": 1,
"orderdata": [
{"title": "food1"},
{"title": "food2"}
]
},
{
"id": 2,
"orderdata": [
{"title": "food3"},
{"title": "food4"}
]
},
]
};
class OrderData {
final String title;
OrderData(this.title);
@override
String toString() {
return title;
}
}
class FoodData {
final int id;
final List<OrderData> orderData;
FoodData(this.id, this.orderData);
}
void main() {
final tmpMap = (myApi['list'] as List<Map<String, Object>>);
print(tmpMap);
List<FoodData> myList = tmpMap.map<FoodData>((elem) {
final value = elem;
final _id = value['id'] as int;
final List<OrderData> _orderData =
(value['orderdata'] as List<Map<String, String>>)
.map<OrderData>((order) => OrderData(order['title']))
.toList();
return FoodData(_id, _orderData);
}).toList();
print(myList.length);
for (int i = 0; i < myList.length; i++) {
for (int j = 0; j < myList[i].orderData.length; j++) {
print("i: $i, j: $j, elem: ${myList[i].orderData[j]}");
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在,最后您需要的是getOnProcessRequest使用单个列表更改您的 ,因此删除您的orderdata,并仅使用fooddata,现在您的 foodData 对于每个元素(食物)也将具有订单的内部表示形式。
当你想实例化 ListView.builder 时:
希望这能帮助您找到合适的解决方案
| 归档时间: |
|
| 查看次数: |
10629 次 |
| 最近记录: |