Unverified Commit e00b1531 authored by Justin McCandless's avatar Justin McCandless Committed by GitHub

Reland "TextField constrained layout bug (#65966)" (#66055)

parent d65e2c3a
......@@ -1032,11 +1032,12 @@ class _RenderDecoration extends RenderBox {
counterHeight,
helperErrorHeight,
);
final Offset densityOffset = decoration.visualDensity.baseSizeAdjustment;
boxToBaseline[input] = _layoutLineBox(
input,
boxConstraints.deflate(EdgeInsets.only(
top: contentPadding.top + topHeight,
bottom: contentPadding.bottom + bottomHeight,
top: contentPadding.top + topHeight + densityOffset.dy / 2,
bottom: contentPadding.bottom + bottomHeight + densityOffset.dy / 2,
)).copyWith(
minWidth: inputWidth,
maxWidth: inputWidth,
......@@ -1065,13 +1066,15 @@ class _RenderDecoration extends RenderBox {
prefixHeight - boxToBaseline[prefix],
suffixHeight - boxToBaseline[suffix],
);
// TODO(justinmc): fixBelowInput should have no effect when there is no
// prefix/suffix below the input.
// https://github.com/flutter/flutter/issues/66050
final double fixBelowInput = math.max(
0,
fixBelowBaseline - (inputHeight - inputInternalBaseline),
);
// Calculate the height of the input text container.
final Offset densityOffset = decoration.visualDensity.baseSizeAdjustment;
final double prefixIconHeight = prefixIcon == null ? 0 : prefixIcon.size.height;
final double suffixIconHeight = suffixIcon == null ? 0 : suffixIcon.size.height;
final double fixIconHeight = math.max(prefixIconHeight, suffixIconHeight);
......@@ -1087,8 +1090,8 @@ class _RenderDecoration extends RenderBox {
);
final double minContainerHeight = decoration.isDense || decoration.isCollapsed || expands
? 0.0
: kMinInteractiveDimension + densityOffset.dy;
final double maxContainerHeight = boxConstraints.maxHeight - bottomHeight + densityOffset.dy;
: kMinInteractiveDimension;
final double maxContainerHeight = boxConstraints.maxHeight - bottomHeight;
final double containerHeight = expands
? maxContainerHeight
: math.min(math.max(contentHeight, minContainerHeight), maxContainerHeight);
......
......@@ -4235,4 +4235,80 @@ void main() {
expect(tester.getSize(find.text(labelText)).width, labelWidth);
expect(getOpacity(tester, prefixText), 1.0);
});
testWidgets('given enough space, constrained and unconstrained heights result in the same size widget', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/65572
final UniqueKey keyUnconstrained = UniqueKey();
final UniqueKey keyConstrained = UniqueKey();
Widget getInputDecorator(VisualDensity visualDensity) {
return MaterialApp(
home: Material(
child: Builder(
builder: (BuildContext context) {
return Theme(
data: Theme.of(context).copyWith(visualDensity: visualDensity),
child: Center(
child: Row(
children: <Widget>[
SizedBox(
width: 35.0,
child: TextField(
key: keyUnconstrained,
),
),
SizedBox(
width: 35.0,
// 48 is the height that this TextField would take when
// laid out with no constraints.
height: 48.0,
child: TextField(
key: keyConstrained,
),
),
],
),
),
);
},
),
),
);
}
await tester.pumpWidget(getInputDecorator(VisualDensity.standard));
final double constrainedHeight = tester.getSize(find.byKey(keyConstrained)).height;
final double unConstrainedHeight = tester.getSize(find.byKey(keyUnconstrained)).height;
expect(constrainedHeight, equals(unConstrainedHeight));
await tester.pumpWidget(getInputDecorator(VisualDensity.compact));
final double constrainedHeightCompact = tester.getSize(find.byKey(keyConstrained)).height;
final double unConstrainedHeightCompact = tester.getSize(find.byKey(keyUnconstrained)).height;
expect(constrainedHeightCompact, equals(unConstrainedHeightCompact));
});
testWidgets('A vertically constrained TextField still positions its text inside of itself', (WidgetTester tester) async {
await tester.pumpWidget(MaterialApp(
home: Material(
child: Center(
child: Container(
width: 200,
height: 28,
child: TextField(
controller: TextEditingController(text: 'A'),
),
),
),
),
));
final double textFieldTop = tester.getTopLeft(find.byType(TextField)).dy;
final double textFieldBottom = tester.getBottomLeft(find.byType(TextField)).dy;
final double textTop = tester.getTopLeft(find.text('A')).dy;
// The text is inside the field.
expect(tester.getSize(find.text('A')).height, lessThan(textFieldBottom - textFieldTop));
expect(textTop, greaterThan(textFieldTop));
expect(textTop, lessThan(textFieldBottom));
});
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment