I have a form with lots of input fields. I would like to change the background color when a TextField has focus:
This is my TextField:
TextFormField(
focusNode: _textFieldFocus,
decoration: InputDecoration(
labelText: 'Input test',
filled: true,
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.blue, width: 3),
),
),
),
I´ve searched some time for a solution, but it seems that you have to wrap the TextField in a stateful widget that uses a FocusNode. Seen in this post for an example: How to change TextFiled widget background color when focus
I am not too keen on this solution, because I have a lot of text fields, and I think it is unnecessary to create stateful instances for each "dumb" text input I have. I would prefer if there was a focusBackgroundColor property or alike. So is there an easier solution than wrapping a TextField in a stateful widget?
CodePudding user response:
Add a listener on FocusNode
to use setState
for UI update. to change color we can use fillColor: _textFieldFocus.hasFocus ? Colors.purple : null
, modify the color you want.
late final _textFieldFocus = FocusNode()
..addListener(() {
setState(() {});
});
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
TextFormField(
focusNode: _textFieldFocus,
decoration: InputDecoration(
fillColor: _textFieldFocus.hasFocus ? Colors.purple : null,
labelText: 'Input test',
filled: true,
focusedBorder: UnderlineInputBorder(
borderSide: BorderSide(color: Colors.blue, width: 3),
),
),
),
],
),
With ValueNotifier
class TestA extends StatelessWidget {
TestA({Key? key}) : super(key: key);
final ValueNotifier<bool> _textFiledIsFocused = ValueNotifier(false);
late final FocusNode _textFieldFocus = FocusNode()
..addListener(() {
_textFiledIsFocused.value = _textFieldFocus.hasFocus;
});
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
ValueListenableBuilder<bool>(
valueListenable: _textFiledIsFocused,
builder: (context, value, child) => TextFormField(
focusNode: _textFieldFocus,
decoration: InputDecoration(
fillColor: value ? Colors.purple : null,
labelText: 'Input test',
filled: true,
focusedBorder: const UnderlineInputBorder(
borderSide: BorderSide(
color: Colors.blue,
width: 3,
),
),
),
),
),
],
),
}
}