flutter - 将控制器添加到自定义小部件
问题描述
我创建了一个自定义小部件MyDateTimePicker
,它基本上是一个TextFormField
显示日期并允许用户点击选择日期的小部件。现在,我的问题是,我想从父小部件中的另一个事件更新当前选择/显示的日期。起初我想使用像TextEditingController
for这样的控制器TextFormField
。不幸的是,我不知道该怎么做,所以我选择了最后的方法,即使用全局键作为小部件状态并使用键从父小部件调用更新函数。正如许多人所说,尽可能避免使用全局键,所以我想使用控制器。如果可能的话,我希望你能帮助我了解如何为我的自定义小部件使用控制器。谢谢!
class MyDateTimePicker extends StatefulWidget {
const MyDateTimePicker(
{Key key,
this.labelText,
@required this.initialDate,
this.onValueChanged})
: super(key: key);
final String labelText;
final DateTime initialDate;
final ValueChanged<DateTime> onValueChanged;
@override
MyDateTimePickerState createState() => MyDateTimePickerState();
}
class MyDateTimePickerState extends State<MyDateTimePicker> {
final TextEditingController _controller = TextEditingController();
DateTime _selectedDate;
@override
void initState() {
super.initState();
_selectedDate = widget.initialDate;
_controller.text = DateFormat.yMMMd().format(_selectedDate);
}
// Called by the parent widget through a global key.
void setDate(DateTime date) {
_selectedDate = date;
_controller.text = DateFormat.yMMMd().format(_selectedDate);
}
Future<void> _selectDate(BuildContext context) async {
final DateTime picked = await showDatePicker(
context: context,
initialDate: _selectedDate,
firstDate: DateTime(1970, 8),
lastDate: DateTime(2101));
if (picked != null && picked != _selectedDate) {
_selectedDate = picked;
_controller.text = DateFormat.yMMMd().format(_selectedDate);
widget.onValueChanged(picked);
}
}
@override
Widget build(BuildContext context) {
return TextFormField(
controller: _controller,
decoration: InputDecoration(
border: const OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(5.0)),
),
contentPadding: const EdgeInsets.symmetric(vertical: 0.0),
labelText: widget.labelText,
prefixIcon: Icon(Icons.calendar_today),
suffixIcon: Icon(Icons.arrow_drop_down),
),
readOnly: true,
onTap: () {
_selectDate(context);
},
);
}
}
解决方案
您可以将 TextEditingController 作为 MyDateTimePicker 小部件的参数传递,如下所示:
class MyDateTimePicker extends StatefulWidget {
const MyDateTimePicker({
Key key,
this.labelText,
@required this.initialDate,
this.onValueChanged,
@required this.controller,
}) : super(key: key);
final String labelText;
final DateTime initialDate;
final ValueChanged<DateTime> onValueChanged;
final TextEditingController controller;
@override
MyDateTimePickerState createState() => MyDateTimePickerState();
}
class MyDateTimePickerState extends State<MyDateTimePicker> {
DateTime _selectedDate;
@override
void initState() {
super.initState();
_selectedDate = widget.initialDate;
widget.controller.text = DateFormat.yMMMd().format(_selectedDate);
}
// Called by the parent widget through a global key.
void setDate(DateTime date) {
_selectedDate = date;
widget.controller.text = DateFormat.yMMMd().format(_selectedDate);
}
Future<void> _selectDate(BuildContext context) async {
final DateTime picked = await showDatePicker(
context: context,
initialDate: _selectedDate,
firstDate: DateTime(1970, 8),
lastDate: DateTime(2101));
if (picked != null && picked != _selectedDate) {
_selectedDate = picked;
widget.controller.text = DateFormat.yMMMd().format(_selectedDate);
widget.onValueChanged(picked);
}
}
@override
Widget build(BuildContext context) {
return TextFormField(
controller: widget.controller,
decoration: InputDecoration(
border: const OutlineInputBorder(
borderRadius: BorderRadius.all(Radius.circular(5.0)),
),
contentPadding: const EdgeInsets.symmetric(vertical: 0.0),
labelText: widget.labelText,
prefixIcon: Icon(Icons.calendar_today),
suffixIcon: Icon(Icons.arrow_drop_down),
),
readOnly: true,
onTap: () {
_selectDate(context);
},
);
}
}
推荐阅读
- python - 根据一组值检查相等性
- c++ - 在视觉工作室中构建代码时,我面临错误,.h 文件丢失
- c - ffmpeg c api中的av_register_all()与avcodec_register_all()有什么区别?
- javascript - 如何从 javascript 中的变量创建对象属性?
- batch-file - 将数值转换回字母
- unity3d - 在 Unity 中使用 HiDPI 在 Mac 上获取 Retina 屏幕分辨率
- html - 调整窗口大小时将复选框位置保留在表单中
- nonlinear-optimization - R (NLOPTR - COBYLA) 非线性优化中的二元约束
- sql - 数据转换 Nvarchar 到 Money
- python - 文本分类 RNN - LSTM - 错误检查目标