mirror of
https://github.com/flutter/flutter
synced 2024-10-12 11:12:54 +00:00
Fix computeMinIntrinsicHeight in _RenderDecoration (#87404)
This commit is contained in:
parent
6458a478b2
commit
5cf62e8445
1
AUTHORS
1
AUTHORS
|
@ -83,3 +83,4 @@ Mirko Mucaria <skogsfrae@gmail.com>
|
|||
Karol Czeryna <karol.czeryna@gmail.com>
|
||||
Callum Moffat <callum@moffatman.com>
|
||||
Koutaro Mori <koutaro.mo@gmail.com>
|
||||
Sergei Smitskoi <sergflutterdev@gmail.com>
|
||||
|
|
|
@ -971,11 +971,17 @@ class _RenderDecoration extends RenderBox {
|
|||
final BoxConstraints boxConstraints = layoutConstraints.loosen();
|
||||
|
||||
// Layout all the widgets used by InputDecorator
|
||||
boxToBaseline[prefix] = _layoutLineBox(prefix, boxConstraints);
|
||||
boxToBaseline[suffix] = _layoutLineBox(suffix, boxConstraints);
|
||||
boxToBaseline[icon] = _layoutLineBox(icon, boxConstraints);
|
||||
boxToBaseline[prefixIcon] = _layoutLineBox(prefixIcon, boxConstraints);
|
||||
boxToBaseline[suffixIcon] = _layoutLineBox(suffixIcon, boxConstraints);
|
||||
final BoxConstraints containerConstraints = boxConstraints.copyWith(
|
||||
maxWidth: boxConstraints.maxWidth - _boxSize(icon).width,
|
||||
);
|
||||
boxToBaseline[prefixIcon] = _layoutLineBox(prefixIcon, containerConstraints);
|
||||
boxToBaseline[suffixIcon] = _layoutLineBox(suffixIcon, containerConstraints);
|
||||
final BoxConstraints contentConstraints = containerConstraints.copyWith(
|
||||
maxWidth: containerConstraints.maxWidth - contentPadding.horizontal,
|
||||
);
|
||||
boxToBaseline[prefix] = _layoutLineBox(prefix, contentConstraints);
|
||||
boxToBaseline[suffix] = _layoutLineBox(suffix, contentConstraints);
|
||||
|
||||
final double inputWidth = math.max(
|
||||
0.0,
|
||||
|
@ -1011,18 +1017,14 @@ class _RenderDecoration extends RenderBox {
|
|||
hint,
|
||||
boxConstraints.copyWith(minWidth: inputWidth, maxWidth: inputWidth),
|
||||
);
|
||||
boxToBaseline[counter] = _layoutLineBox(counter, boxConstraints);
|
||||
boxToBaseline[counter] = _layoutLineBox(counter, contentConstraints);
|
||||
|
||||
// The helper or error text can occupy the full width less the space
|
||||
// occupied by the icon and counter.
|
||||
boxToBaseline[helperError] = _layoutLineBox(
|
||||
helperError,
|
||||
boxConstraints.copyWith(
|
||||
maxWidth: math.max(0.0, boxConstraints.maxWidth
|
||||
- _boxSize(icon).width
|
||||
- _boxSize(counter).width
|
||||
- contentPadding.horizontal,
|
||||
),
|
||||
contentConstraints.copyWith(
|
||||
maxWidth: math.max(0.0, contentConstraints.maxWidth - _boxSize(counter).width),
|
||||
),
|
||||
);
|
||||
|
||||
|
@ -1267,15 +1269,45 @@ class _RenderDecoration extends RenderBox {
|
|||
|
||||
@override
|
||||
double computeMinIntrinsicHeight(double width) {
|
||||
double subtextHeight = _lineHeight(width, <RenderBox?>[helperError, counter]);
|
||||
final double iconHeight = _minHeight(icon, width);
|
||||
final double iconWidth = _minWidth(icon, iconHeight);
|
||||
|
||||
width = math.max(width - iconWidth, 0.0);
|
||||
|
||||
final double prefixIconHeight = _minHeight(prefixIcon, width);
|
||||
final double prefixIconWidth = _minWidth(prefixIcon, prefixIconHeight);
|
||||
|
||||
final double suffixIconHeight = _minHeight(suffixIcon, width);
|
||||
final double suffixIconWidth = _minWidth(suffixIcon, suffixIconHeight);
|
||||
|
||||
width = math.max(width - contentPadding.horizontal, 0.0);
|
||||
|
||||
final double counterHeight = _minHeight(counter, width);
|
||||
final double counterWidth = _minWidth(counter, counterHeight);
|
||||
|
||||
final double helperErrorAvailableWidth = math.max(width - counterWidth, 0.0);
|
||||
final double helperErrorHeight = _minHeight(helperError, helperErrorAvailableWidth);
|
||||
double subtextHeight = math.max(counterHeight, helperErrorHeight);
|
||||
if (subtextHeight > 0.0)
|
||||
subtextHeight += subtextGap;
|
||||
|
||||
final double prefixHeight = _minHeight(prefix, width);
|
||||
final double prefixWidth = _minWidth(prefix, prefixHeight);
|
||||
|
||||
final double suffixHeight = _minHeight(suffix, width);
|
||||
final double suffixWidth = _minWidth(suffix, suffixHeight);
|
||||
|
||||
final double availableInputWidth = math.max(width - prefixWidth - suffixWidth - prefixIconWidth - suffixIconWidth, 0.0);
|
||||
final double inputHeight = _lineHeight(availableInputWidth, <RenderBox?>[input, hint]);
|
||||
final double inputMaxHeight = <double>[inputHeight, prefixHeight, suffixHeight].reduce(math.max);
|
||||
|
||||
final Offset densityOffset = decoration.visualDensity!.baseSizeAdjustment;
|
||||
final double containerHeight = contentPadding.top
|
||||
final double contentHeight = contentPadding.top
|
||||
+ (label == null ? 0.0 : decoration.floatingLabelHeight)
|
||||
+ _lineHeight(width, <RenderBox?>[prefix, input, suffix])
|
||||
+ inputMaxHeight
|
||||
+ contentPadding.bottom
|
||||
+ densityOffset.dy;
|
||||
final double containerHeight = <double>[iconHeight, contentHeight, prefixIconHeight, suffixIconHeight].reduce(math.max);
|
||||
final double minContainerHeight = decoration.isDense! || expands
|
||||
? 0.0
|
||||
: kMinInteractiveDimension;
|
||||
|
|
|
@ -5023,6 +5023,146 @@ void main() {
|
|||
expect(tester.takeException(), isNull);
|
||||
});
|
||||
|
||||
testWidgets('min intrinsic height for TextField with prefix icon', (WidgetTester tester) async {
|
||||
// Regression test for: https://github.com/flutter/flutter/issues/87403
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
home: Material(
|
||||
child: Center(
|
||||
child: SizedBox(
|
||||
width: 100.0,
|
||||
child: IntrinsicHeight(
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
TextField(
|
||||
controller: TextEditingController(text: 'input'),
|
||||
maxLines: null,
|
||||
decoration: const InputDecoration(
|
||||
prefixIcon: Icon(Icons.search),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
||||
|
||||
expect(tester.takeException(), isNull);
|
||||
});
|
||||
|
||||
testWidgets('min intrinsic height for TextField with suffix icon', (WidgetTester tester) async {
|
||||
// Regression test for: https://github.com/flutter/flutter/issues/87403
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
home: Material(
|
||||
child: Center(
|
||||
child: SizedBox(
|
||||
width: 100.0,
|
||||
child: IntrinsicHeight(
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
TextField(
|
||||
controller: TextEditingController(text: 'input'),
|
||||
maxLines: null,
|
||||
decoration: const InputDecoration(
|
||||
suffixIcon: Icon(Icons.search),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
||||
|
||||
expect(tester.takeException(), isNull);
|
||||
});
|
||||
|
||||
testWidgets('min intrinsic height for TextField with prefix', (WidgetTester tester) async {
|
||||
// Regression test for: https://github.com/flutter/flutter/issues/87403
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
home: Material(
|
||||
child: Center(
|
||||
child: SizedBox(
|
||||
width: 100.0,
|
||||
child: IntrinsicHeight(
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
TextField(
|
||||
controller: TextEditingController(text: 'input'),
|
||||
maxLines: null,
|
||||
decoration: const InputDecoration(
|
||||
prefix: Text('prefix'),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
||||
|
||||
expect(tester.takeException(), isNull);
|
||||
});
|
||||
|
||||
testWidgets('min intrinsic height for TextField with suffix', (WidgetTester tester) async {
|
||||
// Regression test for: https://github.com/flutter/flutter/issues/87403
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
home: Material(
|
||||
child: Center(
|
||||
child: SizedBox(
|
||||
width: 100.0,
|
||||
child: IntrinsicHeight(
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
TextField(
|
||||
controller: TextEditingController(text: 'input'),
|
||||
maxLines: null,
|
||||
decoration: const InputDecoration(
|
||||
suffix: Text('suffix'),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
||||
|
||||
expect(tester.takeException(), isNull);
|
||||
});
|
||||
|
||||
testWidgets('min intrinsic height for TextField with icon', (WidgetTester tester) async {
|
||||
// Regression test for: https://github.com/flutter/flutter/issues/87403
|
||||
await tester.pumpWidget(MaterialApp(
|
||||
home: Material(
|
||||
child: Center(
|
||||
child: SizedBox(
|
||||
width: 100.0,
|
||||
child: IntrinsicHeight(
|
||||
child: Column(
|
||||
children: <Widget>[
|
||||
TextField(
|
||||
controller: TextEditingController(text: 'input'),
|
||||
maxLines: null,
|
||||
decoration: const InputDecoration(
|
||||
icon: Icon(Icons.search),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
));
|
||||
|
||||
expect(tester.takeException(), isNull);
|
||||
});
|
||||
|
||||
testWidgets('InputDecorationTheme floatingLabelStyle overrides label widget styles when the widget is a text widget (focused)', (WidgetTester tester) async {
|
||||
const TextStyle style16 = TextStyle(fontFamily: 'Ahem', fontSize: 16.0);
|
||||
final TextStyle floatingLabelStyle = style16.merge(const TextStyle(color: Colors.indigo));
|
||||
|
|
Loading…
Reference in a new issue