skip to Main Content

I want to add widgets (like extra border) when the text field is focused.
I’ve simplified my problem.

class CustomTextField extends StatefulWidget {
  const CustomTextField({super.key});

  @override
  State<CustomTextField> createState() => _CustomTextFieldState();
}

class _CustomTextFieldState extends State<CustomTextField> {
  final _widgetStatesController = WidgetStatesController();
  bool isFocused = false;

  @override
  void initState() {
    _widgetStatesController.addListener(() {
      setState(() {
        isFocused = _widgetStatesController.value.contains(WidgetState.focused);
      });
    });
    super.initState();
  }

  @override
  void dispose() {
    _widgetStatesController.dispose();
    super.dispose();
  }

  @override
  Widget build(final BuildContext context) {
    Widget textField = TextField(
      statesController: _widgetStatesController,
    );

    if (isFocused) {
      textField = Column(
        children: [
          textField,
          const Text('isFocused'),
        ],
      );
    }

    return textField;
  }
}

When I tap on text field, I have this error:

The following assertion was thrown while rebuilding dirty elements:
'package:flutter/src/widgets/framework.dart': Failed assertion: line 5212 pos 12: '!_dirty': is not true.

3

Answers


  1. I don’t know how this simplifies your problem, have you tried using FocusNode though ? Below an example

    class _CustomTextFieldState extends State<CustomTextField> {
      final FocusNode _focusNode = FocusNode();
    
      @override
      void initState() {
        super.initState();
        _focusNode.addListener(() {
          setState(() {});
        });
      }
    
      @override
      void dispose() {
        _focusNode.dispose();
        super.dispose();
      }
    
      @override
      Widget build(BuildContext context) {
        return Column(
          children: [
            TextField(
              focusNode: _focusNode,
            ),
            if (_focusNode.hasFocus) const Text('isFocused'),
          ],
        );
      }
    }
    
    Login or Signup to reply.
  2. Try this one

    class CustomTextField extends StatefulWidget {
      const CustomTextField({Key? key}) : super(key: key);
    
      @override
      State<CustomTextField> createState() => _CustomTextFieldState();
    }
    
    class _CustomTextFieldState extends State<CustomTextField> {
      final FocusNode _focusNode = FocusNode();
      bool isFocused = false;
    
      @override
      void initState() {
        super.initState();
        _focusNode.addListener(_onFocusChange);
      }
    
      void _onFocusChange() {
        setState(() {
          isFocused = _focusNode.hasFocus;
        });
      }
    
      @override
      void dispose() {
        _focusNode.removeListener(_onFocusChange);
        _focusNode.dispose();
        super.dispose();
      }
    
      @override
      Widget build(BuildContext context) {
        Widget textField = TextField(
          focusNode: _focusNode,
          decoration: InputDecoration(
            border: OutlineInputBorder(),
            hintText: 'Enter text here',
          ),
        );
    
        if (isFocused) {
          textField = Column(
            crossAxisAlignment: CrossAxisAlignment.start,
            children: [
              textField,
              const SizedBox(height: 8),
              const Text('Field is focused', style: TextStyle(color: Colors.blue)),
            ],
          );
        }
    
        return Padding(
          padding: const EdgeInsets.all(8.0),
          child: AnimatedContainer(
            duration: const Duration(milliseconds: 200),
            decoration: BoxDecoration(
              border: Border.all(
                color: isFocused ? Colors.blue : Colors.grey,
                width: isFocused ? 2.0 : 1.0,
              ),
              borderRadius: BorderRadius.circular(8),
            ),
            padding: const EdgeInsets.all(4),
            child: textField,
          ),
        );
      }
    }
    
    Login or Signup to reply.
  3. Try below code

    class _CustomTextFieldState extends State<CustomTextFieldFocus> {
      bool isFocused = false;
      final FocusNode _focusNode = FocusNode();
    
      @override
      void initState() {
        _focusNode.addListener(() {
          setState(() {});
        });
        super.initState();
      }
    
      @override
      void dispose() {
        _focusNode.dispose();
        super.dispose();
      }
    
      @override
      Widget build(final BuildContext context) {
        Widget textField = Material(
          child: TextField(
            focusNode: _focusNode,
          ),
        );
    
        if (isFocused) {
          textField = Column(
            children: [
              textField,
              const Text('isFocused'),
            ],
          );
        }
    
        return textField;
      }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search