Skip to content

TextEditingController got exception because of invalid text selection #17647

Closed

Description

@blaizechuang
I got an exception after calling clear() in TextEditingController and then click TextField widget immediately and below is the call stack.
══╡ EXCEPTION CAUGHT BY GESTURE ╞════════════════════════════
═══════════════════════════════════════
I/flutter (20797): The following assertion was thrown while handling a gesture:
I/flutter (20797): invalid text selection: TextSelection(baseOffset: 3, extentOf
fset: 3, affinity:
I/flutter (20797): TextAffinity.upstream, isDirectional: false)
I/flutter (20797): When the exception was thrown, this was the stack:
I/flutter (20797): #0      TextEditingController.set:selection (package:flutter/
src/widgets/editable_text.dart:94)
I/flutter (20797): #1      EditableTextState._handleSelectionChanged (package:fl
utter/src/widgets/editable_text.dart:504)
I/flutter (20797): #2      RenderEditable.handleTap (package:flutter/src/renderi
ng/editable.dart:624)
I/flutter (20797): #3      _TextFieldState._handleTap (package:flutter/src/mater
ial/text_field.dart:404)
I/flutter (20797): #4      GestureRecognizer.invokeCallback (package:flutter/src
/gestures/recognizer.dart:102)
I/flutter (20797): #5      TapGestureRecognizer._checkUp (package:flutter/src/ge
stures/tap.dart:161)
I/flutter (20797): #6      TapGestureRecognizer.acceptGesture (package:flutter/s
rc/gestures/tap.dart:123)
I/flutter (20797): #7      GestureArenaManager.sweep (package:flutter/src/gestur
es/arena.dart:156)
I/flutter (20797): #8      _WidgetsFlutterBinding&BindingBase&GestureBinding.han
dleEvent (package:flutter/src/gestures/binding.dart:147)
I/flutter (20797): #9      _WidgetsFlutterBinding&BindingBase&GestureBinding.dis
patchEvent (package:flutter/src/gestures/binding.dart:121)
I/flutter (20797): #10     _WidgetsFlutterBinding&BindingBase&GestureBinding._ha
ndlePointerEvent (package:flutter/src/gestures/binding.dart:101)
I/flutter (20797): #11     _WidgetsFlutterBinding&BindingBase&GestureBinding._fl
ushPointerEventQueue (package:flutter/src/gestures/binding.dart:64)
I/flutter (20797): #12     _WidgetsFlutterBinding&BindingBase&GestureBinding._ha
ndlePointerDataPacket (package:flutter/src/gestures/binding.dart:48)
I/flutter (20797): #13     _invoke1 (dart:ui/hooks.dart:134)
I/flutter (20797): #14     _dispatchPointerDataPacket (dart:ui/hooks.dart:91)
I/flutter (20797): Handler: onTap
I/flutter (20797): Recognizer:
I/flutter (20797):   TapGestureRecognizer#485eb(debugOwner: GestureDetector, sta
te: ready, won arena, finalPosition:
I/flutter (20797):   Offset(240.2, 138.4), sent tap down)
I/flutter (20797): ═════════════════════════════════════════════════════════════
═══════════════════════════════════════

Doctor summary (to see all details, run flutter doctor -v):
[√] Flutter (Channel beta, v0.2.8, on Microsoft Windows [Version 6.1.7601], loca
le zh-TW)
[√] Android toolchain - develop for Android devices (Android SDK 27.0.3)
[√] Android Studio (version 3.1)
[!] VS Code, 64-bit edition (version 1.21.1)
[√] Connected devices (1 available)

! Doctor found issues in 1 category.

