Search code examples
flutterdartflutter-layoutflutter-textformfield

Change background color on TextField when focused


I have a form with lots of input fields. I would like to change the background color when a TextField has focus:

enter image description here

enter image description here

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?


Solution

  • 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,
                      ),
                    ),
                  ),
                ),
              ),
            ],
          ),
     }
    }