Skip to content

Exception thrown when programmatically changing a TextEditingController value #10681

@yyoon

Description

@yyoon

Not sure whether this is a flutter bug or I should restructure the code.
The intended behavior is that whenever I click the circled plus button, it should add ", " to the end of the input text and advance the cursor to the end.

Steps to Reproduce

  • Run the following sample flutter program.
  • Type something in the text field and click the circled plus button.
  • The text field flicker for a moment, and the console shows some error messages (see below).

<main.dart>

import 'package:flutter/material.dart';

void main() {
  runApp(new MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Flutter Demo',
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: new MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => new _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  final TextEditingController _textController = new TextEditingController();

  @override
  Widget build(BuildContext context) {
    ThemeData theme = Theme.of(context);

    return new Scaffold(
      appBar: new AppBar(
        title: new Text(widget.title),
      ),
      body: new Center(
        child: new AnimatedBuilder(
          animation: _textController,
          builder: (BuildContext context, Widget child) {
            return new AlertDialog(
              title: new Text('Sample Values'),
              content: new Row(
                children: <Widget>[
                  new Expanded(
                    child: new TextField(
                      autofocus: true,
                      controller: _textController,
                      onSubmitted: (String text) =>
                          text.isNotEmpty ? _handleSubmit(text) : null,
                    ),
                  ),
                  new IconButton(
                    icon: new Icon(Icons.add_circle_outline),
                    color: theme.primaryColor,
                    onPressed: _shouldEnablePlusButton(_textController.text)
                        ? _handlePlusButton
                        : null,
                  ),
                ],
              ),
              actions: <Widget>[
                new FlatButton(
                  child: new Text('OK'),
                  onPressed: _textController.text.isNotEmpty
                      ? () => _handleSubmit(_textController.text)
                      : null,
                ),
              ],
            );
          },
        ),
      ),
    );
  }

  bool _shouldEnablePlusButton(String text) {
    return text.trim().isNotEmpty && !text.trim().endsWith(',');
  }

  void _handlePlusButton() {
    _textController.text = _textController.text + ', ';
    _textController.selection = new TextSelection.collapsed(
      offset: _textController.text.length,
    );
  }

  void _handleSubmit(String text) {
    print(text);
    _textController.clear();
  }
}

Logs

E/SpannableStringBuilder(16005): SPAN_EXCLUSIVE_EXCLUSIVE spans cannot have a zero length
E/SpannableStringBuilder(16005): SPAN_EXCLUSIVE_EXCLUSIVE spans cannot have a zero length
E/SpannableStringBuilder(16005): SPAN_EXCLUSIVE_EXCLUSIVE spans cannot have a zero length
E/SpannableStringBuilder(16005): SPAN_EXCLUSIVE_EXCLUSIVE spans cannot have a zero length
W/IInputConnectionWrapper(16005): finishComposingText on inactive InputConnection
W/IInputConnectionWrapper(16005): beginBatchEdit on inactive InputConnection
W/IInputConnectionWrapper(16005): getTextBeforeCursor on inactive InputConnection
W/IInputConnectionWrapper(16005): getTextAfterCursor on inactive InputConnection
W/IInputConnectionWrapper(16005): getSelectedText on inactive InputConnection
W/IInputConnectionWrapper(16005): endBatchEdit on inactive InputConnection
W/IInputConnectionWrapper(16005): beginBatchEdit on inactive InputConnection
W/IInputConnectionWrapper(16005): getTextBeforeCursor on inactive InputConnection
W/IInputConnectionWrapper(16005): getTextAfterCursor on inactive InputConnection
W/IInputConnectionWrapper(16005): getSelectedText on inactive InputConnection
W/IInputConnectionWrapper(16005): endBatchEdit on inactive InputConnection
I/flutter (16005): ══╡ EXCEPTION CAUGHT BY RENDERING LIBRARY ╞═════════════════════════════════════════════════════════
I/flutter (16005): The following assertion was thrown during paint():
I/flutter (16005): 'package:flutter/src/rendering/object.dart': Failed assertion: line 2110: 'owner == null ||
I/flutter (16005): !owner.debugDoingPaint': is not true.
I/flutter (16005): 
I/flutter (16005): Either the assertion indicates an error in the framework itself, or we should provide substantially
I/flutter (16005): more information in this error message to help you determine and fix the underlying cause.
I/flutter (16005): In either case, please report this assertion by filing a bug on GitHub:
I/flutter (16005):   https://github.com/flutter/flutter/issues/new
I/flutter (16005): 
I/flutter (16005): When the exception was thrown, this was the stack:
I/flutter (16005): #2      RenderObject.markNeedsPaint (package:flutter/src/rendering/object.dart:2110)
I/flutter (16005): #3      _RenderInkFeatures._didChangeLayout (package:flutter/src/material/material.dart:315)
I/flutter (16005): #4      _MaterialState.build.<anonymous closure> (package:flutter/src/material/material.dart:228)
I/flutter (16005): #5      NotificationListener._dispatch (package:flutter/src/widgets/notification_listener.dart:110)
I/flutter (16005): #6      Notification.visitAncestor (package:flutter/src/widgets/notification_listener.dart:43)
I/flutter (16005): #7      LayoutChangedNotification&ViewportNotificationMixin.visitAncestor (package:flutter/src/widgets/scroll_notification.dart:36)
I/flutter (16005): #8      Element.visitAncestorElements (package:flutter/src/widgets/framework.dart:3103)
I/flutter (16005): #9      Notification.dispatch (package:flutter/src/widgets/notification_listener.dart:57)
I/flutter (16005): #10     ScrollActivity.dispatchScrollStartNotification (package:flutter/src/widgets/scroll_activity.dart:90)
I/flutter (16005): #11     ScrollPosition.didStartScroll (package:flutter/src/widgets/scroll_position.dart:543)
I/flutter (16005): #12     ScrollPosition.beginActivity (package:flutter/src/widgets/scroll_position.dart:535)
I/flutter (16005): #13     ScrollPositionWithSingleContext.beginActivity (package:flutter/src/widgets/scroll_position_with_single_context.dart:119)
I/flutter (16005): #14     ScrollPositionWithSingleContext.animateTo (package:flutter/src/widgets/scroll_position_with_single_context.dart:186)
I/flutter (16005): #15     ScrollController.animateTo (package:flutter/src/widgets/scroll_controller.dart:143)
I/flutter (16005): #16     EditableTextState._handleCaretChanged (package:flutter/src/widgets/editable_text.dart:463)
I/flutter (16005): #17     RenderEditable._paintCaret (package:flutter/src/rendering/editable.dart:497)
I/flutter (16005): #18     RenderEditable._paintContents (package:flutter/src/rendering/editable.dart:515)
I/flutter (16005): #19     RenderEditable.paint (package:flutter/src/rendering/editable.dart:531)
I/flutter (16005): #20     RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:2259)
I/flutter (16005): #21     PaintingContext.paintChild (package:flutter/src/rendering/object.dart:116)
I/flutter (16005): #22     RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.paint (package:flutter/src/rendering/proxy_box.dart:123)
I/flutter (16005): #23     RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:2259)
I/flutter (16005): #24     PaintingContext.paintChild (package:flutter/src/rendering/object.dart:116)
I/flutter (16005): #25     RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.paint (package:flutter/src/rendering/proxy_box.dart:123)
I/flutter (16005): #26     RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:2259)
I/flutter (16005): #27     PaintingContext.paintChild (package:flutter/src/rendering/object.dart:116)
I/flutter (16005): #28     RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.paint (package:flutter/src/rendering/proxy_box.dart:123)
I/flutter (16005): #29     RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:2259)
I/flutter (16005): #30     PaintingContext.paintChild (package:flutter/src/rendering/object.dart:116)
I/flutter (16005): #31     RenderBox&RenderObjectWithChildMixin&RenderProxyBoxMixin.paint (package:flutter/src/rendering/proxy_box.dart:123)
I/flutter (16005): #32     RenderObject._paintWithContext (package:flutter/src/rendering/object.dart:2259)
I/flutter (16005): #33     PaintingContext.repaintCompositedChild (package:flutter/src/rendering/object.dart:96)
I/flutter (16005): #34     PipelineOwner.flushPaint (package:flutter/src/rendering/object.dart:1085)
I/flutter (16005): #35     BindingBase&SchedulerBinding&GestureBinding&ServicesBinding&RendererBinding.drawFrame (package:flutter/src/rendering/binding.dart:253)
I/flutter (16005): #36     BindingBase&SchedulerBinding&GestureBinding&ServicesBinding&RendererBinding&WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:504)
I/flutter (16005): #37     BindingBase&SchedulerBinding&GestureBinding&ServicesBinding&RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:189)
I/flutter (16005): #38     BindingBase&SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:688)
I/flutter (16005): #39     BindingBase&SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:636)
I/flutter (16005): #40     _drawFrame (file:///b/build/slave/Linux_Engine/build/src/flutter/lib/ui/hooks.dart:70)
I/flutter (16005): (elided 2 frames from class _AssertionError)
I/flutter (16005): 
I/flutter (16005): The following RenderObject was being processed when the exception was fired:
I/flutter (16005):   RenderEditable#653928671 relayoutBoundary=up25
I/flutter (16005):   creator: _Editable ← _ScrollableScope ← IgnorePointer-[GlobalKey#739450262] ← Listener ←
I/flutter (16005):   _GestureSemantics ← RawGestureDetector-[LabeledGlobalKey<RawGestureDetectorState>#519290292] ←
I/flutter (16005):   RepaintBoundary ← CustomPaint ← RepaintBoundary ← NotificationListener<ScrollNotification> ←
I/flutter (16005):   GlowingOverscrollIndicator ← Scrollable ← ⋯
I/flutter (16005):   parentData: <none> (can use size)
I/flutter (16005):   constraints: BoxConstraints(w=184.0, 0.0<=h<=160.0)
I/flutter (16005):   size: Size(184.0, 19.0)
I/flutter (16005):   cursorColor: Color(0xff90caf9)
I/flutter (16005):   showCursor: ValueNotifier<bool>#24695738(true)
I/flutter (16005):   maxLines: 1
I/flutter (16005):   selectionColor: Color(0xff90caf9)
I/flutter (16005):   textScaleFactor: 1.0
I/flutter (16005):   selection: TextSelection(baseOffset: 6, extentOffset: 6, affinity: TextAffinity.downstream,
I/flutter (16005):   isDirectional: false)
I/flutter (16005):   offset: ScrollPositionWithSingleContext#600127095(offset: 0.0, range: 0.0..0.0, viewport: 184.0,
I/flutter (16005):   ScrollableState, ClampingScrollPhysics -> ClampingScrollPhysics,
I/flutter (16005):   DrivenScrollActivity#106212815(AnimationController#365025467(▶ 0.000; for DrivenScrollActivity)),
I/flutter (16005):   ScrollDirection.idle)
I/flutter (16005): This RenderObject has no descendants.
I/flutter (16005): ════════════════════════════════════════════════════════════════════════════════════════════════════

Flutter Doctor

[✓] Flutter (on Linux, locale en_US.UTF-8, channel unknown)
    • Flutter at /usr/local/google/home/youngseokyoon/Programming/fuchsia/lib/flutter
    • Framework revision 0774c5194b (7 hours ago), 2017-06-13 10:51:17 -0700
    • Engine revision 4f5d6fab11
    • Tools Dart version 1.24.0-dev.6.7

[✓] Android toolchain - develop for Android devices (Android SDK 25.0.3)
    • Android SDK at /usr/local/google/home/youngseokyoon/Android/Sdk
    • Platform android-25, build-tools 25.0.3
    • Java binary at: /opt/android-studio-2.3/jre/bin/java
    • Java version OpenJDK Runtime Environment (build 1.8.0_112-release-b06)

[✓] Android Studio (version 2.3)
    • Android Studio at /opt/android-studio-2.3
    • Gradle version 3.2
    • Java version OpenJDK Runtime Environment (build 1.8.0_112-release-b06)

[-] IntelliJ IDEA Community Edition (version 2017.1)
    ✗ Flutter plugin version 13.1 - the recommended minimum version is 14.0.0
    • Dart plugin version 171.4424
    • For information about managing plugins, see
      https://www.jetbrains.com/help/idea/managing-plugins.html

[✓] Connected devices
    • Pixel C • 5C08000423 • android-arm • Android 7.0 (API 24)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions