首页 > 解决方案 > 在不是 TextFormField 的颤动中验证属性的值

问题描述

这是我在 StackOverFlow 上提出的第一个问题,所以我将尽我所能做到尽可能简洁明了。

我正在尝试验证DateTimePicker颤动中的一个字段,以本质上将按钮的颜色更改为红色,如果单击提交按钮时未选择时间,则向用户显示错误。我遇到的唯一解决方案与TextFormField验证和输入验证有关。由于从DateTimePickerIS NOT a生成的输出TextFormField并且我无权访问验证器功能,因此我试图提出一个解决方案,允许我startTime在单击提交按钮时仍然验证选择。

我想出的一种解决方案是将我的_buildStartEndButtons函数包装在一个 if 语句中,如果startTime值为 null,则返回一个红色按钮,如果选择了时间,则返回黑色。但是,这并不能解决我仅在单击提交按钮且用户未输入任何内容时才向用户显示错误的问题。我当前的解决方案不能带来非常友好的用户体验。我只是很难理解如何将我的startTime财产状态传递给我的提交按钮。

菜单模型小部件:

class MenuModel {
  String startTime;
  String endTime;
}

小时小部件:

  class DateTimePicker extends StatelessWidget {
  MenuModel menu;
  Function updateStartTime;
  Function updateEndTime;

  DateTimePicker(
    this.menu,
    this.updateStartTime,
    this.updateEndTime,
  );

  @override
  Widget build(BuildContext context) {
    return Column(
      children: <Widget>[
        Container(
          padding: EdgeInsets.all(10.0),
          margin: EdgeInsets.symmetric(horizontal: 15, vertical: 15),
          child: Text(
            'What are the hours?',
            style: TextStyle(fontSize: 18),
          ),
        ),
        Container(
          padding: EdgeInsets.symmetric(horizontal: 15, vertical: 15),
          child: Column(
            children: <Widget>[
              _buildTimeRange(
                  starts: this.menu.startTime, ends: this.menu.endTime),
              _buildStartEndButtons(context),
            ],
          ),
        ),
      ],
    );

  Container _buildStartEndButtons(BuildContext context) {
    String errorMsg = 'Please select a time';

    if (this.menu.startTime == null) {
      return Container(
        child: Row(
          children: <Widget>[
            Expanded(
              child: RaisedButton(
                color: Colors.red,
                onPressed: () {
                  DatePicker.showTimePicker(context,
                      theme: DatePickerTheme(containerHeight: 200.0),
                      showTitleActions: true, onConfirm: (time) {
                    print('confirm $time');
                    this.updateStartTime('${time.hour} : ${time.minute}');
                  }, currentTime: DateTime.now(), locale: LocaleType.en);
                },
                child: Text(
                  'Starts',
                  style: TextStyle(color: Colors.white),
                ),
              ),
            ),
    } else {
      return Container(
        child: Row(
          children: <Widget>[
            Expanded(
              child: RaisedButton(
                color: Colors.black,
                onPressed: () {
                  DatePicker.showTimePicker(context,
                      theme: DatePickerTheme(containerHeight: 200.0),
                      showTitleActions: true, onConfirm: (time) {
                    print('confirm $time');
                    this.updateStartTime('${time.hour} : ${time.minute}');
                  }, currentTime: DateTime.now(), locale: LocaleType.en);
                },
                child: Text(
                  'Starts',
                  style: TextStyle(color: Colors.white),
                ),
              ),
            ),
          ],
        ),
      );
    }
  }
  Container _buildTimeRange({String starts, String ends}) {
    if (starts == null || starts.isEmpty) {
      starts = '';
    }
    if (ends == null || ends.isEmpty) {
      ends = '';
    }

    return Container(
      padding: EdgeInsets.symmetric(vertical: 15),
      child: Row(
        mainAxisAlignment: MainAxisAlignment.spaceAround,
        children: <Widget>[
          Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: <Widget>[
              Container(
                child: Text(
                  'Starts',
                  style: TextStyle(fontWeight: FontWeight.w500),
                ),
              ),
              Container(
                child: Text(
                  starts,
                  style: TextStyle(fontWeight: FontWeight.w500),
                ),
              ),
            ],
          ),
          Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: <Widget>[
              Container(
                child: Text(
                  'Ends',
                  style: TextStyle(fontWeight: FontWeight.w500),
                ),
              ),
              Container(
                child: Text(
                  ends,
                  style: TextStyle(fontWeight: FontWeight.w500),
                ),
              ),
            ],
          ),
        ],
      ),
    );
  }
}

AddMenuView 小部件:

class AddMenuView extends StatefulWidget {
  AddMenuView({Key key}) : super(key: key);

  _AddMenuViewState createState() => _AddMenuViewState();
}
class _AddMenuViewState extends State<AddMenuView> {
  MenuModel menu;

 void updateStartTime(String start) {   
    setState(() {
      this.menu.startTime = start;
    });
  }

return Scaffold(
      appBar: AppBar(
        title: Text('Restaurant Information'),
      ),
      body: Container(
        decoration: BoxDecoration(color: Colors.white54),
        padding: EdgeInsets.symmetric(horizontal: 15, vertical: 15),
        child: (Column(children: <Widget>[

      Container(
            child: DateTimePicker(menu, updateStartTime, updateEndTime),
            margin: EdgeInsets.all(10.0),
            decoration: BoxDecoration(
              boxShadow: [
                BoxShadow(
                  color: color,
                ),
              ],
              border: Border.all(color: Colors.black),
              borderRadius: BorderRadius.all(
                Radius.circular(25.0),
              ),
            ),
          ),

      FlatButton(
            color: Colors.black,
            child: Text(
              'Submit',
              style: TextStyle(color: Colors.white),
            ),
            onPressed: () {
              this.menu.startTime.isEmpty ? print('Value needed') : print('Value exists');
         },
          )
        ])),
      ),
    );
  }
}

旁注:暂时忽略该endTime属性。我只是将其分解为startTimeStackOverFlow 上的属性提出一个解决方案,以便我可以自己找出我的第二个问题。

感谢你们抽出时间来帮助我,如果对我在这里想要完成的工作不完全清楚,请询问,我会尽我所能进一步详细说明!

标签: validationflutterconditional-statements

解决方案


推荐阅读