Add Horizontal Padding to Constrained Chip Label Calculations (#31861)
* Add horizontal padding and properly constrain chip label calculations * Added regression test for avatar, label and delete icon constraint
This commit is contained in:
parent
df669ab1ea
commit
7690bb47dc
@ -2188,29 +2188,40 @@ class _RenderChip extends RenderBox {
|
|||||||
// Now that we know the label height and the width of the icons, we can
|
// Now that we know the label height and the width of the icons, we can
|
||||||
// determine how much to shrink the width constraints for the "real" layout.
|
// determine how much to shrink the width constraints for the "real" layout.
|
||||||
if (constraints.maxWidth.isFinite) {
|
if (constraints.maxWidth.isFinite) {
|
||||||
|
final double maxWidth = math.max(
|
||||||
|
0.0,
|
||||||
|
constraints.maxWidth
|
||||||
|
- iconSizes
|
||||||
|
- theme.labelPadding.horizontal
|
||||||
|
- theme.padding.horizontal,
|
||||||
|
);
|
||||||
label.layout(
|
label.layout(
|
||||||
constraints.copyWith(
|
constraints.copyWith(
|
||||||
minWidth: 0.0,
|
minWidth: 0.0,
|
||||||
maxWidth: math.max(
|
maxWidth: maxWidth,
|
||||||
0.0,
|
|
||||||
constraints.maxWidth - iconSizes - theme.labelPadding.horizontal,
|
|
||||||
),
|
|
||||||
minHeight: rawSize.height,
|
minHeight: rawSize.height,
|
||||||
maxHeight: size.height,
|
maxHeight: size.height,
|
||||||
),
|
),
|
||||||
parentUsesSize: true,
|
parentUsesSize: true,
|
||||||
);
|
);
|
||||||
} else {
|
|
||||||
label.layout(
|
final Size updatedSize = _boxSize(label);
|
||||||
BoxConstraints(
|
return Size(
|
||||||
minHeight: rawSize.height,
|
updatedSize.width + theme.labelPadding.horizontal,
|
||||||
maxHeight: size.height,
|
updatedSize.height + theme.labelPadding.vertical,
|
||||||
minWidth: 0.0,
|
|
||||||
maxWidth: size.width,
|
|
||||||
),
|
|
||||||
parentUsesSize: true,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
label.layout(
|
||||||
|
BoxConstraints(
|
||||||
|
minHeight: rawSize.height,
|
||||||
|
maxHeight: size.height,
|
||||||
|
minWidth: 0.0,
|
||||||
|
maxWidth: size.width,
|
||||||
|
),
|
||||||
|
parentUsesSize: true,
|
||||||
|
);
|
||||||
|
|
||||||
return Size(
|
return Size(
|
||||||
rawSize.width + theme.labelPadding.horizontal,
|
rawSize.width + theme.labelPadding.horizontal,
|
||||||
rawSize.height + theme.labelPadding.vertical,
|
rawSize.height + theme.labelPadding.vertical,
|
||||||
|
@ -248,6 +248,79 @@ void main() {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
testWidgets(
|
||||||
|
'Chip constrains the avatar, label, and delete icons to the bounds of '
|
||||||
|
'the chip when it exceeds the available space', (WidgetTester tester) async {
|
||||||
|
// Regression test for https://github.com/flutter/flutter/issues/11523
|
||||||
|
Widget chipBuilder (String text, {Widget avatar, VoidCallback onDeleted}) {
|
||||||
|
return MaterialApp(
|
||||||
|
home: Scaffold(
|
||||||
|
body: Container(
|
||||||
|
width: 150,
|
||||||
|
child: Column(
|
||||||
|
children: <Widget>[
|
||||||
|
Chip(
|
||||||
|
avatar: avatar,
|
||||||
|
label: Text(text),
|
||||||
|
onDeleted: onDeleted,
|
||||||
|
),
|
||||||
|
]
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void chipRectContains(Rect chipRect, Rect rect) {
|
||||||
|
expect(chipRect.contains(rect.topLeft), true);
|
||||||
|
expect(chipRect.contains(rect.topRight), true);
|
||||||
|
expect(chipRect.contains(rect.bottomLeft), true);
|
||||||
|
expect(chipRect.contains(rect.bottomRight), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
Rect chipRect;
|
||||||
|
Rect avatarRect;
|
||||||
|
Rect labelRect;
|
||||||
|
Rect deleteIconRect;
|
||||||
|
const String text = 'Very long text that will be clipped';
|
||||||
|
|
||||||
|
await tester.pumpWidget(chipBuilder(text));
|
||||||
|
|
||||||
|
chipRect = tester.getRect(find.byType(Chip));
|
||||||
|
labelRect = tester.getRect(find.text(text));
|
||||||
|
chipRectContains(chipRect, labelRect);
|
||||||
|
|
||||||
|
await tester.pumpWidget(chipBuilder(
|
||||||
|
text,
|
||||||
|
avatar: const CircleAvatar(child: Text('A')),
|
||||||
|
));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
chipRect = tester.getRect(find.byType(Chip));
|
||||||
|
avatarRect = tester.getRect(find.byType(CircleAvatar));
|
||||||
|
chipRectContains(chipRect, avatarRect);
|
||||||
|
|
||||||
|
labelRect = tester.getRect(find.text(text));
|
||||||
|
chipRectContains(chipRect, labelRect);
|
||||||
|
|
||||||
|
await tester.pumpWidget(chipBuilder(
|
||||||
|
text,
|
||||||
|
avatar: const CircleAvatar(child: Text('A')),
|
||||||
|
onDeleted: () {},
|
||||||
|
));
|
||||||
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
|
chipRect = tester.getRect(find.byType(Chip));
|
||||||
|
avatarRect = tester.getRect(find.byType(CircleAvatar));
|
||||||
|
chipRectContains(chipRect, avatarRect);
|
||||||
|
|
||||||
|
labelRect = tester.getRect(find.text(text));
|
||||||
|
chipRectContains(chipRect, labelRect);
|
||||||
|
|
||||||
|
deleteIconRect = tester.getRect(find.byIcon(Icons.cancel));
|
||||||
|
chipRectContains(chipRect, deleteIconRect);
|
||||||
|
});
|
||||||
|
|
||||||
testWidgets('Chip in row works ok', (WidgetTester tester) async {
|
testWidgets('Chip in row works ok', (WidgetTester tester) async {
|
||||||
const TextStyle style = TextStyle(fontFamily: 'Ahem', fontSize: 10.0);
|
const TextStyle style = TextStyle(fontFamily: 'Ahem', fontSize: 10.0);
|
||||||
await tester.pumpWidget(
|
await tester.pumpWidget(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user