Skip to content

Commit 63634c2

Browse files
authored
Fix filled text field active indicator overflows container bounds (flutter#146637)
## Description This PRs fixes the active indicator vertical position for a filled text field. Before this PR, the active indicator overflowed of container bounds, After this PR the active indicator is painted inside the container bounds. Screenshot of filled text field with active indicator width sets to 4.0dp: | Before | After | |--------|--------| | ![image](https://github.com/flutter/flutter/assets/840911/ed2878ba-130a-4410-b170-423d00a8893d) | ![image](https://github.com/flutter/flutter/assets/840911/f78d06c0-a161-4ab6-b01f-dae297939956) | </details> ## Related Issue Fixes flutter#146507 ## Tests Adds 1 tests, updates 3 tests.
1 parent 1002ce4 commit 63634c2

File tree

2 files changed

+74
-57
lines changed

2 files changed

+74
-57
lines changed

packages/flutter/lib/src/material/input_border.dart

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -254,15 +254,15 @@ class UnderlineInputBorder extends InputBorder {
254254
bottomRight: borderRadius.bottomRight.clamp(maximum: Radius.circular(rect.height / 2)),
255255
);
256256

257-
// We set the strokeAlign to center, so the behavior is consistent with
258-
// drawLine and with the historical behavior of this border.
259257
BoxBorder.paintNonUniformBorder(canvas, rect,
260-
textDirection: textDirection,
261-
borderRadius: updatedBorderRadius,
262-
bottom: borderSide.copyWith(strokeAlign: BorderSide.strokeAlignCenter),
263-
color: borderSide.color);
258+
textDirection: textDirection,
259+
borderRadius: updatedBorderRadius,
260+
bottom: borderSide.copyWith(strokeAlign: BorderSide.strokeAlignInside),
261+
color: borderSide.color,
262+
);
264263
} else {
265-
canvas.drawLine(rect.bottomLeft, rect.bottomRight, borderSide.toPaint());
264+
final Offset alignInsideOffset = Offset(0, borderSide.width / 2);
265+
canvas.drawLine(rect.bottomLeft - alignInsideOffset, rect.bottomRight - alignInsideOffset, borderSide.toPaint());
266266
}
267267
}
268268

packages/flutter/test/material/input_decorator_test.dart

Lines changed: 67 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1537,17 +1537,70 @@ void main() {
15371537

15381538
// Fill is the border's outer path, a rounded rectangle.
15391539
expect(box, paints
1540-
..drrect(
1541-
style: PaintingStyle.fill,
1542-
inner: RRect.fromLTRBAndCorners(0.0, 0.0, 800.0, 47.5,
1543-
bottomRight: const Radius.elliptical(12.0, 11.5),
1544-
bottomLeft: const Radius.elliptical(12.0, 11.5)),
1545-
outer: RRect.fromLTRBAndCorners(0.0, 0.0, 800.0, 48.5,
1546-
bottomRight: const Radius.elliptical(12.0, 12.5),
1547-
bottomLeft: const Radius.elliptical(12.0, 12.5)),
1540+
..drrect(
1541+
style: PaintingStyle.fill,
1542+
inner: RRect.fromLTRBAndCorners(0.0, 0.0, 800.0, 47.0,
1543+
bottomRight: const Radius.elliptical(12.0, 11.0),
1544+
bottomLeft: const Radius.elliptical(12.0, 11.0)),
1545+
outer: RRect.fromLTRBAndCorners(0.0, 0.0, 800.0, 48.0,
1546+
bottomRight: const Radius.elliptical(12.0, 12.0),
1547+
bottomLeft: const Radius.elliptical(12.0, 12.0)),
15481548
));
15491549
});
15501550

