【问题标题】:Change Flutter TextFormField suffix Icon Colors accoding to From Validation根据表单验证更改 Flutter TextFormField 后缀图标颜色
【发布时间】:2022-12-15 13:00:14
【问题描述】:

我正在尝试为 TextFormField 后缀图标创建一个覆盖小部件。通常我们会使用工具提示,但只是尝试一些新的东西,因为覆盖小部件可以自定义。如果未通过验证,我想将 TextFormField 的后缀图标颜色从灰色更改为红色。因此,当图标变为红色时,它会提醒用户出现问题,当用户单击它时,将显示覆盖小部件。
我的 OverLay 小部件代码。

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 小部件:

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),
                    )),  

我想在按下提交按钮时更改后缀图标颜色的颜色。如果表单未通过验证,颜色应更改为红色或默认为灰色。非常感谢您的帮助。

【问题讨论】:

  • 你能为文本字段包含简化的完整小部件吗?
  • @YeasinSheikh 对不起,我没听懂你的意思。
  • 我正在考虑一个没有 kTextInputDecoration 的完整小部件,它也将包括表单小部件。

标签: flutter colors widget suffix


【解决方案1】:

警告:以下解决方案目前在稳定频道 3.3.9 上已损坏,但在测试版中运行良好。
issue 已于 2022 年 8 月 23 日标记为已修复,因此我非常希望我们能尽快将其稳定下来。

你可以:

  1. 创建一个扩展MaterialStateColor的类
  2. 根据您的主题在构建方法中创建一个实例
  3. 将实例传递给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: // ...
      ),
    )  
    

【讨论】:

    【解决方案2】:

    您可以创建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,
    ),
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-10-07
      • 2021-08-07
      • 1970-01-01
      • 1970-01-01
      • 2014-07-20
      • 2019-11-05
      • 2023-03-26
      相关资源
      最近更新 更多