簡體   English   中英

在顫振中,如何為 textformfield 自定義樣式錯誤消息?

[英]In flutter, how to custom style error messages for textformfield?

我的 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('')),
                ],
              ),
            ),
          ),
        ),
      ),
    );
  }),
);

}

首先,每個字段需要 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)

您可以通過維護一列 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),
        )),
  ],
);

您可以刪除包裝容器並將您的文本表單設置為您的容器。 這樣,錯誤消息將顯示在灰色區域框之外。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM