简体   繁体   English

TextFormField“错误消息”打破了应用于文本字段的阴影

[英]TextFormField "error message" breaks the shadow applied to the Text Field

I made a TextField builder and customized it and added a shadow to it using "Material" widget And when an error message is shown to the user in the app the TextField gets pushed up but the shadow itself stays Where it was (code and picture included below)我制作了一个 TextField 构建器并对其进行了自定义,并使用“Material”小部件为其添加了阴影当在应用程序中向用户显示错误消息时,TextField 被向上推,但阴影本身保持在原来的位置(包括代码和图片以下)

import 'package:flutter/material.dart';
import 'constants.dart';

class TextFieldBuilder extends StatefulWidget {
  TextFieldBuilder({
    Key key,
    this.icon,
    this.hint,
    this.obscure,
    this.height,
    this.fontSize,
    this.iconSize,
    this.fillColor,
    this.hintFontSize,
    this.iconColor,
    this.validatorFunction,
    this.textInputType,
    this.initialValue,
    this.onSavedFunc,
  }) : super(key: key);
  final IconData icon;
  final String hint;
  final bool obscure;
  final height, fontSize, iconSize, fillColor, hintFontSize;
  final iconColor;
  final validatorFunction;
  final textInputType;
  final initialValue;
  final onSavedFunc;
  @override
  _TextFieldBuilderState createState() => _TextFieldBuilderState();
}

class _TextFieldBuilderState extends State<TextFieldBuilder> {
  var _data;
  @override
  Widget build(BuildContext context) {
    return Container(
      child: Material(
        color: Colors.transparent,
        borderRadius: BorderRadius.circular(9),
        child: Container(
          decoration:
              BoxDecoration(borderRadius: BorderRadius.circular(9), boxShadow: [
            BoxShadow(
              color: Colors.black.withOpacity(0.15),
              blurRadius: 4,
              offset: Offset(1, 3),
            )
          ]),
          child: TextFormField(
            autovalidateMode: AutovalidateMode.onUserInteraction,
            initialValue: widget.initialValue ?? null,
            keyboardType: widget.textInputType ?? null,
            onSaved: widget.onSavedFunc ??
                (String value) {
                  _data = value.trim();
                  if (widget.hint != password &&
                      widget.hint != 'Confirm Password') {
                    print('${widget.hint} is $_data');
                  }
                },
            validator: widget.validatorFunction,
            style: TextStyle(
              color: Color(textColor),
              fontSize: widget.fontSize ?? 18,
            ),
            obscureText: widget.obscure ?? false,
            decoration: InputDecoration(
              contentPadding: EdgeInsets.symmetric(vertical: 1.0),
              prefixIcon: Icon(
                widget.icon ?? Icons.error,
                size: widget.iconSize ?? 35,
                color: widget.iconColor ?? Color(iconColor),
              ),
              filled: true,
              fillColor: Color(textFieldColor),
              hintText: widget.hint ?? placeholder,
              hintStyle: TextStyle(
                color: Color(textColor),
                fontSize: widget.fontSize ?? 18,
                height: widget.height ?? 0.9,
              ),
              border: OutlineInputBorder(
                borderSide: BorderSide.none,
                borderRadius: BorderRadius.circular(9),
              ),
              focusColor: Color(textFieldColor),
            ),
          ),
        ),
      ),
    );
  }
}

I tried wrapping both widgets with a container but it did not seem to help我尝试用容器包装两个小部件,但似乎没有帮助在此处输入图像描述

Combine your TextField with a Text and place both inside a Column .将您的TextFieldText结合起来,并将两者都放在Column中。 You will be able to replicate the error display without messing up the shadow.您将能够复制错误显示而不会弄乱阴影。 Remember to hide the default error message as well.记住也要隐藏默认错误消息。

You can use the elevation and shadowColor property of Material to save some code lines btw.您可以使用MaterialelevationshadowColor属性来节省一些代码行。 Something like:就像是:

Material(
    color: Colors.transparent,
    borderRadius: BorderRadius.circular(9),
    elevation: 4,
    shadowColor: Colors.black.withOpacity(0.15),
    // ... other lines
);

Example code:示例代码:

// ... other lines

class _TextFieldBuilderState extends State<TextFieldBuilder> {
  var _data;
  String _errorText = '';

  @override
  Widget build(BuildContext context) {
    return Container(

      //!! Place both Widgets inside a Column
      child: Column( 
        mainAxisAlignment: MainAxisAlignment.center,
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          Material(
            color: Colors.transparent,
            borderRadius: BorderRadius.circular(9),
            child: Container(
              decoration: BoxDecoration(
                  borderRadius: BorderRadius.circular(9),
                  boxShadow: [
                    BoxShadow(
                      color: Colors.black.withOpacity(0.15),
                      blurRadius: 4,
                      offset: Offset(1, 3),
                    )
                  ]),
              child: TextFormField(
                autovalidateMode: AutovalidateMode.onUserInteraction,
                initialValue: widget.initialValue ?? null,
                keyboardType: widget.textInputType ?? null,
                onSaved: widget.onSavedFunc ??
                    (String value) {
                      _data = value.trim();
                      if (widget.hint != password &&
                          widget.hint != 'Confirm Password') {
                        print('${widget.hint} is $_data');
                      }
                    },

                //!! Set the errorText value here, the Future delayed is to avoid calling [setState] during [build]
                validator: (value) {
                  Future.delayed(Duration.zero, () { 
                  // calling [setState] during [build]
                    setState(() {
                      _errorText = widget.validatorFunction(value) ?? '';
                    });
                  });
                  return _errorText;
                },
                style: TextStyle(
                  color: Color(textColor),
                  fontSize: widget.fontSize ?? 18,
                ),
                obscureText: widget.obscure ?? false,
                decoration: InputDecoration(
                  contentPadding: EdgeInsets.symmetric(vertical: 1.0),
                  prefixIcon: Icon(
                    widget.icon ?? Icons.error,
                    size: widget.iconSize ?? 35,
                    color: widget.iconColor ?? Color(iconColor),
                  ),
                  filled: true,
                  fillColor: Color(textFieldColor),

                  //!! Hide the default error message here
                  errorStyle: TextStyle(fontSize: 0), 
                  hintText: widget.hint ?? placeholder,
                  hintStyle: TextStyle(
                    color: Color(textColor),
                    fontSize: widget.fontSize ?? 18,
                    height: widget.height ?? 0.9,
                  ),
                  border: OutlineInputBorder(
                    borderSide: BorderSide.none,
                    borderRadius: BorderRadius.circular(9),
                  ),
                  focusColor: Color(textFieldColor),
                ),
              ),
            ),
          ),

          //!! Display the error message here
          if (_errorText.isNotEmpty)
            Text(
              _errorText,
              style: TextStyle(color: Colors.red),
            )
        ],
      ),
    );
  }
}
  • Material color must be transparent -> color: Colors.transparent, Like @Bach Said,材质颜色必须透明->颜色:Colors.transparent,就像@Bach说的,
  • TextFormField error style font size should be 0 as @Bach said too, and the height property should be 1 -> errorStyle: TextStyle(fontSize: 0, height: 1)正如@Bach 所说,TextFormField 错误样式字体大小也应为 0,并且 height 属性应为 1 -> errorStyle: TextStyle(fontSize: 0, height: 1)

and show the error message in another widget并在另一个小部件中显示错误消息

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

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