Revert "Warns when single line text fields overflow (#63639)" (#64573)

This reverts commit 0ab5ecc86b.
This commit is contained in:
LongCatIsLooong 2020-08-25 11:11:15 -07:00 committed by GitHub
parent 47596c6203
commit 6536f65048
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 137 additions and 529 deletions

View file

@ -1569,6 +1569,7 @@ class RenderEditable extends RenderBox with RelayoutWhenSystemFontsChangeMixin {
final Offset paintOffset = _paintOffset;
final List<ui.TextBox> boxes = selection.isCollapsed ?
<ui.TextBox>[] : _textPainter.getBoxesForSelection(selection);
if (boxes.isEmpty) {

View file

@ -14,8 +14,6 @@ import 'debug_overflow_indicator.dart';
import 'object.dart';
import 'stack.dart' show RelativeRect;
typedef BoxConstraintsTransform = BoxConstraints Function(BoxConstraints);
/// Abstract class for one-child-layout render boxes that provide control over
/// the child's position.
abstract class RenderShiftedBox extends RenderBox with RenderObjectWithChildMixin<RenderBox> {
@ -596,62 +594,59 @@ class RenderConstrainedOverflowBox extends RenderAligningShiftedBox {
}
}
/// A [RenderBox] that applies an arbitary transform to its [constraints], and
/// sizes its child using the normalized output [BoxConstraints], treating any
/// overflow as error.
/// Renders a box, imposing no constraints on its child, allowing the child to
/// render at its "natural" size.
///
/// This [RenderBox] sizes its child using a normalized [BoxConstraints] created
/// by applying [constraintsTransform] to this [RenderBox]'s own [constraints].
/// This box will then attempt to adopt the same size, within the limits of its
/// own constraints. If it ends up with a different size, it will align the
/// child based on [alignment]. If the box cannot expand enough to accommodate
/// the entire child, the child will be clipped if [clipBehavior] is not
/// [Clip.none].
/// This allows a child to render at the size it would render if it were alone
/// on an infinite canvas with no constraints. This box will then attempt to
/// adopt the same size, within the limits of its own constraints. If it ends
/// up with a different size, it will align the child based on [alignment].
/// If the box cannot expand enough to accommodate the entire child, the
/// child will be clipped.
///
/// In debug mode, if the child overflows the box, a warning will be printed on
/// the console, and black and yellow striped areas will appear where the
/// overflow occurs.
///
/// This [RenderBox] can be used to allow the child to enforce some of its
/// intrinsic sizing rules, partially disregard the constraints set by its
/// parent render object, and display a warning in debug mode if the parent
/// render object fails to provide enough space.
///
/// See also:
///
/// * [ConstraintsTransformBox], the widget that makes use of this
/// [RenderObject] and exposes the same functionality.
/// * [RenderConstrainedBox], which renders a box which imposes constraints
/// on its child.
/// * [RenderConstrainedOverflowBox], which renders a box that imposes different
/// constraints on its child than it gets from its parent, possibly allowing
/// the child to overflow the parent.
/// * [RenderUnconstrainedBox] which allows its children to render themselves
/// unconstrained, expands to fit them, and considers overflow to be an error.
class RenderConstraintsTransformBox extends RenderAligningShiftedBox with DebugOverflowIndicatorMixin {
/// Create a render object that sizes itself to the child and modifies the
/// [constraints] before passing it down to that child.
/// * [RenderSizedOverflowBox], a render object that is a specific size but
/// passes its original constraints through to its child, which it allows to
/// overflow.
class RenderUnconstrainedBox extends RenderAligningShiftedBox with DebugOverflowIndicatorMixin {
/// Create a render object that sizes itself to the child but does not
/// pass the [constraints] down to that child.
///
/// The [alignment] and [clipBehavior] must not be null.
RenderConstraintsTransformBox({
/// The [alignment] must not be null.
RenderUnconstrainedBox({
@required AlignmentGeometry alignment,
@required TextDirection textDirection,
@required BoxConstraintsTransform constraintsTransform,
Axis constrainedAxis,
RenderBox child,
Clip clipBehavior = Clip.none,
}) : assert(alignment != null),
assert(clipBehavior != null),
_constraintsTransform = constraintsTransform,
_constrainedAxis = constrainedAxis,
_clipBehavior = clipBehavior,
super.mixin(alignment, textDirection, child);
/// @{macro flutter.widgets.constraintsTransform}
BoxConstraintsTransform get constraintsTransform => _constraintsTransform;
BoxConstraintsTransform _constraintsTransform;
set constraintsTransform(BoxConstraintsTransform value) {
if (_constraintsTransform == value)
/// The axis to retain constraints on, if any.
///
/// If not set, or set to null (the default), neither axis will retain its
/// constraints. If set to [Axis.vertical], then vertical constraints will
/// be retained, and if set to [Axis.horizontal], then horizontal constraints
/// will be retained.
Axis get constrainedAxis => _constrainedAxis;
Axis _constrainedAxis;
set constrainedAxis(Axis value) {
if (_constrainedAxis == value)
return;
_constraintsTransform = value;
_constrainedAxis = value;
markNeedsLayout();
}
@ -677,10 +672,21 @@ class RenderConstraintsTransformBox extends RenderAligningShiftedBox with DebugO
void performLayout() {
final BoxConstraints constraints = this.constraints;
if (child != null) {
assert(constraintsTransform != null);
final BoxConstraints childConstraints = constraintsTransform(constraints);
assert(childConstraints != null);
assert(childConstraints.isNormalized, '$childConstraints is not normalized');
// Let the child lay itself out at it's "natural" size, but if
// constrainedAxis is non-null, keep any constraints on that axis.
BoxConstraints childConstraints;
if (constrainedAxis != null) {
switch (constrainedAxis) {
case Axis.horizontal:
childConstraints = BoxConstraints(maxWidth: constraints.maxWidth, minWidth: constraints.minWidth);
break;
case Axis.vertical:
childConstraints = BoxConstraints(maxHeight: constraints.maxHeight, minHeight: constraints.minHeight);
break;
}
} else {
childConstraints = const BoxConstraints();
}
child.layout(childConstraints, parentUsesSize: true);
size = constraints.constrain(child.size);
alignChild();
@ -735,78 +741,6 @@ class RenderConstraintsTransformBox extends RenderAligningShiftedBox with DebugO
}
}
/// Renders a box, imposing no constraints on its child, allowing the child to
/// render at its "natural" size.
///
/// This allows a child to render at the size it would render if it were alone
/// on an infinite canvas with no constraints. This box will then attempt to
/// adopt the same size, within the limits of its own constraints. If it ends
/// up with a different size, it will align the child based on [alignment].
/// If the box cannot expand enough to accommodate the entire child, the
/// child will be clipped.
///
/// In debug mode, if the child overflows the box, a warning will be printed on
/// the console, and black and yellow striped areas will appear where the
/// overflow occurs.
///
/// See also:
///
/// * [RenderConstrainedBox], which renders a box which imposes constraints
/// on its child.
/// * [RenderConstrainedOverflowBox], which renders a box that imposes different
/// constraints on its child than it gets from its parent, possibly allowing
/// the child to overflow the parent.
/// * [RenderSizedOverflowBox], a render object that is a specific size but
/// passes its original constraints through to its child, which it allows to
/// overflow.
class RenderUnconstrainedBox extends RenderConstraintsTransformBox {
/// Create a render object that sizes itself to the child but does not
/// pass the [constraints] down to that child.
///
/// The [alignment] and [clipBehavior] must not be null.
RenderUnconstrainedBox({
@required AlignmentGeometry alignment,
@required TextDirection textDirection,
Axis constrainedAxis,
RenderBox child,
Clip clipBehavior = Clip.none,
}) : assert(alignment != null),
assert(clipBehavior != null),
_constrainedAxis = constrainedAxis,
super(alignment: alignment, textDirection: textDirection, child: child, clipBehavior: clipBehavior, constraintsTransform: null) {
_constraintsTransform = _convertAxis;
}
/// The axis to retain constraints on, if any.
///
/// If not set, or set to null (the default), neither axis will retain its
/// constraints. If set to [Axis.vertical], then vertical constraints will
/// be retained, and if set to [Axis.horizontal], then horizontal constraints
/// will be retained.
Axis get constrainedAxis => _constrainedAxis;
Axis _constrainedAxis;
set constrainedAxis(Axis value) {
if (_constrainedAxis == value)
return;
_constrainedAxis = value;
markNeedsLayout();
}
BoxConstraints _convertAxis(BoxConstraints constriants) {
if (constrainedAxis == null) {
return const BoxConstraints();
}
switch (constrainedAxis) {
case Axis.horizontal:
return constraints.copyWith(maxHeight: double.infinity, minHeight: 0);
case Axis.vertical:
return constraints.copyWith(maxWidth: double.infinity, minWidth: 0);
}
assert(false);
return null;
}
}
/// A render object that is a specific size but passes its original constraints
/// through to its child, which it allows to overflow.
///

View file

@ -30,7 +30,6 @@ export 'package:flutter/rendering.dart' show
AlignmentGeometryTween,
Axis,
BoxConstraints,
BoxConstraintsTransform,
CrossAxisAlignment,
CustomClipper,
CustomPainter,
@ -2219,114 +2218,6 @@ class ConstrainedBox extends SingleChildRenderObjectWidget {
}
}
/// A widget that applies an arbitary transform to its constraints, and sizes
/// its child using the resulting [BoxConstraints], treating any overflow
/// as error.
///
/// This container sizes its child using a [BoxConstraints] created by applying
/// [constraintsTransform] to its own constraints. This container will then
/// attempt to adopt the same size, within the limits of its own constraints. If
/// it ends up with a different size, it will align the child based on
/// [alignment]. If the container cannot expand enough to accommodate the entire
/// child, the child will be clipped if [clipBehavior] is not [Clip.none].
///
/// In debug mode, if the child overflows the container, a warning will be
/// printed on the console, and black and yellow striped areas will appear where
/// the overflow occurs.
///
/// {@tool snippet}
/// This snippet guarantees the child [Card] will be at least as tall as its
/// intrinsic height. Unlike [UnconstrainedBox], the child can be taller if the
/// the parent's minHeight is constrained. If parent container's maxHeight is
/// less than [Card]'s intrinsic height, in debug mode a warning will be given.
///
/// ```dart
/// ConstraintsTransformBox(
/// constraintsTransform: (BoxConstraints constraints) => constraints.copyWith(maxHeight: double.infinity),
/// child: const Card(child: Text('Hello World!')),
/// )
/// ```
/// {@end-tool}
///
/// See also:
///
/// * [ConstrainedBox], which renders a box which imposes constraints
/// on its child.
/// * [OverflowBox], a widget that imposes additional constraints on its child,
/// and allows the child to overflow itself.
/// * [UnconstrainedBox] which allows its children to render themselves
/// unconstrained, expands to fit them, and considers overflow to be an error.
class ConstraintsTransformBox extends SingleChildRenderObjectWidget {
/// Creates a widget that uses a function to transform the constraints it
/// passes to its child. If the child overflows the parent's constraints, a
/// warning will be given in debug mode.
///
/// The `alignment`, `clipBehavior` and `constraintsTransform` arguments must
/// not be null.
const ConstraintsTransformBox({
Key key,
Widget child,
this.textDirection,
this.alignment = Alignment.center,
this.constraintsTransform,
this.clipBehavior = Clip.hardEdge,
}) : assert(alignment != null),
assert(clipBehavior != null),
assert(constraintsTransform != null),
super(key: key, child: child);
/// The text direction to use when interpreting the [alignment] if it is an
/// [AlignmentDirectional].
///
/// Defaults to null, in which case [Directionality.of] is used to determine
/// the text direction.
final TextDirection textDirection;
/// The alignment to use when laying out the child, if it has a different size
/// than this widget.
///
/// If this is an [AlignmentDirectional], then [textDirection] must not be
/// null.
///
/// See also:
///
/// * [Alignment] for non-[Directionality]-aware alignments.
/// * [AlignmentDirectional] for [Directionality]-aware alignments.
final AlignmentGeometry alignment;
/// @{template flutter.widgets.constraintsTransform}
/// The function used to transform the incoming [BoxConstraints], to impose on
/// [child].
///
/// Must not be null. The function must return a non-null and normalized
/// [BoxConstraints].
/// @{endtemplate}
final BoxConstraintsTransform constraintsTransform;
// TODO(liyuqian): defaults to [Clip.none] once Google references are updated.
/// {@macro flutter.widgets.Clip}
///
/// Defaults to [Clip.hardEdge].
final Clip clipBehavior;
@override
void updateRenderObject(BuildContext context, covariant RenderConstraintsTransformBox renderObject) {
renderObject
..textDirection = textDirection ?? Directionality.of(context)
..constraintsTransform = constraintsTransform
..alignment = alignment
..clipBehavior = clipBehavior;
}
@override
RenderConstraintsTransformBox createRenderObject(BuildContext context) => RenderConstraintsTransformBox(
textDirection: textDirection ?? Directionality.of(context),
alignment: alignment,
constraintsTransform: constraintsTransform,
clipBehavior: clipBehavior,
);
}
/// A widget that imposes no constraints on its child, allowing it to render
/// at its "natural" size.
///
@ -2351,20 +2242,20 @@ class ConstraintsTransformBox extends SingleChildRenderObjectWidget {
/// * [OverflowBox], a widget that imposes different constraints on its child
/// than it gets from its parent, possibly allowing the child to overflow
/// the parent.
class UnconstrainedBox extends StatelessWidget {
class UnconstrainedBox extends SingleChildRenderObjectWidget {
/// Creates a widget that imposes no constraints on its child, allowing it to
/// render at its "natural" size. If the child overflows the parents
/// constraints, a warning will be given in debug mode.
const UnconstrainedBox({
Key key,
this.child,
Widget child,
this.textDirection,
this.alignment = Alignment.center,
this.constrainedAxis,
this.clipBehavior = Clip.hardEdge,
}) : assert(alignment != null),
assert(clipBehavior != null),
super(key: key);
super(key: key, child: child);
/// The text direction to use when interpreting the [alignment] if it is an
/// [AlignmentDirectional].
@ -2395,39 +2286,22 @@ class UnconstrainedBox extends StatelessWidget {
/// Defaults to [Clip.hardEdge].
final Clip clipBehavior;
/// The widget below this widget in the tree.
///
/// {@macro flutter.widgets.child}
final Widget child;
static BoxConstraints _unconstrained(BoxConstraints constraints) => const BoxConstraints();
static BoxConstraints _widthConstrained(BoxConstraints constraints) => constraints.widthConstraints();
static BoxConstraints _heightConstrained(BoxConstraints constraints) => constraints.heightConstraints();
@override
void updateRenderObject(BuildContext context, covariant RenderUnconstrainedBox renderObject) {
renderObject
..textDirection = textDirection ?? Directionality.of(context)
..alignment = alignment
..constrainedAxis = constrainedAxis
..clipBehavior = clipBehavior;
}
@override
Widget build(BuildContext context) {
BoxConstraintsTransform constraintsTransform;
if (constrainedAxis != null) {
switch (constrainedAxis) {
case Axis.horizontal:
constraintsTransform = _widthConstrained;
break;
case Axis.vertical:
constraintsTransform = _heightConstrained;
break;
}
}
constraintsTransform ??= _unconstrained;
return ConstraintsTransformBox(
child: child,
RenderUnconstrainedBox createRenderObject(BuildContext context) => RenderUnconstrainedBox(
textDirection: textDirection ?? Directionality.of(context),
alignment: alignment,
constrainedAxis: constrainedAxis,
clipBehavior: clipBehavior,
constraintsTransform: constraintsTransform,
);
}
@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {

View file

@ -2397,9 +2397,6 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien
: null;
}
static BoxConstraints _unmodified(BoxConstraints constraints) => constraints;
static BoxConstraints _removeMaxHeightConstraint(BoxConstraints constraints) => constraints.copyWith(maxHeight: double.infinity);
@override
Widget build(BuildContext context) {
assert(debugCheckHasMediaQuery(context));
@ -2407,12 +2404,7 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien
super.build(context); // See AutomaticKeepAliveClientMixin.
final TextSelectionControls controls = widget.selectionControls;
final bool ignoreOverflow = _isMultiline || widget.clipBehavior == Clip.none;
return ConstraintsTransformBox(
constraintsTransform: ignoreOverflow ? _unmodified : _removeMaxHeightConstraint,
clipBehavior: widget.clipBehavior,
child: MouseRegion(
return MouseRegion(
cursor: widget.mouseCursor ?? SystemMouseCursors.text,
child: Scrollable(
excludeFromSemantics: true,
@ -2481,7 +2473,6 @@ class EditableTextState extends State<EditableText> with AutomaticKeepAliveClien
);
},
),
),
);
}

View file

@ -380,74 +380,6 @@ void main() {
expect(unconstrained.getMaxIntrinsicWidth(100.0), equals(200.0));
});
group('ConstraintsTransfromBox', () {
FlutterErrorDetails firstErrorDetails;
void exhaustErrors() {
FlutterErrorDetails next;
do {
next = renderer.takeFlutterErrorDetails();
firstErrorDetails ??= next;
} while (next != null);
}
tearDown(() {
firstErrorDetails = null;
});
test('throws if the resulting constraints are not normalized', () {
final RenderConstrainedBox child = RenderConstrainedBox(additionalConstraints: const BoxConstraints.tightFor(height: 0));
final RenderConstraintsTransformBox box = RenderConstraintsTransformBox(
alignment: Alignment.center,
textDirection: TextDirection.ltr,
constraintsTransform: (BoxConstraints constraints) => const BoxConstraints(maxHeight: -1, minHeight: 200),
child: child,
);
layout(box, constraints: const BoxConstraints(), onErrors: exhaustErrors);
expect(firstErrorDetails?.toString(), contains('is not normalized'));
});
test('overflow is reported when insufficient size is given', () {
final RenderConstrainedBox child = RenderConstrainedBox(additionalConstraints: const BoxConstraints.tightFor(width: double.maxFinite));
final RenderConstraintsTransformBox box = RenderConstraintsTransformBox(
alignment: Alignment.center,
textDirection: TextDirection.ltr,
constraintsTransform: (BoxConstraints constraints) => constraints.copyWith(maxWidth: double.infinity),
child: child,
);
// No error reported.
layout(box, constraints: const BoxConstraints(), phase: EnginePhase.composite, onErrors: expectOverflowedErrors);
});
test('throws when null is returned by the transform function', () {
final RenderConstrainedBox child = RenderConstrainedBox(additionalConstraints: const BoxConstraints.tightFor(width: 200));
final RenderConstraintsTransformBox box = RenderConstraintsTransformBox(
alignment: Alignment.center,
textDirection: TextDirection.ltr,
constraintsTransform: (BoxConstraints constraints) => null,
child: child,
);
layout(box, constraints: const BoxConstraints(), onErrors: exhaustErrors);
expect(firstErrorDetails.toString(), contains('!= null'));
});
test("the transform function can't be set to null", () {
final RenderConstrainedBox child = RenderConstrainedBox(additionalConstraints: const BoxConstraints.tightFor(width: 200));
final RenderConstraintsTransformBox box = RenderConstraintsTransformBox(
alignment: Alignment.center,
textDirection: TextDirection.ltr,
constraintsTransform: null,
child: child,
);
layout(box, constraints: const BoxConstraints(), onErrors: exhaustErrors);
expect(firstErrorDetails.toString(), contains('!= null'));
});
});
test ('getMinIntrinsicWidth error handling', () {
final RenderUnconstrainedBox unconstrained = RenderUnconstrainedBox(
textDirection: TextDirection.ltr,

View file

@ -38,7 +38,7 @@ void main() {
final dynamic exception = tester.takeException();
expect(exception, isFlutterError);
expect(exception.diagnostics.first.level, DiagnosticLevel.summary);
expect(exception.diagnostics.first.toString(), startsWith('A RenderConstraintsTransformBox overflowed by '));
expect(exception.diagnostics.first.toString(), startsWith('A RenderUnconstrainedBox overflowed by '));
expect(find.byType(UnconstrainedBox), paints..rect());
await tester.pumpWidget(

View file

@ -339,7 +339,7 @@ void main() {
testWidgets('UnconstrainedBox can set and update clipBehavior', (WidgetTester tester) async {
await tester.pumpWidget(const UnconstrainedBox());
final RenderConstraintsTransformBox renderObject = tester.allRenderObjects.whereType<RenderConstraintsTransformBox>().first;
final RenderUnconstrainedBox renderObject = tester.allRenderObjects.whereType<RenderUnconstrainedBox>().first;
expect(renderObject.clipBehavior, equals(Clip.hardEdge));
await tester.pumpWidget(const UnconstrainedBox(clipBehavior: Clip.antiAlias));

View file

@ -5385,130 +5385,6 @@ void main() {
expectToAssert(const TextEditingValue(text: 'test', composing: TextRange(start: -1, end: 9)), false);
});
testWidgets('shows overflow indicator for single line text with insufficient height', (WidgetTester tester) async {
await tester.pumpWidget(MediaQuery(
data: const MediaQueryData(devicePixelRatio: 1.0),
child: Directionality(
textDirection: TextDirection.ltr,
child: Center(
child: SizedBox(
height: 10,
child: EditableText(
maxLines: 1,
backgroundCursorColor: Colors.grey,
controller: controller,
focusNode: focusNode,
style: textStyle,
cursorColor: cursorColor,
),
),
),
),
));
final dynamic exception = tester.takeException();
expect(exception, isFlutterError);
expect(exception.diagnostics.first.level, DiagnosticLevel.summary);
expect(exception.diagnostics.first.toString(), startsWith('A RenderConstraintsTransformBox overflowed by '));
// Can be fixed by given enough height;
await tester.pumpWidget(MediaQuery(
data: const MediaQueryData(devicePixelRatio: 1.0),
child: Directionality(
textDirection: TextDirection.ltr,
child: Center(
child: SizedBox(
height: 10,
child: EditableText(
maxLines: 1,
backgroundCursorColor: Colors.grey,
controller: controller,
focusNode: focusNode,
style: textStyle,
cursorColor: cursorColor,
),
),
),
),
));
expect(tester.takeException(), isNull);
});
testWidgets('No overflow indicator for multiline line text or no clipping', (WidgetTester tester) async {
await tester.pumpWidget(MediaQuery(
data: const MediaQueryData(devicePixelRatio: 1.0),
child: Directionality(
textDirection: TextDirection.ltr,
child: Center(
child: SizedBox(
height: 10,
child: EditableText(
maxLines: 1,
backgroundCursorColor: Colors.grey,
controller: controller,
focusNode: focusNode,
style: textStyle,
cursorColor: cursorColor,
clipBehavior: Clip.none,
),
),
),
),
));
expect(tester.takeException(), isNull);
await tester.pumpWidget(MediaQuery(
data: const MediaQueryData(devicePixelRatio: 1.0),
child: Directionality(
textDirection: TextDirection.ltr,
child: Center(
child: SizedBox(
height: 50,
child: EditableText(
backgroundCursorColor: Colors.grey,
controller: controller,
focusNode: focusNode,
style: textStyle,
cursorColor: cursorColor,
),
),
),
),
));
expect(tester.takeException(), isNull);
});
testWidgets('RenderEditable can stretch vertically', (WidgetTester tester) async {
await tester.pumpWidget(MediaQuery(
data: const MediaQueryData(devicePixelRatio: 1.0),
child: Directionality(
textDirection: TextDirection.ltr,
child: Center(
child: SizedBox(
height: 400,
child: EditableText(
maxLines: 1,
backgroundCursorColor: Colors.grey,
controller: controller,
focusNode: focusNode,
style: textStyle,
cursorColor: cursorColor,
),
),
),
),
));
final dynamic exception = tester.takeException();
expect(exception, isNull);
final EditableTextState state = tester.state(find.byType(EditableText));
expect(state.renderEditable.size.height, 400);
});
// Regression test for https://github.com/flutter/flutter/issues/65374.
testWidgets('Length formatter will not cause crash while the TextEditingValue is composing', (WidgetTester tester) async {
final TextInputFormatter formatter = LengthLimitingTextInputFormatter(5);

View file

@ -632,11 +632,11 @@ void main() {
),
children: <InlineSpan>[
WidgetSpan(
child: SizedBox(width: 70, height: 55, child: TextField()),
child: SizedBox(width: 70, height: 25, child: TextField()),
),
TextSpan(text: ', and my favorite city is: ', style: TextStyle(fontSize: 20)),
WidgetSpan(
child: SizedBox(width: 70, height: 55, child: TextField()),
child: SizedBox(width: 70, height: 25, child: TextField()),
),
],
),
@ -743,7 +743,7 @@ void main() {
),
TextSpan(text: 'outer', style: TextStyle(fontSize: 20)),
WidgetSpan(
child: SizedBox(width: 70, height: 55, child: TextField()),
child: SizedBox(width: 70, height: 25, child: TextField()),
),
WidgetSpan(
child: SizedBox(

View file

@ -570,7 +570,7 @@ void main() {
),
),
Container(
height: 40.0,
height: 25.0,
child: EditableText(
key: const ValueKey<String>('text3'),
controller: TextEditingController(text: 'Hello3'),
@ -581,14 +581,14 @@ void main() {
),
),
Container(
height: 40.0,
height: 25.0,
child: TextField(
key: const ValueKey<String>('text4'),
controller: TextEditingController(text: 'Hello4'),
),
),
Container(
height: 40.0,
height: 25.0,
child: TextFormField(
key: const ValueKey<String>('text5'),
controller: TextEditingController(text: 'Hello5'),