【问题标题】:In flutter, how to custom style error messages for textformfield?在颤振中,如何为 textformfield 自定义样式错误消息?
【发布时间】:2022-07-05 04:48:16
【问题描述】:

我的 textformfield 的样式是用灰色包装容器包装的,以便在该字段处于焦点时看起来不同。但是,每当出现错误消息时,它就会变得臃肿(大小增加),因为该字段是用那个灰色的包装容器包装的。

如何在灰色包装容器之外自定义错误消息的样式,以使 textformfield 的大小不会膨胀?

基本上我希望错误消息位于包装容器的灰色之外。

@override Widget build(BuildContext context) {
final InputDecorationTheme inputTheme = Theme.of(context).inputDecorationTheme;

return Focus(
  canRequestFocus: false,
  child: Builder(builder: (context) {
    final FocusNode focusNode = Focus.of(context);
    final bool hasFocus = focusNode.hasFocus;
    return GestureDetector(
      onTap: () {
        if (hasFocus) {
          focusNode.unfocus();
        } else {
          focusNode.requestFocus();
        }
      },
      child: Container(
        decoration: BoxDecoration(
          color: hasFocus ? Colors.white : Color(0xFFF4F4F4),
          border: hasFocus
              ? Border.all(color: Color(0xFF0E4DA4), width: 2)
              : Border.all(width: 2, color: Colors.transparent),
          borderRadius: const BorderRadius.all(Radius.circular(5)),
          boxShadow: hasFocus
              ? [
                  BoxShadow(
                    color: Color(0xFFF4F4F4),
                    spreadRadius: 3,
                    blurRadius: 0,
                    offset: Offset(0, 0), // changes position of shadow
                  ),
                ]
              : [],
        ),
        child: TextFormField(
          enabled: enabled,
          key: this.customKey,
          controller: textEditingController,
          initialValue: initialValue,
          inputFormatters: isNumericalOnly
              ? [
                  FilteringTextInputFormatter.digitsOnly,
                  FilteringTextInputFormatter.singleLineFormatter,
                ]
              : [
                  FilteringTextInputFormatter.singleLineFormatter,
                ],
          keyboardType: isNumericalOnly ? TextInputType.number : TextInputType.text,
          focusNode: focusNodeToggle,
          maxLength: maxLength,
          validator: (String? value) {
            return validator != null ? validator!(value.toString()) : null;
          },
          onSaved: (String? value) {
            return onSaved != null ? onSaved!(value.toString()) : null;
          },
          onChanged: (String? value) {
            return onChanged != null ? onChanged!(value.toString()) : null;
          },
          buildCounter: maxLength != null && isCounterVisible == true
              ? (BuildContext context, {int? currentLength, int? maxLength, bool? isFocused}) =>
                  Container(child: Text('$currentLength/$maxLength'))
              : (BuildContext context, {int? currentLength, int? maxLength, bool? isFocused}) =>
                  null,
          decoration: InputDecoration(
            floatingLabelBehavior: FloatingLabelBehavior.auto,
            hintText: customHintText,
            helperText: customHelperText,
            helperMaxLines: 2,
            filled: true,
            fillColor: Colors.transparent,
            border: InputBorder.none,
            focusedBorder: InputBorder.none,
            enabledBorder: InputBorder.none,
            errorBorder: InputBorder.none,
            disabledBorder: InputBorder.none,
            labelStyle: hasFocus ? inputTheme.labelStyle : TextStyle(color: Color(0xFF525252)),
            label: Text.rich(
              TextSpan(
                children: <InlineSpan>[
                  WidgetSpan(
                    child: Text(
                      label.toString(),
                    ),
                  ),
                  WidgetSpan(
                      child: isDataloading
                          ? LoadingIndicator(
                              width: 15,
                              height: 15,
                            )
                          : Text('')),
                ],
              ),
            ),
          ),
        ),
      ),
    );
  }),
);

}

【问题讨论】:

  • @7mada 不,我想将错误消息定位在包装容器之外,而不仅仅是设置文本外观的样式。
  • 您需要使用 bool 和 Text 小部件管理自定义验证,并在点击您提交的小部件时设置条件

标签: flutter dart flutter-layout flutter-web


【解决方案1】:

首先,每个字段需要 1 个字符串

String nameError = '';

现在你需要为这个字段创建验证函数,比如

void invalidName() {
    nameError = "Enter name";
  }

现在您需要创建可以检查所有验证的函数

    bool validateInput() {
        try {
          if (email.isNotEmpty) {
            return true;
          } else {
            if (nameController.text.isEmpty) { // Here check your controller value
              invalidName(); // here define validation error
              ...
              ...
            }
            return false;
          }
        } catch (e) {
          return false;
        }
      }

现在你只需要在你的按钮中调用 validateInput() 函数,如果它返回 true 然后调用你 api 或其他方式在文本字段下方显示错误,如下所示

nameError == '' ? SizedBox() : Text(nameError)

【讨论】:

    【解决方案2】:

    您可以通过维护一列 TextFormField 和 Text Widget(用于显示错误消息)来做到这一点。你可以这样做。

    final FocusNode focusNode = Focus.of(context);
    final bool hasFocus = focusNode.hasFocus;
    
    Column(
      children: [
        Container(
          margin: EdgeInsets.symmetric(horizontal: 20.0),
          child: TextFormField(
            focusNode: focusNode,
            onFieldSubmitted: (v) {
              FocusScope.of(context).requestFocus(focus);
            },
            textInputAction: TextInputAction.next,
            controller: , //your controller
            autofocus: false,
            decoration: InputDecoration(
              hintText: "sample text*",
              errorStyle: TextStyle(color: Colors.red),
              hintStyle: TextStyle(
                  fontSize: 20,
                  color: Colors.grey),
              border: OutlineInputBorder(
                borderRadius:
                    BorderRadius.circular(5),
                borderSide: BorderSide(
                    //color: Colors.amber,
                    ),
              ),
              enabledBorder: OutlineInputBorder(
                borderRadius:
                    BorderRadius.circular(5),
                borderSide:
                    BorderSide(width: 1, color: Colors.black),
              ),
            ),
            style: TextStyle(
              fontSize: 20,
              color: Colors.black,
            ),
          ),
        ),
        SizedBox(
          height: 5,
        ),
        Visibility(
            visible: hasFocus,
            child: Text(
              'Required field, it cannot be empty',
              style: TextStyle(color: Color.red),
            )),
      ],
    );
    

    【讨论】:

      【解决方案3】:

      您可以删除包装容器并将您的文本表单设置为您的容器。 这样错误信息就会显示在灰色区域框之外。

      【讨论】:

        猜你喜欢
        • 2019-05-31
        • 2019-02-07
        • 1970-01-01
        • 2020-10-13
        • 1970-01-01
        • 1970-01-01
        • 2020-11-01
        • 1970-01-01
        • 2020-11-01
        相关资源
        最近更新 更多