【问题标题】:Flutter: setState() or markNeedsBuild() called during build from onPressedFlutter:在构建期间从 onPressed 调用 setState() 或 markNeedsBuild()
【发布时间】:2023-01-04 23:18:28
【问题描述】:

当有人单击 ListTile 的尾随图标时,我试图显示一个对话框,但我收到“在构建期间调用的 setState() 或 markNeedsBuild()”错误消息。这是卡片(在 MyCard 类中)和给我错误消息的函数(checkCard):

static Widget buildCard(MyCard card, BuildContext context) {
    var dateFormat = DateFormat('MM/dd/yyyy');
    return Column(
      children: [
        Align(
            alignment: Alignment.centerRight,
            child: Text(dateFormat.format(card.createdOn.toDate()))),
        const SizedBox(height: 6),
        ListTile(
          shape:
              RoundedRectangleBorder(borderRadius: BorderRadius.circular(30)),
          tileColor: Colors.white,
          leading: CircleAvatar(child: Text(card.subCategory)),
          title: Text("Score: " + card.score + " Misses: " + card.misses),
          subtitle: card.comment.isNotEmpty
              ? Text("Comment(s): " + card.comment)
              : null,
          trailing: IconButton(
              icon: const Icon(Icons.arrow_forward_ios),
              onPressed: checkCard(card, context)),
        ),
        const SizedBox(height: 18),
      ],
    );
  }

  static checkCard(MyCard card, BuildContext context) {
    showDialog(context: context, builder: (context) => const Text("Hello"));
  }

它们是从 StatefulWidgets 构建的,如下所示:

@override
  Widget build(BuildContext context) =>
      FutureBuilder<List<Map<String, dynamic>>>(
        future: MyCard.getData(3, Utils.ddfDropdown)!
            .whenComplete(() => setState(() {
                  isLoading = false;
                })),
        builder: ((context, snapshot) {
          if (snapshot.hasData && snapshot.data!.isNotEmpty) {
            return FutureBuilder<List<MyCard>>(
                future: MyCard.readData(snapshot.data),
                builder: (context, cards) {
                  if (cards.hasData) {
                    final card = cards.data!;
                    return Expanded(
                      child: ListView.builder(
                        padding: const EdgeInsets.all(16),
                        itemCount: card.length,
                        itemBuilder: (context, index) {
                          return MyCard.buildCard(card[index], context); //Cards being built here
                        },
                      ),
                    );
                  }

我在别处查找了这个错误;一项建议是执行以下操作:

static checkCard(MyCard card, BuildContext context) {
    WidgetsBinding.instance.addPostFrameCallback((_) {
      showDialog(context: context, builder: (context) => const Text("Hello"));
    });
  }

但似乎这样做会调用 showDialog 而不必单击尾随的 IconButton,然后屏幕就会变黑。 另一个建议是做类似的事情:

static checkCard(MyCard card, BuildContext context) {
    SchedulerBinding.instance.addPostFrameCallback((_) {
      showDialog(context: context, builder: (context) => const Text("Hello"));
    });
  }

但同样的事情发生了(似乎无需单击即可调用 showDialog 并且屏幕变黑)。

【问题讨论】:

    标签: flutter dart dialog setstate


    【解决方案1】:

    问题来自于在构建小部件时调用方法。

      onPressed: checkCard(card, context)),
    

    你喜欢在按下时调用方法,所以它可以是

      onPressed:()=> checkCard(card, context)),
    

    【讨论】:

      猜你喜欢
      • 2020-12-12
      • 2020-12-28
      • 2021-01-06
      • 2021-05-31
      • 2021-08-24
      • 2020-08-11
      • 2020-04-10
      相关资源
      最近更新 更多