【发布时间】:2021-01-01 11:02:15
【问题描述】:
我正在尝试制作一个带有购物车中商品数量文本的购物车图标。这需要在另一个小部件中刷新状态时刷新状态。尽管不推荐,我尝试了 setState(),但正如警告的那样,未安装小部件,因此在 null 上调用了 setState()。 然后我从这篇帖子How to set state from another widget? 中了解了 Value Listenable 我试过这个,但它说“NoSuchMethodError:getter 'value'被调用为null,也许我的实现是错误的。
这是我的代码:
var menuJson = [];
var isLoading = true;
class CartIcon extends StatefulWidget {
const CartIcon({Key key2}) : super(key: key2);
@override
_CartIcon createState() => _CartIcon();
}
class _CartIcon extends State<CartIcon> {
@override
Widget build(BuildContext context) {
var filteredList = List();
for (var item in menuJson) {
if (item["quantity"] > 0) {
filteredList.add(item);
}
}
return Padding(
padding: const EdgeInsets.only(top: 35, right: 8),
child: Container(
width: AppBar().preferredSize.height - 12,
height: AppBar().preferredSize.height - 12,
color: Colors.pink,
child: Material(
color: Colors.transparent,
child: InkWell(
borderRadius: BorderRadius.circular(AppBar().preferredSize.height),
child: Stack(
children: <Widget>[
IconButton(
icon: Icon(
Icons.shopping_cart,
color: Colors.white,
),
onPressed: null,
),
filteredList.length == 0
? Container()
: Positioned(
child: Stack(
children: <Widget>[
Icon(Icons.brightness_1,
size: 20.0, color: Colors.green[800]),
Positioned(
top: 3.0,
right: 4.0,
child: Text(
filteredList.length.toString(),
style: TextStyle(
color: Colors.white,
fontSize: 11.0,
fontWeight: FontWeight.w500),
))
],
)),
],
),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => CartPage()),
);
},
),
),
),
);
}
}
class Salads extends StatefulWidget {
const Salads({Key key2}) : super(key: key2);
@override
_Salads createState() => _Salads();
}
class _Salads extends State<Salads> {
final _counter = new ValueNotifier(0);
plus(index) {
var quant = menuJson[index]["quantity"];
quant++;
menuJson[index]["quantity"] = quant;
setState(() {});
}
minus(index) {
var quant = menuJson[index]["quantity"];
quant--;
if (quant < 0) {
quant = 0;
}
menuJson[index]["quantity"] = quant;
setState(() {});
}
@override
Widget build(BuildContext context) {
var filteredList = List();
for (var item in menuJson) {
if (item["category_name"] == "Salads") {
filteredList.add(item);
}
}
if (isLoading) {
return Center(
child: new CircularProgressIndicator(),
);
} else {
return Container(
color: Colors.green,
child: ListView.builder(
itemCount: filteredList.length,
itemBuilder: (context, index) {
return Card(
child: Padding(
padding: const EdgeInsets.only(
top: 10.0, bottom: 10.0, left: 10.0, right: 10.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Container(
padding: EdgeInsets.only(
left: 5, top: 5, bottom: 30),
child: Text(
filteredList[index]["dish_name"],
style: TextStyle(fontSize: 20),
textAlign: TextAlign.left,
),
),
Container(
padding: EdgeInsets.only(
right: 5, top: 5, bottom: 30),
child: Text(
'\u{20B9} ' +
filteredList[index]["price"]
.toString(),
style: TextStyle(
color: Colors.grey.shade600,
fontSize: 20),
textAlign: TextAlign.right,
)),
]),
Row(
mainAxisAlignment: MainAxisAlignment.end,
children: <Widget>[
RawMaterialButton(
onPressed: () =>
plus(filteredList[index]["index"]),
child: new Icon(
Icons.add,
color: Colors.black,
),
fillColor: Colors.white,
shape: CircleBorder(),
),
Text(filteredList[index]["quantity"].toString(),
style: new TextStyle(fontSize: 40.0)),
RawMaterialButton(
onPressed: () =>
minus(filteredList[index]["index"]),
child: new Icon(
const IconData(0xe15b,
fontFamily: 'MaterialIcons'),
color: Colors.black,
),
fillColor: Colors.white,
shape: CircleBorder(),
padding: EdgeInsets.all(0),
)
])
],
)));
}),
);
}
}
}
由于购物车图标在应用栏中,因此它在小部件树中较高。
如何在“沙拉”中按下 + 时,应用栏中的 CartIcon 状态会更新?现在,当我点击购物车按钮时,它会更新状态。
【问题讨论】:
-
嗨@Tushar,您应该为此使用任何状态管理技术,或者您可以将状态从子类更改为父类,但这不是一个好习惯。
标签: flutter widget state cart hybrid-mobile-app