如何验证脚手架中包含的 bottomSheet 内的表单?

Posted

技术标签:

【中文标题】如何验证脚手架中包含的 bottomSheet 内的表单?【英文标题】:How to validate a form inside the bottomSheet which is included in a Scaffold? 【发布时间】:2020-05-28 13:27:03 【问题描述】:

我想验证包含在 Scaffold 中的 bottomSheet 内的表单。

问题是当我关闭 bottomSheet 并单击“保存”(在 AppBar 中)时。

似乎最终形式 = _formAddPlayerKey.currentState; bottomSheet 关闭时返回 null。

当底部表打开时,我可以验证表单。

我的代码,里面有一个bottomSheet的脚手架:

return Scaffold(

      key: _scaffoldKey,
      appBar: AppBar(

        title: Text('MyTitle'),
        actions: <Widget>[
          //--- Form validation
          FlatButton(
            onPressed: () 
                  final form = _formAddPlayerKey.currentState;

              if (form.validate()) 
                form.save();

                print('SAV OK!!!');
              
            ,
            child: Text(
              'SAVE',
              style: Theme.of(context)
                  .textTheme
                  .subhead
                  .copyWith(color: Colors.white),
            ),
          )
        ],
      ),
      floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,
      floatingActionButton: 

          showFab
              ? FloatingActionButton(

                  child: const Icon(Icons.comment, color: Colors.white),
                  onPressed: () 
                    var bottomSheetController =
                        _scaffoldKey.currentState.showBottomSheet(
                      (context) => Container(
                        color: Colors.pink.withOpacity(
                            0.2), //Theme.of(context).accentColor.withOpacity(0.5),
                        //backgroundColor: Theme.of(context).accentColor.withOpacity(0.5),
                        height: MediaQuery.of(context).size.height,
                        width: MediaQuery.of(context).size.width,
                        child: Form(
                          key: _formAddPlayerKey,
                          child: Column(
                            mainAxisAlignment: MainAxisAlignment.start,
                            children: <Widget>[

                              SizedBox(
                                height: 10,
                              ),
                              Container(

                                color: Colors.white.withOpacity(0.5),

                                //Colors.white,
                                margin: EdgeInsets.all(16.0),
                                child: TextFormField(
                                  maxLines: 4,
                                  style: TextStyle(
                                    fontWeight: FontWeight.bold,
                                    fontSize: 30,
                                  ),
                                  decoration: InputDecoration(
                                    hoverColor: Colors.white,
                                    fillColor: Colors.white,
                                    labelText: 'Observation',
                                    border: OutlineInputBorder(),
                                    prefixIcon: Icon(Icons.note),
                                  ),
                                  keyboardType: TextInputType.text,
                                  initialValue:
                                      'My observation....',
                                  validator: (value) 
                                    return validateMyValue(value);
                                  ,
                                  onSaved: (value) =>
                                      _MyValue = value,
                                ),
                              ),
                            ],
                          ),
                        ),
                      ),
                    );

                    showFoatingActionButton(false);

                    /// close ?



                    bottomSheetController.closed.then((value) 
                      showFoatingActionButton(true);
                    );
                  )
              : Container(),

      bottomNavigationBar: _buildBottomNavigationBar(context),
      body: _buildBody(context),
    );
  

  void showFoatingActionButton(bool value) 
    setState(() 
      showFab = value;
    );
  

【问题讨论】:

【参考方案1】:

只需全局定义表单键,即在 State 类中

var _formAddPlayerKey = GlobalKey<FormState>();

每当您想使用相应的键验证您的表单时,您只需要输入这个,

bool validate = _formAddPlayerKey.currentState.validate();

如果布尔变量 validate 为 true,则您的表单符合标记,如果验证失败,它会自动设置您已在 TextFormField 小部件的 validate 属性中定义的错误消息

【讨论】:

谢谢你的回答(我已经按照你的建议全局定义了密钥,我将编辑代码)但是问题仍然存在,当 bottonSheet 关闭时,当 onPressed 被执行时(当我点击时)我有这个错误: Validate() is called on null... 似乎 bottonSheet 内的表单在关闭 bottonSheet 时被破坏,所以表单为 null,键为 null 和 formstate 的 validate() 方法表单在 null 上调用...... 是的,如果视图与屏幕分离,它会破坏视图的当前状态,以验证您可以像这样在关闭 BottomSheet 时保存 FormState,_formAddPlayerKey.save(); 感谢您回复 Yogesh。我做了一些测试,最后我选择不将 BottomSheet 用于我的 UI,因为它不想练习。

以上是关于如何验证脚手架中包含的 bottomSheet 内的表单?的主要内容,如果未能解决你的问题,请参考以下文章

使用签名中包含的密钥正确验证了签名,但该密钥不受信任

签名使用签名中包含的密钥正确验证,但该密钥不受信任

在代码中访问.webtestResult文件中包含的信息

jQuery:像应用商店中包含的 ios 滚动框一样滚动

从我的项目中包含的 jar 调用属性文件

如何获取 NSFontCollection 中包含的字体数组?