flutter 生成ItemCard(脏)时引发了以下Assert:在生成期间调用了setState()或NeedmarksBuild()

cunj1qz1  于 2023-02-13  发布在  Flutter
关注(0)|答案(3)|浏览(137)

我是flutter的新手,我正在尝试构建一个在线购物应用程序作为我的毕业设计。
每次我运行应用程序,它会直接进入“项目卡”方法,并通过它到“详细信息屏幕”,即使它应该只去那里按下通过导航小部件。
它还将项目卡标记为肮脏的孩子(我不太明白这意味着什么,以及如何恢复为正常的孩子)。

Error message: The following assertion was thrown building ItemCard(dirty):
setState() or markNeedsBuild() called during build.

我希望我解释的错误足够好..以下是代码,首先是身体类,然后项目卡类,然后详细信息屏幕类:

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)
      ],
    );
  }
}
bxpogfeg

bxpogfeg1#

GestureDetector中的onPress函数被立即调用。
有两种方法可以解决这个问题。
1.通过删除(),删除对函数的调用
1.将press函数 Package 在一个匿名函数中,这样当用户实际执行该操作时可以调用I,这通常是在需要对变量求值时完成的,例如在TextFieldTextFormFieldonChanged处理程序中
检查下面的代码片段。

  • 方法1的示例。*
@override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: press,
      child: ...
   )
}
  • 方法2示例:*
@override
  Widget build(BuildContext context) {
    return GestureDetector(
      onTap: () => press(),
      child: ...
   )
}
xytpbqjk

xytpbqjk2#

推迟到下一个滴答声会有用的-

以前

@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: ...
   )
}
rpppsulh

rpppsulh3#

我也有同样的问题。
删除()
onTap:按下(),
这样做
onTap:按下,

相关问题