-
Notifications
You must be signed in to change notification settings - Fork 29.7k
Closed
Labels
a: error messageError messages from the Flutter frameworkError messages from the Flutter frameworka: text inputEntering text in a text field or keyboard related problemsEntering text in a text field or keyboard related problemsf: material designflutter/packages/flutter/material repository.flutter/packages/flutter/material repository.found in release: 3.13Found to occur in 3.13Found to occur in 3.13found in release: 3.16Found to occur in 3.16Found to occur in 3.16has reproducible stepsThe issue has been confirmed reproducible and is ready to work onThe issue has been confirmed reproducible and is ready to work onteam-designOwned by Design Languages teamOwned by Design Languages team
Description
Is there an existing issue for this?
- I have searched the existing issues
- I have read the guide to filing a bug
Steps to reproduce
I built a minimal reproducible sample with a TextEditingController that replaces abc with a WidgetSpan (it surrounds abc with a border)
When the TextField is used inside the main Scaffold, no issue. If it is in an AlertDialog, it crashes.
- Clone this repo https://github.com/GP4cK/alert_bug
- Tap on the FAB
- Type
abcin the AlertDialog
Expected results
It should behave the same whether the TextField is in a dialog or not.
Actual results
In the dialog, it throws an exception during layout.
Code sample
Code sample
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
title: 'Flutter Demo',
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatelessWidget {
const MyHomePage({super.key, required this.title});
final String title;
void openAlert(BuildContext context) {
showDialog(
context: context,
builder: (context) {
return const AlertDialog(content: MyTextField());
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
title: Text(title),
),
body: const Padding(
padding: EdgeInsets.all(24.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
MyTextField(),
SizedBox(height: 24),
Text('Tap the FAB and type "abc"'),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () => openAlert(context),
child: const Icon(Icons.add),
),
);
}
}
class MyTextController extends TextEditingController {
static const textToReplace = 'abc';
static final replacement = TextSpan(children: [
WidgetSpan(
alignment: PlaceholderAlignment.middle,
baseline: TextBaseline.ideographic,
child: Container(
padding: const EdgeInsets.all(1),
decoration: BoxDecoration(
borderRadius: const BorderRadius.all(Radius.circular(4)),
border: Border.all(color: Colors.blue),
),
child: const Text(textToReplace),
),
),
// Adds invisible characters to the end of the span to make sure the
// cursor is at the right place
// https://stackoverflow.com/questions/66304688/cursor-wrong-position-after-text-replacing-with-textspan.
TextSpan(text: '\u200b' * (textToReplace.length - 1)),
]);
@override
TextSpan buildTextSpan(
{required BuildContext context,
TextStyle? style,
required bool withComposing}) {
return TextSpan(
children: text
.split(textToReplace)
.map((str) =>
TextSpan(text: str, style: const TextStyle(color: Colors.black)))
.separated(replacement)
.toList(),
);
}
}
class MyTextField extends StatefulWidget {
const MyTextField({super.key});
@override
State<MyTextField> createState() => _MyTextFieldState();
}
class _MyTextFieldState extends State<MyTextField> {
final controller = MyTextController();
@override
void dispose() {
controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return TextField(
autofocus: true,
controller: controller,
);
}
}
extension<T> on Iterable<T> {
/// Puts [separator] between every element.
///
/// Example:
///
/// ```dart
/// final list1 = <int>[].separated(2); // [];
/// final list2 = [0].separated(2); // [0];
/// final list3 = [0, 0].separated(2); // [0, 2, 0];
/// ```
Iterable<T> separated(T separator) sync* {
final iterator = this.iterator;
if (iterator.moveNext()) {
yield iterator.current;
while (iterator.moveNext()) {
yield separator;
yield iterator.current;
}
}
}
}
Screenshots or Video
Using the same TextField / TextController, see how there is no problem when I enter 'abc' in the Scaffold of the main app, but it crashes when I enter it in the dialog.
Screenshots / Video demonstration
Video.MP4.584x624.mp4
Logs
Logs
Restarted application in 451ms.
════════ Exception caught by rendering library ═════════════════════════════════
The following assertion was thrown during performLayout():
'package:flutter/src/widgets/widget_span.dart': Failed assertion: line 137 pos 12: 'dimensions != null': is not true.
Either the assertion indicates an error in the framework itself, or we should provide substantially more information in this error message to help you determine and fix the underlying cause.
In either case, please report this assertion by filing a bug on GitHub:
https://github.com/flutter/flutter/issues/new?template=2_bug.yml
The relevant error-causing widget was
AlertDialog
When the exception was thrown, this was the stack
#2 WidgetSpan.build
#3 TextSpan.build
#4 TextSpan.build
#5 TextPainter._createParagraph
#6 TextPainter.layout
#7 RenderEditable._layoutText
#8 RenderEditable.computeMaxIntrinsicWidth
#9 RenderBox._computeIntrinsicDimension.<anonymous closure>
#10 _LinkedHashMapMixin.putIfAbsent (dart:collection-patch/compact_hash.dart:535:23)
#11 RenderBox._computeIntrinsicDimension
#12 RenderBox.getMaxIntrinsicWidth
#13 RenderProxyBoxMixin.computeMaxIntrinsicWidth
#14 RenderBox._computeIntrinsicDimension.<anonymous closure>
#15 _LinkedHashMapMixin.putIfAbsent (dart:collection-patch/compact_hash.dart:535:23)
#16 RenderBox._computeIntrinsicDimension
#17 RenderBox.getMaxIntrinsicWidth
#18 RenderProxyBoxMixin.computeMaxIntrinsicWidth
#19 RenderBox._computeIntrinsicDimension.<anonymous closure>
#20 _LinkedHashMapMixin.putIfAbsent (dart:collection-patch/compact_hash.dart:535:23)
#21 RenderBox._computeIntrinsicDimension
#22 RenderBox.getMaxIntrinsicWidth
#23 RenderProxyBoxMixin.computeMaxIntrinsicWidth
#24 RenderBox._computeIntrinsicDimension.<anonymous closure>
#25 _LinkedHashMapMixin.putIfAbsent (dart:collection-patch/compact_hash.dart:535:23)
#26 RenderBox._computeIntrinsicDimension
#27 RenderBox.getMaxIntrinsicWidth
#28 RenderProxyBoxMixin.computeMaxIntrinsicWidth
#29 RenderBox._computeIntrinsicDimension.<anonymous closure>
#30 _LinkedHashMapMixin.putIfAbsent (dart:collection-patch/compact_hash.dart:535:23)
#31 RenderBox._computeIntrinsicDimension
#32 RenderBox.getMaxIntrinsicWidth
#33 RenderProxyBoxMixin.computeMaxIntrinsicWidth
#34 RenderBox._computeIntrinsicDimension.<anonymous closure>
#35 _LinkedHashMapMixin.putIfAbsent (dart:collection-patch/compact_hash.dart:535:23)
#36 RenderBox._computeIntrinsicDimension
#37 RenderBox.getMaxIntrinsicWidth
#38 RenderProxyBoxMixin.computeMaxIntrinsicWidth
#39 RenderBox._computeIntrinsicDimension.<anonymous closure>
#40 _LinkedHashMapMixin.putIfAbsent (dart:collection-patch/compact_hash.dart:535:23)
#41 RenderBox._computeIntrinsicDimension
#42 RenderBox.getMaxIntrinsicWidth
#43 RenderProxyBoxMixin.computeMaxIntrinsicWidth
#44 RenderBox._computeIntrinsicDimension.<anonymous closure>
#45 _LinkedHashMapMixin.putIfAbsent (dart:collection-patch/compact_hash.dart:535:23)
#46 RenderBox._computeIntrinsicDimension
#47 RenderBox.getMaxIntrinsicWidth
#48 RenderProxyBoxMixin.computeMaxIntrinsicWidth
#49 RenderBox._computeIntrinsicDimension.<anonymous closure>
#50 _LinkedHashMapMixin.putIfAbsent (dart:collection-patch/compact_hash.dart:535:23)
#51 RenderBox._computeIntrinsicDimension
#52 RenderBox.getMaxIntrinsicWidth
#53 RenderProxyBoxMixin.computeMaxIntrinsicWidth
#54 RenderBox._computeIntrinsicDimension.<anonymous closure>
#55 _LinkedHashMapMixin.putIfAbsent (dart:collection-patch/compact_hash.dart:535:23)
#56 RenderBox._computeIntrinsicDimension
#57 RenderBox.getMaxIntrinsicWidth
#58 RenderProxyBoxMixin.computeMaxIntrinsicWidth
#59 RenderBox._computeIntrinsicDimension.<anonymous closure>
#60 _LinkedHashMapMixin.putIfAbsent (dart:collection-patch/compact_hash.dart:535:23)
#61 RenderBox._computeIntrinsicDimension
#62 RenderBox.getMaxIntrinsicWidth
#63 _RenderDecoration._maxWidth
#64 _RenderDecoration.computeMaxIntrinsicWidth
#65 RenderBox._computeIntrinsicDimension.<anonymous closure>
#66 _LinkedHashMapMixin.putIfAbsent (dart:collection-patch/compact_hash.dart:535:23)
#67 RenderBox._computeIntrinsicDimension
#68 RenderBox.getMaxIntrinsicWidth
#69 RenderProxyBoxMixin.computeMaxIntrinsicWidth
#70 RenderBox._computeIntrinsicDimension.<anonymous closure>
#71 _LinkedHashMapMixin.putIfAbsent (dart:collection-patch/compact_hash.dart:535:23)
#72 RenderBox._computeIntrinsicDimension
#73 RenderBox.getMaxIntrinsicWidth
#74 RenderProxyBoxMixin.computeMaxIntrinsicWidth
#75 RenderBox._computeIntrinsicDimension.<anonymous closure>
#76 _LinkedHashMapMixin.putIfAbsent (dart:collection-patch/compact_hash.dart:535:23)
#77 RenderBox._computeIntrinsicDimension
#78 RenderBox.getMaxIntrinsicWidth
#79 RenderProxyBoxMixin.computeMaxIntrinsicWidth
#80 RenderBox._computeIntrinsicDimension.<anonymous closure>
#81 _LinkedHashMapMixin.putIfAbsent (dart:collection-patch/compact_hash.dart:535:23)
#82 RenderBox._computeIntrinsicDimension
#83 RenderBox.getMaxIntrinsicWidth
#84 RenderProxyBoxMixin.computeMaxIntrinsicWidth
#85 RenderBox._computeIntrinsicDimension.<anonymous closure>
#86 _LinkedHashMapMixin.putIfAbsent (dart:collection-patch/compact_hash.dart:535:23)
#87 RenderBox._computeIntrinsicDimension
#88 RenderBox.getMaxIntrinsicWidth
#89 RenderProxyBoxMixin.computeMaxIntrinsicWidth
#90 RenderBox._computeIntrinsicDimension.<anonymous closure>
#91 _LinkedHashMapMixin.putIfAbsent (dart:collection-patch/compact_hash.dart:535:23)
#92 RenderBox._computeIntrinsicDimension
#93 RenderBox.getMaxIntrinsicWidth
#94 RenderProxyBoxMixin.computeMaxIntrinsicWidth
#95 RenderBox._computeIntrinsicDimension.<anonymous closure>
#96 _LinkedHashMapMixin.putIfAbsent (dart:collection-patch/compact_hash.dart:535:23)
#97 RenderBox._computeIntrinsicDimension
#98 RenderBox.getMaxIntrinsicWidth
#99 RenderPadding.computeMaxIntrinsicWidth
#100 RenderBox._computeIntrinsicDimension.<anonymous closure>
#101 _LinkedHashMapMixin.putIfAbsent (dart:collection-patch/compact_hash.dart:535:23)
#102 RenderBox._computeIntrinsicDimension
#103 RenderBox.getMaxIntrinsicWidth
#104 RenderFlex.computeMaxIntrinsicWidth.<anonymous closure>
#105 RenderFlex._getIntrinsicSize
#106 RenderFlex.computeMaxIntrinsicWidth
#107 RenderBox._computeIntrinsicDimension.<anonymous closure>
#108 _LinkedHashMapMixin.putIfAbsent (dart:collection-patch/compact_hash.dart:535:23)
#109 RenderBox._computeIntrinsicDimension
#110 RenderBox.getMaxIntrinsicWidth
#111 RenderIntrinsicWidth._computeSize
#112 RenderIntrinsicWidth.performLayout
#113 RenderObject.layout
#114 RenderBox.layout
#115 RenderProxyBoxMixin.performLayout
#116 RenderObject.layout
#117 RenderBox.layout
#118 RenderProxyBoxMixin.performLayout
#119 RenderCustomPaint.performLayout
#120 RenderObject.layout
#121 RenderBox.layout
#122 RenderProxyBoxMixin.performLayout
#123 _RenderCustomClip.performLayout
#124 RenderObject.layout
#125 RenderBox.layout
#126 RenderConstrainedBox.performLayout
#127 RenderObject.layout
#128 RenderBox.layout
#129 RenderPositionedBox.performLayout
#130 RenderObject._layoutWithoutResize
#131 PipelineOwner.flushLayout
#132 RendererBinding.drawFrame
#133 WidgetsBinding.drawFrame
#134 RendererBinding._handlePersistentFrameCallback
#135 SchedulerBinding._invokeFrameCallback
#136 SchedulerBinding.handleDrawFrame
#137 SchedulerBinding._handleDrawFrame
#138 _invoke (dart:ui/hooks.dart:170:13)
#139 PlatformDispatcher._drawFrame (dart:ui/platform_dispatcher.dart:401:5)
#140 _drawFrame (dart:ui/hooks.dart:140:31)
(elided 2 frames from class _AssertionError)
The following RenderObject was being processed when the exception was fired: RenderIntrinsicWidth#18c0a relayoutBoundary=up5 NEEDS-LAYOUT
RenderObject: RenderIntrinsicWidth#18c0a relayoutBoundary=up5 NEEDS-LAYOUT
needs compositing
parentData: <none> (can use size)
constraints: BoxConstraints(280.0<=w<=720.0, 0.0<=h<=552.0)
size: Size(280.0, 92.0)
stepWidth: null
stepHeight: null
child: RenderFlex#1f5bb relayoutBoundary=up6 NEEDS-LAYOUT
needs compositing
parentData: <none> (can use size)
constraints: BoxConstraints(w=280.0, 0.0<=h<=552.0)
size: Size(280.0, 92.0)
direction: vertical
mainAxisAlignment: start
mainAxisSize: min
crossAxisAlignment: stretch
verticalDirection: down
child 1: RenderPadding#2aba3 relayoutBoundary=up7 NEEDS-LAYOUT
needs compositing
parentData: offset=Offset(0.0, 0.0); flex=1; fit=FlexFit.loose (can use size)
constraints: BoxConstraints(w=280.0, 0.0<=h<=552.0)
size: Size(280.0, 92.0)
padding: EdgeInsets(24.0, 20.0, 24.0, 24.0)
textDirection: ltr
child: RenderSemanticsAnnotations#5b481 relayoutBoundary=up8 NEEDS-LAYOUT
needs compositing
parentData: offset=Offset(24.0, 20.0) (can use size)
constraints: BoxConstraints(w=232.0, 0.0<=h<=508.0)
semantic boundary
size: Size(232.0, 48.0)
child: RenderMouseRegion#b755f relayoutBoundary=up9 NEEDS-LAYOUT
needs compositing
parentData: <none> (can use size)
constraints: BoxConstraints(w=232.0, 0.0<=h<=508.0)
size: Size(232.0, 48.0)
behavior: opaque
listeners: enter, exit
cursor: SystemMouseCursor(text)
════════════════════════════════════════════════════════════════════════════════
════════ Exception caught by rendering library ═════════════════════════════════
'package:flutter/src/widgets/widget_span.dart': Failed assertion: line 137 pos 12: 'dimensions != null': is not true.
════════════════════════════════════════════════════════════════════════════════
════════ Exception caught by rendering library ═════════════════════════════════
'package:flutter/src/widgets/widget_span.dart': Failed assertion: line 137 pos 12: 'dimensions != null': is not true.
════════════════════════════════════════════════════════════════════════════════
════════ Exception caught by scheduler library ═════════════════════════════════
'package:flutter/src/widgets/widget_span.dart': Failed assertion: line 137 pos 12: 'dimensions != null': is not true.
════════════════════════════════════════════════════════════════════════════════
════════ Exception caught by scheduler library ═════════════════════════════════
'package:flutter/src/widgets/widget_span.dart': Failed assertion: line 137 pos 12: 'dimensions != null': is not true.
════════════════════════════════════════════════════════════════════════════════
Flutter Doctor output
Doctor output
Doctor summary (to see all details, run flutter doctor -v):
[✓] Flutter (Channel stable, 3.13.7, on macOS 13.4.1 22F770820d darwin-x64, locale en-GB)
[!] Android toolchain - develop for Android devices (Android SDK version 30.0.3)
✗ cmdline-tools component is missing
Run `path/to/sdkmanager --install "cmdline-tools;latest"`
See https://developer.android.com/studio/command-line for more details.
✗ Android license status unknown.
Run `flutter doctor --android-licenses` to accept the SDK licenses.
See https://flutter.dev/docs/get-started/install/macos#android-setup for more details.
[✓] Xcode - develop for iOS and macOS (Xcode 14.3.1)
[✓] Chrome - develop for the web
[✓] Android Studio (version 2022.3)
[✓] VS Code (version 1.83.1)
[✓] Connected device (2 available)
[✓] Network resources
! Doctor found issues in 1 category.Metadata
Metadata
Assignees
Labels
a: error messageError messages from the Flutter frameworkError messages from the Flutter frameworka: text inputEntering text in a text field or keyboard related problemsEntering text in a text field or keyboard related problemsf: material designflutter/packages/flutter/material repository.flutter/packages/flutter/material repository.found in release: 3.13Found to occur in 3.13Found to occur in 3.13found in release: 3.16Found to occur in 3.16Found to occur in 3.16has reproducible stepsThe issue has been confirmed reproducible and is ready to work onThe issue has been confirmed reproducible and is ready to work onteam-designOwned by Design Languages teamOwned by Design Languages team