Activity

  1. zoechi commented on May 17, 2018

    @zoechi
    Contributor

    Please add instructions how to reproduce.
    Your Flutter version is a bit dated already.

  2. blaizechuang commented on May 18, 2018

    @blaizechuang
    Author

    Thanks, Zoechi.

    I think this issue easily happened in the low-end devices or its background task was heavy.
    I have a TextField with a TextEditingController and a cancel button in TextField and I attached the detail steps as following:

    Step1: Type some words on TextField
    Step2: Click cancel button [which will call cancel() function of TextEditingController]
    Step3: Click TextField immediately before the words on TextField has not being cleared.
    And the exception occurred.

    I also update the flutter sdk to a newer version but this issue still happened.
    [√] Flutter (Channel beta, v0.3.2, on Microsoft Windows [Version 6.1.7601], loca
    le zh-TW)
    [√] Android toolchain - develop for Android devices (Android SDK 27.0.3)
    [√] Android Studio (version 3.1)
    [!] VS Code, 64-bit edition (version 1.21.1)
    [√] Connected devices (1 available)

  3. zoechi commented on May 18, 2018

    @zoechi
    Contributor

    Some code that shows how and where you initialize TextEditingController and TextField` would be helpful to diagnose the problem.

  4. zoechi commented on Aug 3, 2018

    @zoechi
    Contributor

    Without additional information, we are unfortunately not sure how to resolve this issue. We are therefore reluctantly going to close this bug for now. Please don't hesitate to comment on the bug if you have any more information for us; we will reopen it right away!
    Thanks for your contribution.

  5. MrHarrisOnline commented on Jul 10, 2019

    @MrHarrisOnline

    This happens to me when I trigger an onTap event to clear a text controller, while the text field dose not have focus.

    I am trying to have a way to click outside of the textfield to drop the keyboard and then have an option to clear the textfield as an after thought.

    I want this because the text in the field results in showing conditional filter results in a listview, the keyboard is in the way. I want to be able to filter, select items in the results with the keyboard removed then clear the text which will clear the filter results. I hope that makes sense?

    I am using 'FocusScope.of(context).requestFocus(FocusNode());' to pull fucus from the texfield and close the keyboard. calling textController.clear(); or text.controller.text = '' causes the error when the textfield does not have focus.

    If I have the textfield request focus before I clear the text I am back to where I started with the keyboard open but if the user presses the clear button at this point there is little chance they would want to enter more text in the field. I want to clear the text without interacting with the keyboard or textfield in anyway.

    The following works but you do see the keyboard briefly...

    onTap: () {
                      filterNode.requestFocus();
                      Future.delayed(Duration(milliseconds: 50), () {
                        textController.clear();
    
                        FocusScope.of(context).requestFocus(FocusNode());
                      });
                    },
    

    Thank you.

  6. larssn commented on Jul 12, 2019

    @larssn

    EDIT - Valid workaround:
    WidgetsBinding.instance.addPostFrameCallback((_) => _searchController.clear());
    See below for example.

    @zoechi Could you reopen?
    We have a simple search field like the following, and when we click the clear button, we get the above error.

    class SearchField extends StatefulWidget {
      SearchField({
        Key key,
        this.onTextChanged,
      }) : super(key: key);
    
      final void Function(String) onTextChanged;
    
      @override
      _SearchFieldState createState() => _SearchFieldState();
    }
    
    class _SearchFieldState extends State<SearchField> {
      final _searchController = TextEditingController();
    
      @override
      void initState() {
        super.initState();
        _searchController.addListener(() => widget.onTextChanged != null ? widget.onTextChanged(_searchController.text) : null);
      }
    
      @override
      Widget build(BuildContext context) {
        return Row(
          children: <Widget>[
            Expanded(
              child: TextField(
                controller: _searchController,
                decoration: InputDecoration(
                  contentPadding: EdgeInsets.symmetric(vertical: 20.0),
                  prefixIcon: Icon(
                    Icons.search,
                    color: Colors.grey[400],
                  ),
                  hintText: 'Search',
                  suffixIcon: IconButton(
                    icon: Icon(Icons.clear, color: Colors.red),
                    onPressed: () {
                      // _searchController.text = '';
                      // _searchController.clear(); // Both approaches throw
                      // Workaround
                      WidgetsBinding.instance.addPostFrameCallback((_) => _searchController.clear());
                    },
                  ),
                ),
              ),
            ),
          ],
        );
      }
    
      @override
      void dispose() {
        _searchController.dispose();
        super.dispose();
      }
    }
    

    flutter doctor
    [✓] Flutter (Channel stable, v1.7.8+hotfix.3, on Mac OS X 10.13.6 17G7024, locale en-DK)
    [✓] Android toolchain - develop for Android devices (Android SDK version 28.0.3)
    [✓] Xcode - develop for iOS and macOS (Xcode 10.1)
    [✓] iOS tools - develop for iOS devices
    [✓] Android Studio (version 3.4)
    [✓] VS Code (version 1.36.1)
    [✓] Connected device (1 available)

    • No issues found!

  7. NickCullen commented on Jul 13, 2019

    @NickCullen

    Can confirm the above workaround fixes this issue, but leads to unexpected consequences using the library datetime_picker_formfield which results in multiple datetime pickers opening. Although I appreciate this is likely a bug with their plugin.

    [√] Flutter (Channel beta, v1.7.8+hotfix.3, on Microsoft Windows [Version 10.0.17763.615], locale en-GB)
    [√] Android toolchain - develop for Android devices (Android SDK version 28.0.3)
    [√] Android Studio (version 3.4)
    [√] VS Code, 64-bit edition (version 1.35.1)
    [√] Connected device (1 available)

  8. ramamurthyk commented on Jul 13, 2019

    @ramamurthyk

    I can confirm that the work around is solving this issue. So far ok in plain vanilla TextFields.
    If anyone is interested, snippet below which will enable text clear icon only when there is a text entry. It will hide the clear icon when the text field is empty. It also hides the annoying text underline as well.

    TextField(
                    maxLines: 1,
                    controller: searchTextController,
                    decoration: InputDecoration(
                      hintText: 'Search places...',
                      hintStyle: TextStyle(color: Colors.white70),
                      suffixIcon: searchTextController.text.isNotEmpty
                          ? GestureDetector(
                              onTap: () {
                                // This is not working. Exception - invalid text selection: TextSelection(baseOffset: 2, extentOffset: 2, affinity: TextAffinity.upstream, isDirectional: false)
                                //searchTextController.clear();
                                WidgetsBinding.instance.addPostFrameCallback(
                                    (_) => searchTextController.clear());
                              },
                              child: Icon(
                                Icons.clear,
                                color: Colors.white,
                              ),
                            )
                          : null,
                      border: OutlineInputBorder(
                        borderSide: BorderSide.none,
                      ),
                    ),
                    style: TextStyle(color: Colors.white),
                    autocorrect: false,
                  ),
  9. rockingdice commented on Jul 21, 2019

    @rockingdice

    bump this. I also met this issue after upgrading the flutter SDK to the latest.

  10. inm-certi commented on Jul 25, 2019

    @inm-certi

    I'm also having this issue.
    Thanks for the workaround!

  11. alectogeek commented on Jul 30, 2019

    @alectogeek

    +1

  12. jifalops commented on Aug 6, 2019

    @jifalops

    @NickCullen The issue with datetime_picker_formfield is fixed. It had to add the workaround described here.

  13. added
    p: material_uimaterial_ui package in flutter/packages
    frameworkflutter/packages/flutter repository. See also f: labels.
    on Aug 6, 2019
  14. xlfdyzcs commented on Sep 24, 2019

    @xlfdyzcs

    Without additional information, we are unfortunately not sure how to resolve this issue. We are therefore reluctantly going to close this bug for now. Please don't hesitate to comment on the bug if you have any more information for us; we will reopen it right away!
    Thanks for your contribution.

    Sloppy

  15. Ajmal-Jalal commented on Nov 1, 2019

    @Ajmal-Jalal

    EDIT - Valid workaround:
    WidgetsBinding.instance.addPostFrameCallback((_) => _searchController.clear());
    See below for example.

    @zoechi Could you reopen?
    We have a simple search field like the following, and when we click the clear button, we get the above error.

    class SearchField extends StatefulWidget {
      SearchField({
        Key key,
        this.onTextChanged,
      }) : super(key: key);
    
      final void Function(String) onTextChanged;
    
      @override
      _SearchFieldState createState() => _SearchFieldState();
    }
    
    class _SearchFieldState extends State<SearchField> {
      final _searchController = TextEditingController();
    
      @override
      void initState() {
        super.initState();
        _searchController.addListener(() => widget.onTextChanged != null ? widget.onTextChanged(_searchController.text) : null);
      }
    
      @override
      Widget build(BuildContext context) {
        return Row(
          children: <Widget>[
            Expanded(
              child: TextField(
                controller: _searchController,
                decoration: InputDecoration(
                  contentPadding: EdgeInsets.symmetric(vertical: 20.0),
                  prefixIcon: Icon(
                    Icons.search,
                    color: Colors.grey[400],
                  ),
                  hintText: 'Search',
                  suffixIcon: IconButton(
                    icon: Icon(Icons.clear, color: Colors.red),
                    onPressed: () {
                      // _searchController.text = '';
                      // _searchController.clear(); // Both approaches throw
                      // Workaround
                      WidgetsBinding.instance.addPostFrameCallback((_) => _searchController.clear());
                    },
                  ),
                ),
              ),
            ),
          ],
        );
      }
    
      @override
      void dispose() {
        _searchController.dispose();
        super.dispose();
      }
    }
    

    flutter doctor
    [✓] Flutter (Channel stable, v1.7.8+hotfix.3, on Mac OS X 10.13.6 17G7024, locale en-DK)
    [✓] Android toolchain - develop for Android devices (Android SDK version 28.0.3)
    [✓] Xcode - develop for iOS and macOS (Xcode 10.1)
    [✓] iOS tools - develop for iOS devices
    [✓] Android Studio (version 3.4)
    [✓] VS Code (version 1.36.1)
    [✓] Connected device (1 available)

    • No issues found!

    This worked fine for me

  16. lukepighetti commented on Feb 28, 2020

    @lukepighetti
    Contributor

    This issue is still prevalent and the above reproduction should still work. TLDR: create a text field, connect a controller, type some text, select the text, call TextEditingController.clear()

    Here's a quick fix for everyone's project

    extension TextEditingControllerExtensions on TextEditingController {
      void safeClear() {
        WidgetsBinding.instance.addPostFrameCallback((_) {
          this.clear();
        });
      }
    }
  17. RenanMouraDaSilvaBarros commented on Jun 12, 2020

    @RenanMouraDaSilvaBarros

    solution:
    () async {
    await Future.delayed(Duration(seconds: 0));
    _controller.clear();
    },

  18. github-actions commented on Aug 20, 2021

    @github-actions

    This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.

  19. locked as resolved and limited conversation to collaborators on Aug 20, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    frameworkflutter/packages/flutter repository. See also f: labels.p: material_uimaterial_ui package in flutter/packages

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions