无法在Flutter中不先更改日期的情况下选择当前日期。

huangapple go评论70阅读模式
英文:

Bug , Cannot select current date without changing to a different date first in flutter

问题

日期选择字段

无法在Flutter中不先更改日期的情况下选择当前日期。1

日期选择器

无法在Flutter中不先更改日期的情况下选择当前日期。2

在当前实现中,默认显示的日期是今天的日期。但是,如果用户希望选择当前日期,他们必须首先更改日期,然后重新选择今天的日期。我想通过使生日字段最初显示当前日期来解决这个问题。当用户点击字段时,日期选择器应该打开并显示今天的日期。如果用户不选择不同的日期或想要选择今天的日期,他们应该能够通过单击屏幕上的任何位置(自动最小化日期选择器)或单击日期选择器本身来执行此操作,日期选择器本身应该选择并显示今天的日期。

代码

UI 代码

GestureDetector(
  onTap: () => showDatePicker(context),
  child: SizedBox(
    width: width * 0.9,
    height: height * 0.06,
    child: Container(
      decoration: BoxDecoration(
        color: Colors.white,
        border: Border.all(
          color: Colors.black,
          width: 1.0,
        ),
        borderRadius: BorderRadius.circular(15),
      ),
      child: Padding(
        padding: EdgeInsets.only(
          left: width * 0.060, top: height * 0.018),
        child: Text(
          selectedDate == null
            ? '生日'
            : '${selectedDate?.year}/${selectedDate?.month}/${selectedDate?.day} ',
          style: TextStyle(
            fontSize: 16, fontWeight: FontWeight.w500),
          ),
        ),
      ),
    ),
  ),
),

showDatePicker(context) 代码

DateTime? selectedDate;
DateTime now = DateTime.now();

void showDatePicker(BuildContext context) {
  DateTime initialDate = DateTime.now();
  DateTime minDate = DateTime(initialDate.year - 50, initialDate.month, initialDate.day);

  showCupertinoModalPopup(
    context: context,
    builder: (BuildContext builder) {
      return Container(
        height: MediaQuery.of(context).copyWith().size.height * 0.25,
        color: Colors.white,
        child: CupertinoDatePicker(
          maximumYear: initialDate.year,
          minimumYear: initialDate.year - 50,
          mode: CupertinoDatePickerMode.date,
          initialDateTime: initialDate,
          onDateTimeChanged: (value) {
            setState(() {
              selectedDate = value;
              // calAge();
            });
          },
          maximumDate: initialDate,
          minimumDate: minDate,
        ),
      );
    },
  );
}

如何解决这个问题?

英文:

date picker field

无法在Flutter中不先更改日期的情况下选择当前日期。

date picker

无法在Flutter中不先更改日期的情况下选择当前日期。

In the current implementation, the default date displayed is today's date. However, if a user wishes to select the current date, they must first change the date and then reselect today's date. I would like to address this issue by making the birthday field initially display the current date. When the user clicks on the field, the date picker should open and show today's date. If the user doesn't select a different date or wants to select today's date, they should be able to do so by clicking anywhere on the screen (automatically minimizing the date picker) or by clicking the date picker itself, which should select and display today's date.

code

ui code

         GestureDetector(
              onTap: () => showDatePicker(context),
              child: SizedBox(
                width: width * 0.9,
                height: height * 0.06,
                child: Container(
                  decoration: BoxDecoration(
                    color: Colors.white,
                    border: Border.all(
                      color: Colors.black,
                      width: 1.0,
                    ),
                    borderRadius: BorderRadius.circular(15),
                  ),
                  child: Padding(
                    padding: EdgeInsets.only(
                        left: width * 0.060, top: height * 0.018),
                    child: Text(
                      selectedDate == null
                          ? 'Birthday'
                          : '${selectedDate?.year}/${selectedDate?.month}/${selectedDate?.day} ',
                      style: TextStyle(
                          fontSize: 16, fontWeight: FontWeight.w500),
                    ),
                  ),
                ),
              ),
            ),

showDatePicker(context) code

  DateTime? selectedDate;
  DateTime now = DateTime.now();

  void showDatePicker(BuildContext context) {
    DateTime initialDate = DateTime.now();
    DateTime minDate = DateTime(initialDate.year - 50, initialDate.month, initialDate.day);

    showCupertinoModalPopup(
      context: context,
      builder: (BuildContext builder) {
        return Container(
          height: MediaQuery.of(context).copyWith().size.height * 0.25,
          color: Colors.white,
          child: CupertinoDatePicker(
            maximumYear: initialDate.year,
            minimumYear: initialDate.year - 50,
            mode: CupertinoDatePickerMode.date,
            initialDateTime: initialDate,
            onDateTimeChanged: (value) {
              setState(() {
                selectedDate = value;
                // calAge();
              });
            },
            maximumDate: initialDate,
            minimumDate: minDate,
          ),
        );
      },
    );
  }

How to solve this?

答案1

得分: 1