1551+
testWidgets('UnderlineInputBorder clips top border to prevent anti-aliasing glitches', (WidgetTester tester) async {
1552+
const Rect canvasRect = Rect.fromLTWH(0, 0, 100, 100);
1553+
const UnderlineInputBorder border = UnderlineInputBorder(
1554+
borderRadius: BorderRadius.all(Radius.circular(12.0)),
1555+
);
1556+
expect(
1557+
(Canvas canvas) => border.paint(canvas, canvasRect),
1558+
paints
1559+
..drrect(
1560+
outer: RRect.fromLTRBAndCorners(0.0, 0.0, 100.0, 100.0,
1561+
bottomRight: const Radius.elliptical(12.0, 12.0),
1562+
bottomLeft: const Radius.elliptical(12.0, 12.0)),
1563+
inner: RRect.fromLTRBAndCorners(0.0, 0.0, 100.0, 99.0,
1564+
bottomRight: const Radius.elliptical(12.0, 11.0),
1565+
bottomLeft: const Radius.elliptical(12.0, 11.0)),
1566+
),
1567+
);
1568+
1569+
const UnderlineInputBorder border2 = UnderlineInputBorder(
1570+
borderRadius: BorderRadius.all(Radius.circular(60.0)),
1571+
);
1572+
expect(
1573+
(Canvas canvas) => border2.paint(canvas, canvasRect),
1574+
paints
1575+
..drrect(
1576+
outer: RRect.fromLTRBAndCorners(0.0, 0.0, 100.0, 100.0,
1577+
bottomRight: const Radius.elliptical(50.0, 50.0),
1578+
bottomLeft: const Radius.elliptical(50.0, 50.0)),
1579+
inner: RRect.fromLTRBAndCorners(0.0, 0.0, 100.0, 99.0,
1580+
bottomRight: const Radius.elliptical(50.0, 49.0),
1581+
bottomLeft: const Radius.elliptical(50.0, 49.0)),
1582+
),
1583+
reason: 'clamp is expected',
1584+
);
1585+
});
1586+
1587+
testWidgets('UnderlineInputBorder draws bottom border inside container bounds', (WidgetTester tester) async {
1588+
const Rect canvasRect = Rect.fromLTWH(0, 0, 100, 100);
1589+
const double borderWidth = 2.0;
1590+
const UnderlineInputBorder border = UnderlineInputBorder(
1591+
borderSide: BorderSide(width: borderWidth),
1592+
);
1593+
expect(
1594+
(Canvas canvas) => border.paint(canvas, canvasRect),
1595+
paints
1596+
..line(
1597+
p1: Offset(0, canvasRect.height - borderWidth / 2),
1598+
p2: Offset(100, canvasRect.height - borderWidth / 2),
1599+
strokeWidth: borderWidth,
1600+
),
1601+
);
1602+
});
1603+
15511604
testWidgets('InputDecorator OutlineBorder focused label with icon', (WidgetTester tester) async {
15521605
// This is a regression test for https://github.com/flutter/flutter/issues/82321
15531606
Widget buildFrame(TextDirection textDirection) {
@@ -5174,42 +5227,6 @@ void main() {
51745227
});
51755228
});
51765229

5177-
testWidgets('UnderlineInputBorder clips top border to prevent anti-aliasing glitches', (WidgetTester tester) async {
5178-
const Rect canvasRect = Rect.fromLTWH(0, 0, 100, 100);
5179-
const UnderlineInputBorder border = UnderlineInputBorder(
5180-
borderRadius: BorderRadius.all(Radius.circular(12.0)),
5181-
);
5182-
expect(
5183-
(Canvas canvas) => border.paint(canvas, canvasRect),
5184-
paints
5185-
..drrect(
5186-
outer: RRect.fromLTRBAndCorners(0.0, 0.0, 100.0, 100.5,
5187-
bottomRight: const Radius.elliptical(12.0, 12.5),
5188-
bottomLeft: const Radius.elliptical(12.0, 12.5)),
5189-
inner: RRect.fromLTRBAndCorners(0.0, 0.0, 100.0, 99.5,
5190-
bottomRight: const Radius.elliptical(12.0, 11.5),
5191-
bottomLeft: const Radius.elliptical(12.0, 11.5)),
5192-
),
5193-
);
5194-
5195-
const UnderlineInputBorder border2 = UnderlineInputBorder(
5196-
borderRadius: BorderRadius.all(Radius.circular(60.0)),
5197-
);
5198-
expect(
5199-
(Canvas canvas) => border2.paint(canvas, canvasRect),
5200-
paints
5201-
..drrect(
5202-
outer: RRect.fromLTRBAndCorners(0.0, 0.0, 100.0, 100.5,
5203-
bottomRight: const Radius.elliptical(50.0, 50.5),
5204-
bottomLeft: const Radius.elliptical(50.0, 50.5)),
5205-
inner: RRect.fromLTRBAndCorners(0.0, 0.0, 100.0, 99.5,
5206-
bottomRight: const Radius.elliptical(50.0, 49.5),
5207-
bottomLeft: const Radius.elliptical(50.0, 49.5)),
5208-
),
5209-
reason: 'clamp is expected',
5210-
);
5211-
});
5212-
52135230
testWidgets('Ensure the height of labelStyle remains unchanged when TextField is focused', (WidgetTester tester) async {
52145231
// Regression test for https://github.com/flutter/flutter/issues/141448.
52155232
final FocusNode focusNode = FocusNode();
@@ -9754,12 +9771,12 @@ void main() {
97549771
expect(box, paints
97559772
..drrect(
97569773
style: PaintingStyle.fill,
9757-
inner: RRect.fromLTRBAndCorners(0.0, 0.0, 800.0, 47.5,
9758-
bottomRight: const Radius.elliptical(12.0, 11.5),
9759-
bottomLeft: const Radius.elliptical(12.0, 11.5)),
9760-
outer: RRect.fromLTRBAndCorners(0.0, 0.0, 800.0, 48.5,
9761-
bottomRight: const Radius.elliptical(12.0, 12.5),
9762-
bottomLeft: const Radius.elliptical(12.0, 12.5)),
9774+
inner: RRect.fromLTRBAndCorners(0.0, 0.0, 800.0, 47.0,
9775+
bottomRight: const Radius.elliptical(12.0, 11.0),
9776+
bottomLeft: const Radius.elliptical(12.0, 11.0)),
9777+
outer: RRect.fromLTRBAndCorners(0.0, 0.0, 800.0, 48.0,
9778+
bottomRight: const Radius.elliptical(12.0, 12.0),
9779+
bottomLeft: const Radius.elliptical(12.0, 12.0)),
97639780
));
97649781
});
97659782

0 commit comments

Comments
 (0)