【问题标题】:The following assertion was thrown building ReusableCard(dirty): setState() or markNeedsBuild() called during build构建 ReusableCard(dirty) 时抛出了以下断言:在构建期间调用了 setState() 或 markNeedsBuild()
【发布时间】:2023-02-08 23:02:04
【问题描述】:

我正在用 Angela Yu 的 Flutter 构建一个 BMI 计算器。我的代码产生了这个错误,我很不明白。错误在 InputPage widget 的第一行某处,我将不胜感激。 这是错误信息。

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

下面是一些更多的错误信息。

This InputPage widget cannot be marked as needing to build because the framework is already in the process of building widgets. A widget can be marked as needing to be built during the build phase only if one of its ancestors is currently building. This exception is allowed because the framework builds parent widgets before children, which means a dirty descendant will always be built. Otherwise, the framework might not visit this widget during this build phase.
The widget on which setState() or markNeedsBuild() was called was: InputPage
  state: _InputPageState#8c2a5
The widget which was currently being built when the offending call was made was: ReusableCard
  dirty

ReusableCard 小部件

import 'package:flutter/material.dart';
    
    class ReusableCard extends StatelessWidget {
      final Color color;
      final Widget cardChild;
      final Function onPress;
    
      const ReusableCard({
        super.key,
        required this.color,
        this.cardChild = const SizedBox(),
        required this.onPress,
      });
    
      @override
      Widget build(BuildContext context) {
        return Expanded(
          child: GestureDetector(
            onTap: onPress(),
            child: Container(
              margin: const EdgeInsets.all(15.0),
              height: 205.0,
              width: 175.0,
              decoration: BoxDecoration(
                // color: Color(0xFF1D1E33),
                color: color,
                borderRadius: BorderRadius.circular(10.0),
              ),
              child: cardChild,
            ),
          ),
        );
      }
    }

输入页面小部件

import 'package:flutter/material.dart';
import 'reusable_card.dart';
import 'icon_content.dart';

const double bottomContainerHeight = 93.0;
const activeCardColor = Color(0xFF1D1E33);
const inactiveCardColor = Color(0xFF111328);
const bottomContainerColor = Color(0xFFEB1555);

enum Gender {
  male,
  female,
}

class InputPage extends StatefulWidget {
  const InputPage({Key? key}) : super(key: key);

  @override
  State<InputPage> createState() => _InputPageState();
}

class _InputPageState extends State<InputPage> {
  Gender selectedGender = Gender.male;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text(
          'BMI CALCULATOR',
          style: TextStyle(fontSize: 30.0),
        ),
      ),
      body: Column(
        children: [
          Row(
            children: [
              ReusableCard(
                onPress: () {
                  setState(() {
                    selectedGender = Gender.male;
                  });
                },
                color: selectedGender == Gender.male
                    ? activeCardColor
                    : inactiveCardColor,
                cardChild: const IconContent(icon: Icons.male, label: 'MALE'),
              ),
              ReusableCard(
                onPress: () {
                  setState(() {
                    selectedGender = Gender.female;
                  });
                },
                color: selectedGender == Gender.female
                    ? activeCardColor
                    : inactiveCardColor,
                cardChild:
                    const IconContent(icon: Icons.female, label: 'FEMALE'),
              ),
            ],
          ),
          Row(
            children: [
              ReusableCard(
                onPress: () {},
                color: activeCardColor,
              ),
            ],
          ),
        ],
      ),
    );
  }
}

【问题讨论】:

    标签: flutter dart


    【解决方案1】:

    问题来自onTap: onPress(),它在构建时调用该方法。

    您可以在 ReusableCard 上使用 VoidCallback 而不是函数。

    
    class ReusableCard extends StatelessWidget {
      final Color color;
      final Widget cardChild;
      final VoidCallback onPress; // this
    
      const ReusableCard({
        super.key,
        required this.color,
        this.cardChild = const SizedBox(),
        required this.onPress,
      });
    
      @override
      Widget build(BuildContext context) {
        return Expanded(
          child: GestureDetector(
            onTap: onPress, // * 
            child: Container(
              margin: const EdgeInsets.all(15.0),
              height: 205.0,
              width: 175.0,
              decoration: BoxDecoration(
                // color: Color(0xFF1D1E33),
                color: color,
                borderRadius: BorderRadius.circular(10.0),
              ),
              child: cardChild,
            ),
          ),
        );
      }
    }
    

    【讨论】:

      猜你喜欢
      • 2021-09-09
      • 2021-04-19
      • 2021-11-14
      • 2019-02-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-15
      • 1970-01-01
      相关资源
      最近更新 更多