(Flutter)Listview 构建器不会显示复选框列表
(Flutter) Listview builder won't show checkboxlist
没有显示任何错误
但列表视图生成器不显示任何复选框列表。
我哪里出错了?
请指正。
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:selfordering1/models/addon.dart';
import 'package:selfordering1/models/models.dart';
class Americano extends StatefulWidget {
@override
_AmericanoState createState() => _AmericanoState();
}
class _AmericanoState extends State<Americano> {
List<Products> beverages = [];
List<addonsize> listSize = [];
List<addontopping> listTopping = [];
var items = Products().beverages;
bool _value = false;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(''),
leading: IconButton(
icon: Icon(Icons.arrow_back, color: Colors.white),
onPressed: () {
Navigator.pop(context);
},
),
backgroundColor: Colors.transparent,
elevation: 0.0,
),
extendBodyBehindAppBar: true,
body: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/lightwood.jpg'),
fit: BoxFit.fill,
),
),
child: ListView(
physics: NeverScrollableScrollPhysics(),
primary: false,
padding: const EdgeInsets.all(100),
children: <Widget>[
Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
width: 200,
height: 200,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage(items[1].img),
),
),
),
Text(
items[1].name,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 30,
color: Colors.brown),
),
Container(
margin: EdgeInsets.all(50),
child: Text(
items[1].price.toStringAsFixed(0) + ' บาท',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 30,
color: Colors.brown),
),
),
],
),
Row(
children: [
Expanded(
child: ListView.builder(
shrinkWrap: true,
itemCount: listTopping.length,
itemBuilder: (BuildContext context, int i) {
return new Card(
child: new Container(
padding: new EdgeInsets.all(10.0),
child: Column(
children: <Widget>[
new CheckboxListTile(
activeColor: Colors.blue,
dense: true,
//font change
title: new Text(
listTopping[i].topping,
style: TextStyle(
fontSize: 25,
fontWeight: FontWeight.bold,
),
),
value: listTopping[i].isCheck,
secondary: Container(
height: 50,
width: 50,
child: Text(listTopping[i]
.price
.toStringAsFixed(0)),
),
onChanged: (bool? val) {
itemChange(val!, i);
},
),
],
),
),
);
}),
),
],
),
],
),
),
);
}
void itemChange(bool val, int i) {
setState(() {
listTopping[i].isCheck = val;
});
}
}
这是模型
import 'package:flutter/material.dart';
class addonsize {
int id;
String size;
double price;
addonsize({
required this.id,
required this.size,
required this.price,
});
}
List<addonsize> listSize = [
addonsize(
id: 6,
size: 'Grande',
price: 30,
),
addonsize(
id: 7,
size: 'Venti',
price: 50,
),
];
class addontopping {
int id;
String topping;
double price;
bool isCheck;
addontopping({
required this.id,
required this.topping,
required this.price,
required this.isCheck,
});
}
List<addontopping> listTopping = [
addontopping(
id: 8,
topping: 'Whipcream',
price: 0,
isCheck: true,
),
addontopping(
id: 9,
topping: 'Javachip',
price: 30,
isCheck: false,
),
addontopping(
id: 10,
topping: 'SoyMilk',
price: 20,
isCheck: false,
),
addontopping(
id: 11,
topping: 'ExtraSyrup',
price: 30,
isCheck: false,
),
];
如果需要更详细的,请告诉我。
另外,如果不是太多,我希望价格根据浇头的点击进行相应调整。请给我看例子@_@
因为您的 'CheckboxListTile' 是由 'ListView.builder' 使用 listTopping 列表构建的。
但是在“_AmericanoState”class 中,listTopping 是空的。
...
List<addontopping> listTopping = [];
...
ListView.builder(
shrinkWrap: true,
itemCount: listTopping.length,
itemBuilder: (BuildContext context, int i) {
return new Card(
child: new Container(
padding: new EdgeInsets.all(10.0),
child: Column(
children: <Widget>[
new CheckboxListTile(
您需要更改“_AmericanoState”中的 listTopping 变量 class,如下所示。
List<addontopping> listTopping = [
addontopping(
id: 8,
topping: 'Whipcream',
price: 0,
isCheck: true,
),
addontopping(
id: 9,
topping: 'Javachip',
price: 30,
isCheck: false,
),
addontopping(
id: 10,
topping: 'SoyMilk',
price: 20,
isCheck: false,
),
addontopping(
id: 11,
topping: 'ExtraSyrup',
price: 30,
isCheck: false,
),
];
原因是您在 2 个不同的文件中有 2 个 listTopping
和 2 个 listSize
变量。它会将您本地 _AmericanoState
class(没有数据)中的一个优先于另一个(有数据)。
要解决此问题,只需将 _AmericanoState
中的 listTopping
和 listSize
替换为其他文件中包含数据的列表即可。
class Americano extends StatefulWidget {
@override
_AmericanoState createState() => _AmericanoState();
}
class _AmericanoState extends State<Americano> {
List<Products> beverages = [];
var items = Products().beverages;
List<addonsize> listSize = [
addonsize(
id: 6,
size: 'Grande',
price: 30,
),
addonsize(
id: 7,
size: 'Venti',
price: 50,
),
];
List<addontopping> listTopping = [
addontopping(
id: 8,
topping: 'Whipcream',
price: 0,
isCheck: true,
),
addontopping(
id: 9,
topping: 'Javachip',
price: 30,
isCheck: false,
),
addontopping(
id: 10,
topping: 'SoyMilk',
price: 20,
isCheck: false,
),
addontopping(
id: 11,
topping: 'ExtraSyrup',
price: 30,
isCheck: false,
),
];
对于每次选择浇头后的价格更新,您可以使用此方法。此 returns 一个 double
值,您可以在 UI:
中使用
double calculatePrice() {
if (listTopping.isNotEmpty) {
var _price;
// Get those toppings that are chosen (`isCheck` is true)
final chosenTopping = listTopping.where((element) => element.isCheck);
// Calculate the sum
for (var item in chosenTopping) {
_price += item.price;
}
return _price;
}
return 0.0;
}
快速说明: 你应该在 Flutter 中为每个 class 名称使用 UpperCamelCase
作为一个好习惯(所以 AddonTopping
而不是 addontopping
).阅读更多关于 styling here
没有显示任何错误 但列表视图生成器不显示任何复选框列表。 我哪里出错了? 请指正。
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:selfordering1/models/addon.dart';
import 'package:selfordering1/models/models.dart';
class Americano extends StatefulWidget {
@override
_AmericanoState createState() => _AmericanoState();
}
class _AmericanoState extends State<Americano> {
List<Products> beverages = [];
List<addonsize> listSize = [];
List<addontopping> listTopping = [];
var items = Products().beverages;
bool _value = false;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(''),
leading: IconButton(
icon: Icon(Icons.arrow_back, color: Colors.white),
onPressed: () {
Navigator.pop(context);
},
),
backgroundColor: Colors.transparent,
elevation: 0.0,
),
extendBodyBehindAppBar: true,
body: Container(
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage('assets/lightwood.jpg'),
fit: BoxFit.fill,
),
),
child: ListView(
physics: NeverScrollableScrollPhysics(),
primary: false,
padding: const EdgeInsets.all(100),
children: <Widget>[
Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
width: 200,
height: 200,
decoration: BoxDecoration(
image: DecorationImage(
image: AssetImage(items[1].img),
),
),
),
Text(
items[1].name,
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 30,
color: Colors.brown),
),
Container(
margin: EdgeInsets.all(50),
child: Text(
items[1].price.toStringAsFixed(0) + ' บาท',
style: TextStyle(
fontWeight: FontWeight.bold,
fontSize: 30,
color: Colors.brown),
),
),
],
),
Row(
children: [
Expanded(
child: ListView.builder(
shrinkWrap: true,
itemCount: listTopping.length,
itemBuilder: (BuildContext context, int i) {
return new Card(
child: new Container(
padding: new EdgeInsets.all(10.0),
child: Column(
children: <Widget>[
new CheckboxListTile(
activeColor: Colors.blue,
dense: true,
//font change
title: new Text(
listTopping[i].topping,
style: TextStyle(
fontSize: 25,
fontWeight: FontWeight.bold,
),
),
value: listTopping[i].isCheck,
secondary: Container(
height: 50,
width: 50,
child: Text(listTopping[i]
.price
.toStringAsFixed(0)),
),
onChanged: (bool? val) {
itemChange(val!, i);
},
),
],
),
),
);
}),
),
],
),
],
),
),
);
}
void itemChange(bool val, int i) {
setState(() {
listTopping[i].isCheck = val;
});
}
}
这是模型
import 'package:flutter/material.dart';
class addonsize {
int id;
String size;
double price;
addonsize({
required this.id,
required this.size,
required this.price,
});
}
List<addonsize> listSize = [
addonsize(
id: 6,
size: 'Grande',
price: 30,
),
addonsize(
id: 7,
size: 'Venti',
price: 50,
),
];
class addontopping {
int id;
String topping;
double price;
bool isCheck;
addontopping({
required this.id,
required this.topping,
required this.price,
required this.isCheck,
});
}
List<addontopping> listTopping = [
addontopping(
id: 8,
topping: 'Whipcream',
price: 0,
isCheck: true,
),
addontopping(
id: 9,
topping: 'Javachip',
price: 30,
isCheck: false,
),
addontopping(
id: 10,
topping: 'SoyMilk',
price: 20,
isCheck: false,
),
addontopping(
id: 11,
topping: 'ExtraSyrup',
price: 30,
isCheck: false,
),
];
如果需要更详细的,请告诉我。 另外,如果不是太多,我希望价格根据浇头的点击进行相应调整。请给我看例子@_@
因为您的 'CheckboxListTile' 是由 'ListView.builder' 使用 listTopping 列表构建的。
但是在“_AmericanoState”class 中,listTopping 是空的。
...
List<addontopping> listTopping = [];
...
ListView.builder(
shrinkWrap: true,
itemCount: listTopping.length,
itemBuilder: (BuildContext context, int i) {
return new Card(
child: new Container(
padding: new EdgeInsets.all(10.0),
child: Column(
children: <Widget>[
new CheckboxListTile(
您需要更改“_AmericanoState”中的 listTopping 变量 class,如下所示。
List<addontopping> listTopping = [
addontopping(
id: 8,
topping: 'Whipcream',
price: 0,
isCheck: true,
),
addontopping(
id: 9,
topping: 'Javachip',
price: 30,
isCheck: false,
),
addontopping(
id: 10,
topping: 'SoyMilk',
price: 20,
isCheck: false,
),
addontopping(
id: 11,
topping: 'ExtraSyrup',
price: 30,
isCheck: false,
),
];
原因是您在 2 个不同的文件中有 2 个 listTopping
和 2 个 listSize
变量。它会将您本地 _AmericanoState
class(没有数据)中的一个优先于另一个(有数据)。
要解决此问题,只需将 _AmericanoState
中的 listTopping
和 listSize
替换为其他文件中包含数据的列表即可。
class Americano extends StatefulWidget {
@override
_AmericanoState createState() => _AmericanoState();
}
class _AmericanoState extends State<Americano> {
List<Products> beverages = [];
var items = Products().beverages;
List<addonsize> listSize = [
addonsize(
id: 6,
size: 'Grande',
price: 30,
),
addonsize(
id: 7,
size: 'Venti',
price: 50,
),
];
List<addontopping> listTopping = [
addontopping(
id: 8,
topping: 'Whipcream',
price: 0,
isCheck: true,
),
addontopping(
id: 9,
topping: 'Javachip',
price: 30,
isCheck: false,
),
addontopping(
id: 10,
topping: 'SoyMilk',
price: 20,
isCheck: false,
),
addontopping(
id: 11,
topping: 'ExtraSyrup',
price: 30,
isCheck: false,
),
];
对于每次选择浇头后的价格更新,您可以使用此方法。此 returns 一个 double
值,您可以在 UI:
double calculatePrice() {
if (listTopping.isNotEmpty) {
var _price;
// Get those toppings that are chosen (`isCheck` is true)
final chosenTopping = listTopping.where((element) => element.isCheck);
// Calculate the sum
for (var item in chosenTopping) {
_price += item.price;
}
return _price;
}
return 0.0;
}
快速说明: 你应该在 Flutter 中为每个 class 名称使用 UpperCamelCase
作为一个好习惯(所以 AddonTopping
而不是 addontopping
).阅读更多关于 styling here