mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Fix intrinsic width of input decorator (#138074)
Fix min intrinsic width of input decorator by removing left or right padding when `prefixIcon` or `suffixIcon` are used. Fixes #137937.
This commit is contained in:
parent
e49cc81222
commit
ad62645fce
@ -1224,25 +1224,25 @@ class _RenderDecoration extends RenderBox with SlottedContainerRenderObjectMixin
|
||||
@override
|
||||
double computeMinIntrinsicWidth(double height) {
|
||||
return _minWidth(icon, height)
|
||||
+ contentPadding.left
|
||||
+ (prefixIcon != null ? 0.0 : (textDirection == TextDirection.ltr ? contentPadding.left : contentPadding.right))
|
||||
+ _minWidth(prefixIcon, height)
|
||||
+ _minWidth(prefix, height)
|
||||
+ math.max(_minWidth(input, height), _minWidth(hint, height))
|
||||
+ _minWidth(suffix, height)
|
||||
+ _minWidth(suffixIcon, height)
|
||||
+ contentPadding.right;
|
||||
+ (suffixIcon != null ? 0.0 : (textDirection == TextDirection.ltr ? contentPadding.right : contentPadding.left));
|
||||
}
|
||||
|
||||
@override
|
||||
double computeMaxIntrinsicWidth(double height) {
|
||||
return _maxWidth(icon, height)
|
||||
+ contentPadding.left
|
||||
+ (prefixIcon != null ? 0.0 : (textDirection == TextDirection.ltr ? contentPadding.left : contentPadding.right))
|
||||
+ _maxWidth(prefixIcon, height)
|
||||
+ _maxWidth(prefix, height)
|
||||
+ math.max(_maxWidth(input, height), _maxWidth(hint, height))
|
||||
+ _maxWidth(suffix, height)
|
||||
+ _maxWidth(suffixIcon, height)
|
||||
+ contentPadding.right;
|
||||
+ (suffixIcon != null ? 0.0 : (textDirection == TextDirection.ltr ? contentPadding.right : contentPadding.left));
|
||||
}
|
||||
|
||||
double _lineHeight(double width, List<RenderBox?> boxes) {
|
||||
|
||||
@ -26,6 +26,7 @@ Widget buildInputDecorator({
|
||||
bool isFocused = false,
|
||||
bool isHovering = false,
|
||||
bool useMaterial3 = false,
|
||||
bool useIntrinsicWidth = false,
|
||||
TextStyle? baseStyle,
|
||||
TextAlignVertical? textAlignVertical,
|
||||
VisualDensity? visualDensity,
|
||||
@ -34,6 +35,21 @@ Widget buildInputDecorator({
|
||||
style: TextStyle(fontSize: 16.0),
|
||||
),
|
||||
}) {
|
||||
Widget widget = InputDecorator(
|
||||
expands: expands,
|
||||
decoration: decoration,
|
||||
isEmpty: isEmpty,
|
||||
isFocused: isFocused,
|
||||
isHovering: isHovering,
|
||||
baseStyle: baseStyle,
|
||||
textAlignVertical: textAlignVertical,
|
||||
child: child,
|
||||
);
|
||||
|
||||
if (useIntrinsicWidth) {
|
||||
widget = IntrinsicWidth(child: widget);
|
||||
}
|
||||
|
||||
return MaterialApp(
|
||||
theme: ThemeData(useMaterial3: false),
|
||||
home: Material(
|
||||
@ -50,16 +66,7 @@ Widget buildInputDecorator({
|
||||
alignment: Alignment.topLeft,
|
||||
child: Directionality(
|
||||
textDirection: textDirection,
|
||||
child: InputDecorator(
|
||||
expands: expands,
|
||||
decoration: decoration,
|
||||
isEmpty: isEmpty,
|
||||
isFocused: isFocused,
|
||||
isHovering: isHovering,
|
||||
baseStyle: baseStyle,
|
||||
textAlignVertical: textAlignVertical,
|
||||
child: child,
|
||||
),
|
||||
child: widget,
|
||||
),
|
||||
),
|
||||
);
|
||||
@ -6890,6 +6897,48 @@ testWidgetsWithLeakTracking('OutlineInputBorder with BorderRadius.zero should dr
|
||||
expect(decoratorRight, lessThanOrEqualTo(prefixRight));
|
||||
});
|
||||
|
||||
testWidgetsWithLeakTracking('instrinic width with prefixIcon/suffixIcon', (WidgetTester tester) async {
|
||||
// Regression test for https://github.com/flutter/flutter/issues/137937
|
||||
for (final TextDirection direction in TextDirection.values) {
|
||||
Future<Size> measureText(InputDecoration decoration) async {
|
||||
await tester.pumpWidget(
|
||||
buildInputDecorator(
|
||||
useMaterial3: useMaterial3,
|
||||
// isEmpty: false (default)
|
||||
// isFocused: false (default)
|
||||
decoration: decoration,
|
||||
useIntrinsicWidth: true,
|
||||
textDirection: direction,
|
||||
),
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.text('text'), findsOneWidget);
|
||||
|
||||
return tester.renderObject<RenderBox>(find.text('text')).size;
|
||||
}
|
||||
|
||||
const EdgeInsetsGeometry padding = EdgeInsetsDirectional.only(end: 24, start: 12);
|
||||
|
||||
final Size textSizeWithoutIcons = await measureText(const InputDecoration(
|
||||
contentPadding: padding,
|
||||
));
|
||||
|
||||
final Size textSizeWithPrefixIcon = await measureText(const InputDecoration(
|
||||
contentPadding: padding,
|
||||
prefixIcon: Focus(child: Icon(Icons.search)),
|
||||
));
|
||||
|
||||
final Size textSizeWithSuffixIcon = await measureText(const InputDecoration(
|
||||
contentPadding: padding,
|
||||
suffixIcon: Focus(child: Icon(Icons.search)),
|
||||
));
|
||||
|
||||
expect(textSizeWithPrefixIcon.width, equals(textSizeWithoutIcons.width), reason: 'text width is different with prefixIcon and $direction');
|
||||
expect(textSizeWithSuffixIcon.width, equals(textSizeWithoutIcons.width), reason: 'text width is different with prefixIcon and $direction');
|
||||
}
|
||||
});
|
||||
|
||||
testWidgetsWithLeakTracking('InputDecorator with counter does not crash when given a 0 size', (WidgetTester tester) async {
|
||||
// Regression test for https://github.com/flutter/flutter/issues/129611
|
||||
const InputDecoration decoration = InputDecoration(
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user