如何在 flutter 中刷新小部件树上的 'if condition'?

How can i refresh 'if condition' on widget tree in flutter?

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

  @override
  _CustomDateAndTimeState createState() => _CustomDateAndTimeState();
}

class _CustomDateAndTimeState extends State<CustomDateAndTime> {
  bool checkDate = false;
  TextEditingController controller = TextEditingController();
  String dateText = '';
  late DateTime date;
  var formatter = new DateFormat('d MMM, yyyy');

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 4),
      child: SizedBox(
        width: MediaQuery.of(context).size.width,
        child: Row(
          mainAxisAlignment: MainAxisAlignment.start,
          children: <Widget>[
            Expanded(
              flex: 4,
              child: datePicker(context),
            ),
            Expanded(
              flex: 1,
              child: Padding(
                padding: EdgeInsets.only(top: 15),
                child: Icon(Icons.date_range_outlined),
              ),
            ),
            if (checkDate == true)
              Expanded(
                flex: 1,
                child: Padding(
                  padding: EdgeInsets.only(top: 15),
                  child: IconButton(
                    icon: Icon(Icons.close),
                    onPressed: () {
                      setState(() {
                        controller.clear();
                        checkDate = false;
                      });
                    },
                  ),
                ),
              ),
          ],
        ),
      ),
    );
  }

  TextFormField datePicker(BuildContext context) {
    return TextFormField(
      readOnly: true,
      controller: controller,
      onTap: () async {
        date = (await showDatePicker(
          context: context,
          initialDate: DateTime.now(),
          firstDate: DateTime(2021, 8),
          lastDate: DateTime(2050),
        ))!;
        if (date.day == DateTime.now().day) {
          controller.text = "TODAY";
          checkDate = true;
        } else if (date.day == DateTime.now().day + 1) {
          controller.text = "TOMORROW";
          checkDate = true;
        } else {
          controller.text = formatter.format(date);
          checkDate = true;
        }
      },
    );
  }
}

在此代码中,如果输入了日期,我将添加一个删除按钮,但为此,if 块需要再次工作。但它不起作用。虽然它是 'statefull widget',但它不在 if 块内。 概括;输入日期后将添加一个新按钮。我怎样才能做到这一点 ? .................................................... ..................................................... .....................

您需要在选择日期后运行 setState。例如

    Future<void> _selectDate(BuildContext context) async {
    final DateTime picked = await showDatePicker(
        context: context,
        initialDate: selectedDate,
        firstDate: DateTime(2015, 8),
        lastDate: DateTime(2101));
    if (picked != null && picked != selectedDate)
      setState(() {
        selectedDate = picked;
      });
  }

Stateful Widgets 在触发 setState() 方法时重建、重绘屏幕。所以,当像“checkDate”这样的状态变量被任何代码块改变时,你也应该触发 setState() 方法。

最佳做法是使用 setState 方法包装您的重新分配行:

if (date.day == DateTime.now().day) {
          controller.text = "TODAY";
          setState((){ checkDate = true;});
        } else if (date.day == DateTime.now().day + 1) {
          controller.text = "TOMORROW";
          setState((){ checkDate = true;});
        } else {
          controller.text = formatter.format(date);
          setState((){ checkDate = true;});
        }

if block 没有调用的原因是因为它只在构建小部件时第一次调用,所以当您稍后更改它的值时不会再次调用。

有很多解决方案,每次你想更改时最简单的一个 checkDate 变量像那样将语句放在 setState() 中

setState(() =>  checkDate = false);

确保小部件再次创建所以代码输入if block

或者使用 ValueListenableBuilder 效率更高

https://www.youtube.com/watch?v=s-ZG-jS5QHQ