定制Flutter响应式TextFormField:聚焦时切换背景色
自定义响应式TextFormField组件(带焦点背景色切换)
以下是完全符合需求的自定义组件实现,它保留了原生TextFormField的所有可配置属性,支持响应式布局,并且会在获得焦点时切换背景色,样式与你提供的空/填充状态示例匹配:
完整组件代码
import 'package:flutter/material.dart'; class CustomStyledTextFormField extends StatefulWidget { // 继承原生TextFormField的所有核心参数 final TextInputType? keyboardType; final String? hintText; final TextEditingController? controller; final String? Function(String?)? validator; final void Function(String)? onChanged; final InputDecoration? decoration; final TextStyle? style; // 自定义可选参数:设置焦点前后的背景色 final Color unfocusedBgColor; final Color focusedBgColor; const CustomStyledTextFormField({ super.key, this.keyboardType, this.hintText, this.controller, this.validator, this.onChanged, this.decoration, this.style, this.unfocusedBgColor = const Color(0xFFF5F5F5), this.focusedBgColor = const Color(0xFFE8F0FE), }); @override State<CustomStyledTextFormField> createState() => _CustomStyledTextFormFieldState(); } class _CustomStyledTextFormFieldState extends State<CustomStyledTextFormField> { late FocusNode _focusNode; bool _hasFocus = false; @override void initState() { super.initState(); _focusNode = FocusNode(); // 监听焦点变化状态 _focusNode.addListener(() { setState(() { _hasFocus = _focusNode.hasFocus; }); }); } @override void dispose() { _focusNode.dispose(); super.dispose(); } @override Widget build(BuildContext context) { // 响应式适配:根据屏幕尺寸动态调整样式参数 final screenWidth = MediaQuery.of(context).size.width; final borderRadius = screenWidth * 0.02; final contentPadding = EdgeInsets.symmetric( horizontal: screenWidth * 0.04, vertical: screenWidth * 0.03, ); return TextFormField( focusNode: _focusNode, keyboardType: widget.keyboardType, controller: widget.controller, validator: widget.validator, onChanged: widget.onChanged, style: widget.style ?? TextStyle(fontSize: screenWidth * 0.04), decoration: widget.decoration ?? InputDecoration( hintText: widget.hintText, hintStyle: TextStyle(color: Colors.grey[500], fontSize: screenWidth * 0.04), filled: true, // 根据焦点状态切换背景色 fillColor: _hasFocus ? widget.focusedBgColor : widget.unfocusedBgColor, border: OutlineInputBorder( borderRadius: BorderRadius.circular(borderRadius), borderSide: BorderSide.none, ), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(borderRadius), borderSide: BorderSide.none, ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(borderRadius), borderSide: BorderSide(color: Colors.blue[300]!, width: 1.5), ), contentPadding: contentPadding, ), ); } }
组件使用示例
// 完全兼容原生TextFormField的调用方式 CustomStyledTextFormField( keyboardType: TextInputType.emailAddress, hintText: '输入你的邮箱', validator: (value) { if (value == null || value.isEmpty) { return '请输入邮箱'; } return null; }, )
关键特性说明
- 原生属性全兼容:组件接收并传递
TextFormField的所有核心参数,完全保留原生组件的校验、输入控制等功能 - 焦点背景色切换:通过
FocusNode监听焦点状态,自动切换填充背景色 - 响应式布局:基于
MediaQuery获取屏幕尺寸,动态调整圆角、内边距、字体大小,适配不同设备 - 样式可自定义:默认样式匹配空/填充状态示例,也可通过参数修改背景色、边框样式等
内容的提问来源于stack exchange,提问作者Mohammed
相关产品推荐
相关产品推荐

