简体   繁体   English

验证器错误消息更改 TextFormField 的高度

[英]Validator error message changes TextFormField's height

When the error message shows up, it reduces the height of the TextFormField .当错误消息出现时,它会降低TextFormField的高度。 If I understood correctly, that's because the height of the error message is taking into account in the height specified.如果我理解正确,那是因为错误消息的高度考虑到了指定的高度。

Here's a screen before :这是之前的屏幕:

前

and after :之后 :

后

Tried to put conterText: ' ' to the BoxDecoration (as I've seen on another topic) but it didn't help.试图将conterText: ' '放入 BoxDecoration (正如我在另一个主题上看到的那样),但它没有帮助。

An idea ?一个想法 ?

EDIT : OMG completly forgot to put the code, here it is :编辑:OMG 完全忘了放代码,这里是:

 return Form(
      key: _formKey,
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.center,
        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
        children: <Widget>[
          Container(
            height: 40.0,
            child: _createTextFormField(loginEmailController, Icons.alternate_email, "Email Adress", false, TextInputType.emailAddress),
          ),
          Container(
            height: 40.0,
            child: _createTextFormField(loginPasswordController, Icons.lock, "Password", true, TextInputType.text),
          ),

          SizedBox(
            width: double.infinity,
            child: loginButton
          )
        ],
      ),
    );

  }

  Widget _createTextFormField(TextEditingController controller, IconData icon, String hintText, bool obscureText, TextInputType inputType){
      return TextFormField(
        keyboardType: inputType,
        controller: controller,
        obscureText: obscureText,
        /* style: TextStyle(
          fontSize: 15.0,
        ), */
        decoration: InputDecoration(
         /*  contentPadding:
              EdgeInsets.symmetric(vertical: 5.0, horizontal: 8.0), */
          border: OutlineInputBorder(borderRadius: BorderRadius.circular(5.0)),
          icon: Icon(
            icon,
            color: Colors.black,
            size: 22.0,
          ),
          //hintText: hintText,
          labelText: hintText,
        ),
        validator: (value) {
          if (value.isEmpty) {
            return 'Enter some text';
          }
          return null;
        },
      );
    }

In your Code - you need to comment out the 40 height given to each container.在您的代码中 - 您需要注释掉每个容器的40高度。

Container(
             // height: 40.0,
              child: _createTextFormField(
                  loginEmailController,
                  Icons.alternate_email,
                  "Email Adress",
                  false,
                  TextInputType.emailAddress),
            ),
            Container(
            //  height: 40.0,
              child: _createTextFormField(loginPasswordController, Icons.lock,
                  "Password", true, TextInputType.text),
            ),

and then in your - TextFormField in InputDecoration , you can alter these value as per your liking.然后在InputDecoration中的 - TextFormField中,您可以根据自己的喜好更改这些值。

  contentPadding:
      EdgeInsets.symmetric(vertical: 10.0, horizontal: 10.0),

The problem is that we are not able to see your code so it might be challenging to assist you but I will do everything from scratch.问题是我们无法看到您的代码,因此帮助您可能具有挑战性,但我将从头开始做所有事情。 You can firstly create the authentication class in one dart file您可以先在一个 dart 文件中创建身份验证类

class AuthBloc{
   StreamController _passController = new StreamController();
   Stream get passStream => _passController.stream;
   bool isValid(String pass){
       _passController.sink.add("");
       if(pass == null || pass.length < 6){
         _passController.sink.addError("Password is too short");
         return false;
       }
       else{
         return true;
       }
    }

    void dispose(){
      _passController.close();    
     }
}

And then insert the following code in another dart file...然后在另一个 dart 文件中插入以下代码...

