英文:
Bug , Cannot select current date without changing to a different date first in flutter
问题
日期选择字段
日期选择器
在当前实现中,默认显示的日期是今天的日期。但是,如果用户希望选择当前日期,他们必须首先更改日期,然后重新选择今天的日期。我想通过使生日字段最初显示当前日期来解决这个问题。当用户点击字段时,日期选择器应该打开并显示今天的日期。如果用户不选择不同的日期或想要选择今天的日期,他们应该能够通过单击屏幕上的任何位置(自动最小化日期选择器)或单击日期选择器本身来执行此操作,日期选择器本身应该选择并显示今天的日期。
代码
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
date picker
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 { // <-- 将此函数改为异步
DateTime initialDate = DateTime.now();
selectedDate = initialDate; // <-- 添加这行
DateTime minDate =
DateTime(initialDate.year - 50, initialDate.month, initialDate.day);
await showCupertinoModalPopup( // <-- 在此函数上使用 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(() {}); // <-- 更新状态
}
要在用户点击今天的日期时关闭选择器,您需要将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( // <-- 使用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<void> showDatePicker(BuildContext context) async { // <-- add async to this function
DateTime initialDate = DateTime.now();
selectedDate = initialDate; // <-- add this line
DateTime minDate =
DateTime(initialDate.year - 50, initialDate.month, initialDate.day);
await showCupertinoModalPopup( // <-- 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(() {}); // <-- 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<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( // <-- 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(() {});
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论