【问题标题】:Flutter Form Widget Won't Show Text or KeyboardFlutter 表单小部件不显示文本或键盘
【发布时间】:2018-11-24 16:17:35
【问题描述】:

我有一个表单,里面有很多 TextFormFields 和(目前)一个 DropDownButton。

当我点击其中一个 TextFormFields 时,键盘会闪烁,但不会停留。我发现的唯一解决方法是开始在我的计算机键盘上键入以使电话键盘自行弹出 - 显然不是在任何地方键入 - 然后,当键盘已经启动时,点击 TextFormField 然后我能够输入文本,但是一旦我点击该字段,输入的文本就会消失。此创可贴对除名称以外的所有字段都无效,因为它们的键盘类型是数字键盘。因此,由于既不输入字母也不输入数字会在手机上调用此键盘,因此不可能让键盘实现这些字段。

我确信 Form 是问题所在,因为在相同的分层情况下,如果我将 Padding 的子项更改为直接转到相同的 ListView,所有 TextFormField 问题都会消失。

我选择不包含我的 DropDownButton 问题的相关代码,因为它可能是不相关的,因为这是我暂时删除表单小部件时唯一无法解决的问题。

Keyboard will not pop

With temporary workaround, entered text still will not remain after exiting field

DropDownButton wont display selected value

class NewPage extends MaterialPageRoute<Null>{
 final formKey = GlobalKey<FormState>();
 String _name;

 void _submit(){
  final form = formKey.currentState;
  if(form.validate()){
   form.save();
   print("$_name");
  }
 }
 final name = TextFormField(
  //all other TextFormFields are declared as name is
  validator: (val) =>
   val.isEmpty? "Name can't be empty.': null,
  onSaved: (val) => _name = val,
  decoration: InputDecoration(
   labelText: "Name",
   labelStyle: TextStyle(
    fontSize: 20.0,
   ),
   contentPadding: EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 12.0),
   border: OutlineInputBorder(
    borderRadius: BorderRadius.circular(20.0),
   )
  )
 );
 final age = TextFormField(
  keyboardType: TextInputType.number,
  validator: null,
  decoration: InputDecoration(
   labelText: "Age",
   labelStyle: TextStyle(
    fontSize: 20.0,
   ),
   contentPadding: EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 12.0),
   border: OutlineInputBorder(
    borderRadius: BorderRadius.circular(20.0),
   )
  ),
 );
 return Scaffold(
  body: Padding(
   padding: EdgeInsets.symmetric(horizontal: 20.0),
   child: new Form(
    key: formKey,
     child: new ListView(
      children: <Widget> [
       SizedBox(height: 100.0),
       name,
       SizedBox(height: 20.0),
       new Text("Sex:"),
       sex,
       SizedBox(height: 20.0),
       age,
       //and so on
       new RaisedButton(
        onPressed: _submit,
        child: new Text("Go"),
       ),
      ],
     ),
   ),
  ),
 );
}

【问题讨论】:

    标签: android ios dart flutter flutter-layout


    【解决方案1】:

    我认为问题可能源于class NewPage extends MaterialPageRoute&lt;Null&gt;。除非你正在创建一个新的路由子类来显着改变路由的行为,否则你不应该从它扩展 - 如果你正在扩展它,那将是在你深入了解颤振的工作原理之后。

    我相信您要做的是扩展 StatefulWidget 并创建相应的 State。如果您出于某种原因需要制作路线,您仍然可以传入一个可以满足您需要的构建器,即new MaterialPageRoute(builder: (context) =&gt; new NewPage())。

    当我在模拟器中运行它时,这对我有用。我也添加到下拉列表中只是为了好玩=D。

    import 'package:flutter/material.dart';
    import 'package:flutter/widgets.dart';
    
    void main() => runApp(new MaterialApp(home: new NewPage()));
    
    class NewPage extends StatefulWidget {
      @override
      State<StatefulWidget> createState() => new NewPageState();
    }
    
    class NewPageState extends State<NewPage> {
      final formKey = GlobalKey<FormState>();
      String _name;
    
      String _sex;
    
      void _submit() {
        final form = formKey.currentState;
        if (form.validate()) {
          form.save();
          print("$_name");
        }
      }
    
      @override
      Widget build(BuildContext context) {
        final name = TextFormField(
          //all other TextFormFields are declared as name is
          validator: (val) => val.isEmpty ? "Name can't be empty." : null,
          onSaved: (val) => _name = val,
          decoration: InputDecoration(
            labelText: "Name",
            labelStyle: TextStyle(
              fontSize: 20.0,
            ),
            contentPadding: EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 12.0),
            border: OutlineInputBorder(
              borderRadius: BorderRadius.circular(20.0),
            ),
          ),
        );
        final age = TextFormField(
          keyboardType: TextInputType.number,
          validator: null,
          decoration: InputDecoration(
            labelText: "Age",
            labelStyle: TextStyle(
              fontSize: 20.0,
            ),
            contentPadding: EdgeInsets.fromLTRB(20.0, 15.0, 20.0, 12.0),
            border: OutlineInputBorder(
              borderRadius: BorderRadius.circular(20.0),
            ),
          ),
        );
        final sex = DropdownButton(
          items: [
            new DropdownMenuItem(child: new Text("Male"), value: "male"),
            new DropdownMenuItem(child: new Text("Female"), value: "female"),
            new DropdownMenuItem(child: new Text("Other"), value: "other"),
          ],
          onChanged: (val) => setState(() => _sex = val),
          value: _sex,
        );
        return new Scaffold(
          body: Padding(
            padding: EdgeInsets.symmetric(horizontal: 20.0),
            child: new Form(
              key: formKey,
              child: new ListView(
                children: <Widget>[
                  SizedBox(height: 100.0),
                  name,
                  SizedBox(height: 20.0),
                  new Text("Sex:"),
                  sex,
                  SizedBox(height: 20.0),
                  age,
                  //and so on
                  new RaisedButton(
                    onPressed: _submit,
                    child: new Text("Go"),
                  ),
                ],
              ),
            ),
          ),
        );
      }
    }
    

    如果这不能解决问题,一些额外的信息(例如您使用的设备)会有所帮助。此外,发布一个实际编译的代码示例将帮助我们帮助您 - 我建议在下次发布问题之前检查一下。

    【讨论】:

      【解决方案2】:

      不要将所有TextFormFields 包装在同一个表单中。这不是一个好的做法,会导致很多问题。

      单独包装每个字段并确保使用不同的键。分别验证它们。并尝试使用onChanged 方法或onEditingComplete 方法立即保存字符串,而不是onSaved 方法。

      另外,只有当值有效时,您才保存该值。不要那样做,这可能是问题所在。

      【讨论】:

        猜你喜欢
        • 2021-08-01
        • 2020-04-29
        • 1970-01-01
        • 2011-10-08
        • 2022-01-11
        • 2020-10-31
        • 2022-10-21
        • 2020-12-11
        • 2015-09-10
        相关资源
        最近更新 更多