class LoginPage extends StatefulWidget{
  @override
  _LoginPageState createState() => _LoginPageState();
}
class _LoginPageState extends State<LoginPage>{
   AuthBloc authBloc = new AuthBloc();
   @override
   void dispose(){
     authBloc.dispose();
   }
   @override
   Widget build(BuildContext context){
     return Scaffold(
       body: Container(
         padding: EdgeInsets.fromLTRB(30, 0, 30, 0),
         constraints: BoxConstraints.expand(),
         children: <Widget>[
           Padding(
            padding: const EdgeInsets.fromLTRB(0, 40, 0, 20),
            child: StreamBuilder(
                stream: authBloc.passStream,
                builder: (context, snapshot) => TextField(
                  controller: _passController,
                  style: TextStyle(fontSize: 18, color: Colors.black),
                  decoration: InputDecoration(
                      errorText: snapshot.hasError ? snapshot.error:null,
                      labelText: "Password",
                      prefixIcon: Container(
                        width: 50,
                        child: Icon(Icons.lock),
                      ),
                      border: OutlineInputBorder(
                          borderSide: BorderSide(color: Color(0xffCED802), width: 1),
                          borderRadius: BorderRadius.all(Radius.circular(6))
                      )
                  ),
                ),
            )
          ),
          Padding(
            padding: const EdgeInsets.fromLTRB(0, 30, 0, 40),
            child: SizedBox(
              width: double.infinity,
              height: 52,
              child: RaisedButton(
                onPressed: _onLoginClicked,
                child: Text(
                  "Login",
                  style: TextStyle(fontSize: 18, color: Colors.white),
                ),
                color: Color(0xff327708),
                shape: RoundedRectangleBorder(
                    borderRadius: BorderRadius.all(Radius.circular(6))
                ),
              ),
            ),
          ),
         ]
       )
     )
   }
   _onLoginClicked(){
     var isValid = authBloc.isValid(_passController.text);
     if(isValid){
       //insert your action
     }
   }
}

I hope it works :)我希望它有效:)

The problem with content padding is that you cant decrease the size of the field to UI requirement with an emphasize on decrease but how ever the second answer helped me come with a solution for my perticular problem, so am sharing that内容填充的问题在于,您不能将字段的大小减小到 UI 要求,并强调减少,但是第二个答案如何帮助我为我的特定问题找到解决方案,所以我分享了

StreamBuilder(
                    stream: viewModel.outEmailError,
                    builder: (context, snap) {
                      return Container(
                        width: MediaQuery.of(context).size.width*.7,
                        height: (snap.hasData)?55:35,
                        child: AccountTextFormField(
                          "E-mail",
                          textInputType: TextInputType.emailAddress,
                          focusNode: viewModel.emailFocus,
                          controller: viewModel.emailController,
                          errorText: snap.data,
                          textCapitalization: TextCapitalization.none,
                          onFieldSubmitted: (_) {
                            nextFocus(viewModel.emailFocus,
                                viewModel.passwordFocus, context);
                          },
                        ),
                      );
                    }),

Above solutions did not work for me however I have figured out a very simple solution to avoid the above issue以上解决方案对我不起作用,但是我想出了一个非常简单的解决方案来避免上述问题

TextFormField(
    decoration: InputDecoration(
      **errorStyle: const TextStyle(fontSize: 0.01),**
      errorBorder: OutlineInputBorder(
        borderRadius: BorderRadius.circular(borderRadius),
        borderSide: const BorderSide(
          color: AppColor.neonRed,
          width: LayoutConstants.dimen_1,
          style: BorderStyle.solid,
        ),
      ),
   );

Catch in the above solution is that we are setting the size of the error message to 0.01 so as a result it don't show up.上述解决方案中的问题是我们将错误消息的大小设置为 0.01,因此它不显示。

Additionally we can have custom border for the error.此外,我们可以为错误设置自定义边框。

Note : Setting the Text size to 0 is not working as it don't consider the text size and textFormField widget gets shrinked.注意:将文本大小设置为 0 不起作用,因为它不考虑文本大小并且 textFormField 小部件被缩小。

Instead of using a fixed height container to wrap the textFormField, You can try to put a space in the helper text so it will keep the height of the field constant while only displaying when there is an error.您可以尝试在帮助文本中放置一个空格,而不是使用固定高度的容器来包装 textFormField,这样它将保持字段的高度不变,同时仅在出现错误时显示。

return TextFormField(
   // ...
   decoration: InputDecoration(
     // ...
     helperText: " ",
     helperStyle: <Your errorStyle>,
   )
        

According to Flutter Doc :根据颤振文档

To create a field whose height is fixed regardless of whether or not an error is displayed, either wrap the TextFormField in a fixed height parent like SizedBox, or set the InputDecoration.helperText parameter to a space.要创建一个高度固定的字段(无论是否显示错误),请将 TextFormField 包装在固定高度的父级(如 SizedBox)中,或将 InputDecoration.helperText 参数设置为空格。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM