根据“来自确认”变更 Flutter TextFormField后缀图标颜色

dwbf0jvd  于 2022-12-19  发布在  Flutter
关注(0)|答案(2)|浏览(136)

我正在尝试创建一个覆盖小部件的TextFormField后缀图标。通常我们会使用工具提示,但只是尝试一些新的东西,因为覆盖小部件可以自定义。我想改变后缀图标颜色的TextFormField,如果它没有得到验证,从灰色到红色。所以当图标变成红色,它提醒用户有什么是错误的,当用户点击它覆盖小部件将显示。
我的覆迭程式码Widget。

void _showOverlay(BuildContext context) async {
    OverlayState? overlayState = Overlay.of(context);
    OverlayEntry overlayEntry;
    overlayEntry = OverlayEntry(builder: (context) {
      return Positioned(
        left: MediaQuery.of(context).size.width * 0.1,
        top: MediaQuery.of(context).size.height * 0.23,
        child: ClipRRect(
          borderRadius: BorderRadius.circular(10),
          child: Material(
            child: Container(
              alignment: Alignment.center,
              color: Colors.grey.shade200,
              padding:
                  EdgeInsets.all(MediaQuery.of(context).size.height * 0.02),
              width: MediaQuery.of(context).size.width * 0.8,
              height: MediaQuery.of(context).size.height * 0.06,
              child: const Text(
                'Name should be more than 2 characters',
                style: TextStyle(color: Colors.black),
              ),
            ),
          ),
        ),
      );
    });
    overlayState!.insert(overlayEntry);

    await Future.delayed(const Duration(seconds: 3));

    overlayEntry.remove();
  }

我的提交按钮方法:

void _submitForm() {
    setState(() {
      _autoValidateMode = AutovalidateMode.always;
    });
    final form = _formKey.currentState;
    if (form == null || !form.validate()) return;

    form.save();
    print(_name);
  }

我的文本表单字段构件:

TextFormField(
                  controller: nameController,
                  keyboardType: TextInputType.name,
                  textInputAction: TextInputAction.next,
                  textCapitalization: TextCapitalization.words,
                  validator: (String? value) {
                    if (value == null || value.trim().isEmpty) {
                      return;
                    }
                    return null;
                  },
                  onSaved: (String? value) {
                    _name = value;
                  },
                  decoration: kTextInputDecoration.copyWith(
                      labelText: 'Full Name',
                      prefixIcon: const Icon(Icons.person),
                      suffixIcon: IconButton(
                          padding: EdgeInsets.zero,
                          onPressed: () {
                            _showOverlay(context);
                          },
                          icon: const Icon(
                            Icons.info,
                            color: Colors.grey //change icon color according to form validation 
                          ))),

我的提交按钮。

ElevatedButton(
                    onPressed: () {
                      _submitForm();
                    },
                    style: ElevatedButton.styleFrom(
                        padding: const EdgeInsets.all(10)),
                    child: const Text(
                      'Submit',
                      style: TextStyle(fontSize: 20),
                    )),

我想改变的颜色后缀图标的颜色时,提交按钮被按下。如果该形式是没有验证的颜色应该改变为红色或默认为灰色。非常感谢您提前为您的帮助。

hrirmatl

hrirmatl1#

警告:下面的解决方案目前在稳定通道3.3.9上被破坏,但在beta版中运行良好。
issue在2022年8月23日被标记为已修复,因此我非常希望我们很快就能让它稳定下来。
您可以:
1.创建一个扩展MaterialStateColor的类
1.基于主题在生成方法中创建示例
1.将示例传递给suffixIconColor

class InfoIconColor extends MaterialStateColor {
  const InfoIconColor(
    super.defaultColor, {
    required this.disabledColor,
    required this.errorColor,
  });

  final Color disabledColor;
  final Color errorColor;

  @override
  Color resolve(Set<MaterialState> states) {
    if (states.contains(MaterialState.error)) return errorColor;
    if (states.contains(MaterialState.disabled)) return disabledColor;
    return Color(super.value);
  }
}

TextFormField(
  // ...
  decoration: kTextInputDecoration.copyWith(
    labelText: 'Full Name',
    suffixIcon: // ...
    suffixIconColor: // ...
  ),
)

同时,您可以在应用主题中使用相同的InfoIconColor(或使用主题微件 Package 微件),如下所示:

final theme = Theme.of(context); 
Theme(
  data: theme.copyWith(
    inputDecorationTheme: theme.inputDecorationTheme.copyWith(
      suffixIconColor: //...
    ),
  ),
  child: //...
)
hsgswve4

hsgswve42#

您可以创建bool来存储验证或直接使用validate方法。

///state level
  bool _isValidate = true;
  ......
 /// inside TextFormField
validator: (String? value) {
  if (value == null || value.trim().isEmpty) {
    setState(() {
      _isValidate = false;
    });
    return "Error message";
  }
  return null;
},

onTap: () {
  setState(() {
    _isValidate = true;
  });
},

/// and Icon color 
icon: Icon(
  Icons.info,
  color: _isValidate ? Colors.grey : Colors.red,
),

相关问题