我是 Flutter 新手,我正在尝试构建一个在线购物应用作为我的毕业项目。
每次我运行应用程序时,它都会直接进入“物品卡片”方法并通过它进入“详细信息屏幕”,即使它应该只在按下导航器小部件时才会进入。
它还将物品卡标记为肮脏的孩子(我不太明白这是什么意思以及如何将其恢复为正常孩子)。
Error message: The following assertion was thrown building ItemCard(dirty):
setState() or markNeedsBuild() called during build.
我希望我能很好地解释错误..这是代码, 首先是 Body 类,然后是 Item Card 类,然后是 Details Screen 类:
class Body extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Padding(
padding: const EdgeInsets.symmetric(horizontal: kDefaultPaddin),
child: Text(
"Mobiles",
style: Theme.of(context)
.textTheme
.headline5!
.copyWith(fontWeight: FontWeight.bold),
),
),
Categories(),
Expanded(
child: Padding(
padding: const EdgeInsets.symmetric(horizontal: kDefaultPaddin),
child: GridView.builder(
itemCount: productz.length,
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 2,
mainAxisSpacing: kDefaultPaddin,
crossAxisSpacing: kDefaultPaddin,
childAspectRatio: 0.75,
),
itemBuilder: (context, index) => ItemCard(
productz: productz[index],
press: () => Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DetailsScreen(
productz: productz[index],
),
)),
)),
),
),
],
);
}
}
class ItemCard extends StatelessWidget {
final Productz productz;
final Function press;
const ItemCard({
Key? key,
required this.productz,
required this.press,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: press(),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Expanded(
child: Container(
padding: EdgeInsets.all(kDefaultPaddin),
decoration: BoxDecoration(
color: Colors.white12,
borderRadius: BorderRadius.circular(16),
),
child: Hero(
tag: "${productz.id}",
child: Image.asset(productz.item_image),
),
),
),
Padding(
padding: const EdgeInsets.symmetric(vertical: kDefaultPaddin / 4),
child: Text(
// products is out demo list
productz.item_name,
style: TextStyle(color: kTextLightColor),
),
),
Text(
"\$${productz.item_price}",
style: TextStyle(fontWeight: FontWeight.bold),
)
],
),
);
}
}
class DetailsScreen extends StatelessWidget {
final Productz productz;
const DetailsScreen({Key? key, required this.productz}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
// each product have a color
backgroundColor: Colors.white12,
appBar: buildAppBar(context),
body: Body(productz: productz),
);
}
AppBar buildAppBar(BuildContext context) {
return AppBar(
backgroundColor: Colors.white12,
elevation: 0,
leading: IconButton(
icon: Icon(Icons.arrow_back,
size: 30,
color: Colors.white,
),
onPressed: () => Navigator.pop(context),
),
actions: <Widget>[
IconButton(
icon: Icon(FontAwesomeIcons.search),
onPressed: () {},
),
IconButton(
icon: Icon(FontAwesomeIcons.shoppingCart),
onPressed: () {},
),
SizedBox(width: kDefaultPaddin / 2)
],
);
}
}
答案 0 :(得分:0)
正在立即调用 onPress
中的 GestureDetector
函数。
有两种方法可以解决问题。
()
onChanged
处理程序中TextField
或 TextFormField
检查下面的代码片段。
方法 1 的示例。
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: press,
child: ...
)
}
方法 2 示例:
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () => press(),
child: ...
)
}
答案 1 :(得分:0)
将其推迟到下一个刻度会起作用 -
上一个
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: press();
child: ...
)
}
更改为:
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: Future.delayed(Duration.zero, () async {
press();
}),
child: ...
)
}