这个问题有一个简单的解决办法。在调用选择器函数时,将今天的日期赋给选定的日期变量,然后等待用户在选择器上的响应,如果用户更改日期,它将更新数据,否则它将在用户关闭选择器后立即更新状态

代码 : -

    Future<void> showDatePicker(BuildContext context) async { // &lt;-- 将此函数改为异步
        DateTime initialDate = DateTime.now();
        selectedDate = initialDate;  // &lt;-- 添加这行 
        DateTime minDate =
            DateTime(initialDate.year - 50, initialDate.month, initialDate.day);
    
        await showCupertinoModalPopup(  // &lt;-- 在此函数上使用 await
          context: context,
          builder: (BuildContext builder) {
            return Container(
              height: MediaQuery.of(context).copyWith().size.height * 0.25,
              color: Colors.white,
              child: CupertinoDatePicker(
                maximumYear: initialDate.year,
                minimumYear: initialDate.year - 50,
                mode: CupertinoDatePickerMode.date,
                initialDateTime: initialDate,
                onDateTimeChanged: (value) {
                  setState(() {
                    selectedDate = value;
                    // calAge();
                  });
                },
                maximumDate: initialDate,
                minimumDate: minDate,
              ),
            );
          },
        );
        setState(() {}); // &lt;-- 更新状态
      }

要在用户点击今天的日期时关闭选择器,您需要将Container小部件包装在GestureDetector小部件中,并像这样弹出选择器: -

    Future<void> showDatePicker(BuildContext context) async {
        
        DateTime initialDate = DateTime.now();
        selectedDate = initialDate; 
        DateTime minDate =
            DateTime(initialDate.year - 50, initialDate.month, initialDate.day);
    
        await showCupertinoModalPopup(
         
          context: context,
          builder: (BuildContext builder) {
            return GestureDetector( // &lt;-- 使用GestureDetector检测onTap
              behavior: HitTestBehavior.translucent,
              onTap: () {
                Navigator.pop(context);
              },
              child: Container(
                height: MediaQuery.of(context).copyWith().size.height * 0.25,
                color: Colors.white,
                child: CupertinoDatePicker(
                  maximumYear: initialDate.year,
                  minimumYear: initialDate.year - 50,
                  mode: CupertinoDatePickerMode.date,
                  initialDateTime: initialDate,
                  onDateTimeChanged: (value) {
                    setState(() {
                      selectedDate = value;
                      // calAge();
                    });
                  },
                  maximumDate: initialDate,
                  minimumDate: minDate,
                ),
              ),
            );
          },
        );
        setState(() {}); 
      }
英文:

This issue has an easy fix. When the picker function is called assign today's date to the selected date variable and then wait for the user's response on the picker, if the user changes the date it will update the data if not it will still update the state right after the user closes the picker

Code : -

Future&lt;void&gt; showDatePicker(BuildContext context) async { // &lt;-- add async to this function
    DateTime initialDate = DateTime.now();
    selectedDate = initialDate;  // &lt;-- add this line 
    DateTime minDate =
        DateTime(initialDate.year - 50, initialDate.month, initialDate.day);

    await showCupertinoModalPopup(  // &lt;-- use await on this function
      context: context,
      builder: (BuildContext builder) {
        return Container(
          height: MediaQuery.of(context).copyWith().size.height * 0.25,
          color: Colors.white,
          child: CupertinoDatePicker(
            maximumYear: initialDate.year,
            minimumYear: initialDate.year - 50,
            mode: CupertinoDatePickerMode.date,
            initialDateTime: initialDate,
            onDateTimeChanged: (value) {
              setState(() {
                selectedDate = value;
                // calAge();
              });
            },
            maximumDate: initialDate,
            minimumDate: minDate,
          ),
        );
      },
    );
    setState(() {}); // &lt;-- update the state
  }

And to close the picker when the user taps on todays date, you have to wrap the Container widget with GestureDetector widget and pop the picker like this : -

Future&lt;void&gt; showDatePicker(BuildContext context) async {
    
    DateTime initialDate = DateTime.now();
    selectedDate = initialDate; 
    DateTime minDate =
        DateTime(initialDate.year - 50, initialDate.month, initialDate.day);

    await showCupertinoModalPopup(
     
      context: context,
      builder: (BuildContext builder) {
        return GestureDetector( // &lt;-- detect onTap with GestureDetector
          behavior: HitTestBehavior.translucent,
          onTap: () {
            Navigator.pop(context);
          },
          child: Container(
            height: MediaQuery.of(context).copyWith().size.height * 0.25,
            color: Colors.white,
            child: CupertinoDatePicker(
              maximumYear: initialDate.year,
              minimumYear: initialDate.year - 50,
              mode: CupertinoDatePickerMode.date,
              initialDateTime: initialDate,
              onDateTimeChanged: (value) {
                setState(() {
                  selectedDate = value;
                  // calAge();
                });
              },
              maximumDate: initialDate,
              minimumDate: minDate,
            ),
          ),
        );
      },
    );
    setState(() {}); 
  }

huangapple
  • 本文由 发表于 2023年6月15日 16:42:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/76480674.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定