Flutter中如何在onChanged时根据验证动态修改TextField边框颜色?
Flutter 实时验证输入并动态修改 TextField 边框颜色
核心逻辑很明确:监听输入内容变化,实时执行邮箱/手机号规则验证,根据验证结果更新状态,最终同步到 TextField 的边框样式上。下面是三种主流状态管理方案的落地实现:
一、GetX 实现
1. 编写 GetX 控制器
import 'package:get/get.dart'; class InputController extends GetxController { final RxString inputText = ''.obs; bool isEmailMode = true; // 可根据业务场景切换验证模式 final RegExp emailRegex = RegExp(r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$'); Color get borderColor { if (isEmailMode) { return emailRegex.hasMatch(inputText.value) ? Colors.white : Colors.red; } else { return inputText.value.length == 10 ? Colors.white : Colors.red; } } void updateInput(String text) { inputText.value = text; } void toggleMode() { isEmailMode = !isEmailMode; update(); } }
2. UI 层集成
import 'package:flutter/material.dart'; import 'package:get/get.dart'; class InputPage extends StatelessWidget { final InputController controller = Get.put(InputController()); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( actions: [ Obx(() => TextButton( onPressed: controller.toggleMode, child: Text(controller.isEmailMode ? '切换到手机号' : '切换到邮箱'), )) ], ), body: Padding( padding: const EdgeInsets.all(16.0), child: Obx( () => TextField( onChanged: controller.updateInput, decoration: InputDecoration( border: OutlineInputBorder( borderSide: BorderSide(color: controller.borderColor), ), focusedBorder: OutlineInputBorder( borderSide: BorderSide(color: controller.borderColor), ), hintText: controller.isEmailMode ? '输入邮箱' : '输入手机号', ), ), ), ), ); } }
二、Provider 实现
1. 创建 ChangeNotifier 类
import 'package:flutter/material.dart'; class InputProvider extends ChangeNotifier { String _inputText = ''; bool isEmailMode = true; final RegExp emailRegex = RegExp(r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$'); String get inputText => _inputText; Color get borderColor { if (isEmailMode) { return emailRegex.hasMatch(_inputText) ? Colors.white : Colors.red; } else { return _inputText.length == 10 ? Colors.white : Colors.red; } } void updateInput(String text) { _inputText = text; notifyListeners(); } void toggleMode() { isEmailMode = !isEmailMode; notifyListeners(); } }
2. UI 层集成
import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; class InputPage extends StatelessWidget { @override Widget build(BuildContext context) { return ChangeNotifierProvider( create: (_) => InputProvider(), child: Scaffold( appBar: AppBar( actions: [ Consumer<InputProvider>( builder: (context, provider, child) { return TextButton( onPressed: provider.toggleMode, child: Text(provider.isEmailMode ? '切换到手机号' : '切换到邮箱'), ); }, ) ], ), body: Padding( padding: const EdgeInsets.all(16.0), child: Consumer<InputProvider>( builder: (context, provider, child) { return TextField( onChanged: provider.updateInput, decoration: InputDecoration( border: OutlineInputBorder( borderSide: BorderSide(color: provider.borderColor), ), focusedBorder: OutlineInputBorder( borderSide: BorderSide(color: provider.borderColor), ), hintText: provider.isEmailMode ? '输入邮箱' : '输入手机号', ), ); }, ), ), ), ); } }
三、Bloc 实现
1. 定义事件与状态
import 'package:bloc/bloc.dart'; // 输入变化事件 class InputChangedEvent { final String text; final bool isEmailMode; InputChangedEvent(this.text, this.isEmailMode); } // 输入状态 class InputState { final String inputText; final bool isEmailMode; final Color borderColor; InputState({ required this.inputText, required this.isEmailMode, required this.borderColor, }); } // Bloc 核心逻辑 class InputBloc extends Bloc<InputChangedEvent, InputState> { final RegExp emailRegex = RegExp(r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$'); InputBloc() : super(InputState(inputText: '', isEmailMode: true, borderColor: Colors.red)) { on<InputChangedEvent>((event, emit) { Color color; if (event.isEmailMode) { color = emailRegex.hasMatch(event.text) ? Colors.white : Colors.red; } else { color = event.text.length == 10 ? Colors.white : Colors.red; } emit(InputState( inputText: event.text, isEmailMode: event.isEmailMode, borderColor: color, )); }); } }
2. UI 层集成
import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; class InputPage extends StatefulWidget { @override State<InputPage> createState() => _InputPageState(); } class _InputPageState extends State<InputPage> { bool _isEmailMode = true; @override Widget build(BuildContext context) { return BlocProvider( create: (_) => InputBloc(), child: Scaffold( appBar: AppBar( actions: [ TextButton( onPressed: () { setState(() { _isEmailMode = !_isEmailMode; // 切换模式后触发一次验证更新 context.read<InputBloc>().add(InputChangedEvent(context.read<InputBloc>().state.inputText, _isEmailMode)); }); }, child: Text(_isEmailMode ? '切换到手机号' : '切换到邮箱'), ) ], ), body: Padding( padding: const EdgeInsets.all(16.0), child: BlocBuilder<InputBloc, InputState>( builder: (context, state) { return TextField( onChanged: (text) { context.read<InputBloc>().add(InputChangedEvent(text, _isEmailMode)); }, decoration: InputDecoration( border: OutlineInputBorder( borderSide: BorderSide(color: state.borderColor), ), focusedBorder: OutlineInputBorder( borderSide: BorderSide(color: state.borderColor), ), hintText: _isEmailMode ? '输入邮箱' : '输入手机号', ), ); }, ), ), ), ); } }
以上三种方案均能实现实时验证输入并动态调整边框颜色的需求,可根据项目技术栈自由选择。
内容的提问来源于stack exchange,提问作者Furkan
相关产品推荐
相关产品推荐

