Adjust the drawing position of OutlineInputBorder (#159943)

Fixes #159942

Related Discussion: [#158440
(comment)](https://github.com/flutter/flutter/pull/158440#discussion_r1844902638)

## Temporary code

- Change the background color of the label container.


3f08b61784/packages/flutter/lib/src/material/input_decorator.dart (L2216-L2220)

```diff
+  child: Container(
+    color: Colors.red.withOpacity(0.2),
     child: decoration.label ?? Text( 
       decoration.labelText!, 
       overflow: TextOverflow.ellipsis, 
       textAlign: textAlign, 
     ),
+  ),
```

- Change border width.


3f08b61784/packages/flutter/lib/src/material/input_decorator.dart (L4838)

```diff
- return BorderSide(color: _colors.primary, width: 2.0);
+ return BorderSide(color: _colors.primary, width: 6.0);
 ```

## Example code

```dart
import 'package:flutter/material.dart';

void main() {
  runApp(
    MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: Padding(
          padding: const EdgeInsets.all(16.0),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.spaceEvenly,
            children: [
              Directionality(
                textDirection: TextDirection.ltr,
                child: RepaintBoundary(
                  child: InputDecorator(
                    isFocused: true,
                    isEmpty: true,
                    decoration: InputDecoration(
hintText: 'TextDirection.ltr with BorderSide(width: 2.0)',
labelText: 'ABCDEFGGFEDCBAABCDEFGGFEDCBAABCDEFGGFEDCBAABCDEFGGFEDCBA',
                      border: OutlineInputBorder(
                        gapPadding: 0.0,
                      ),
                    ),
                  ),
                ),
              ),
              Directionality(
                textDirection: TextDirection.rtl,
                child: RepaintBoundary(
                  child: InputDecorator(
                    isFocused: true,
                    isEmpty: true,
                    decoration: InputDecoration(
hintText: 'TextDirection.rtl with BorderSide(width: 2.0)',
labelText: 'ABCDEFGGFEDCBAABCDEFGGFEDCBAABCDEFGGFEDCBAABCDEFGGFEDCBA',
                      border: OutlineInputBorder(
                        gapPadding: 0.0,
                      ),
                    ),
                  ),
                ),
              ),
            ],
          ),
        ),
      ),
    ),
  );
}
```

| Before | After |
| ------ | ----- |
|    ![before1](https://github.com/user-attachments/assets/c4b5ee75-f9f8-4ec0-baa4-7a51430893e6)    |   ![after1](https://github.com/user-attachments/assets/234b16c5-5a9a-4a1c-9f7e-d58e507533a6)    |
|    ![before2](https://github.com/user-attachments/assets/3afc7668-1a3f-49de-8c61-b839a120a950)    |   ![after2](https://github.com/user-attachments/assets/fd9e7f13-9da4-4639-9839-a293c77a76cf)    |

## Pre-launch Checklist

- [x] I read the [Contributor Guide] and followed the process outlined there for submitting PRs.
- [x] I read the [Tree Hygiene] wiki page, which explains my responsibilities.
- [x] I read and followed the [Flutter Style Guide], including [Features we expect every widget to implement].
- [x] I signed the [CLA].
- [x] I listed at least one issue that this PR fixes in the description above.
- [ ] I updated/added relevant documentation (doc comments with `///`).
- [x] I added new tests to check the change I am making, or this PR is [test-exempt].
- [ ] I followed the [breaking change policy] and added [Data Driven Fixes] where supported.
- [x] All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel on [Discord].

<!-- Links -->
[Contributor Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview
[Tree Hygiene]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
[test-exempt]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests
[Flutter Style Guide]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md
[Features we expect every widget to implement]: https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement
[CLA]: https://cla.developers.google.com/
[flutter/tests]: https://github.com/flutter/tests
[breaking change policy]: https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes
[Discord]: https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md
[Data Driven Fixes]: https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
This commit is contained in:
Flop 2024-12-11 04:32:45 +08:00 committed by GitHub
parent 795fef59e8
commit fe0e219b9e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 70 additions and 2 deletions

View File

@ -476,14 +476,14 @@ class OutlineInputBorder extends InputBorder {
// Draw top border from top left corner to gap start.
if (start > scaledRRect.tlRadiusX) {
path.lineTo(scaledRRect.left + start, scaledRRect.top);
path.lineTo(start, scaledRRect.top);
}
// Draw top border from gap end to top right corner and draw top right corner.
const double trCornerArcStart = (3 * math.pi) / 2.0;
const double trCornerArcSweep = cornerArcSweep;
if (start + extent < outerWidth - scaledRRect.trRadiusX) {
path.moveTo(scaledRRect.left + start + extent, scaledRRect.top);
path.moveTo(start + extent, scaledRRect.top);
path.lineTo(scaledRRect.right - scaledRRect.trRadiusX, scaledRRect.top);
if (scaledRRect.trRadius != Radius.zero) {
path.addArc(trCorner, trCornerArcStart, trCornerArcSweep);

View File

@ -1707,6 +1707,74 @@ void main() {
);
});
// Regression test for https://github.com/flutter/flutter/issues/159942.
testWidgets('OutlineBorder does not overlap with the label at the default radius', (WidgetTester tester) async {
Widget buildFrame(TextDirection textDirection) {
return MaterialApp(
home: Scaffold(
body: Container(
padding: const EdgeInsets.all(16.0),
alignment: Alignment.center,
child: Directionality(
textDirection: textDirection,
child: const RepaintBoundary(
child: InputDecorator(
isFocused: true,
decoration: InputDecoration(
labelText: labelText,
border: OutlineInputBorder(
gapPadding: 0.0,
),
),
),
),
),
),
),
);
}
await tester.pumpWidget(buildFrame(TextDirection.ltr));
Rect labelRect = getLabelRect(tester);
RenderBox borderBox = InputDecorator.containerOf(tester.element(findBorderPainter()))!;
expect(findBorderPainter(), paints
..save()
..path(
// The points of the label edge should be part of the border.
includes: <Offset>[
borderBox.globalToLocal(labelRect.centerLeft),
borderBox.globalToLocal(labelRect.centerRight),
],
// The points inside the label should not be part of the border.
excludes: <Offset>[
borderBox.globalToLocal(labelRect.centerLeft) + const Offset(1, 0),
borderBox.globalToLocal(labelRect.centerRight) + const Offset(-1, 0),
],
)
..restore(),
);
await tester.pumpWidget(buildFrame(TextDirection.rtl));
labelRect = getLabelRect(tester);
borderBox = InputDecorator.containerOf(tester.element(findBorderPainter()))!;
expect(findBorderPainter(), paints
..save()
..path(
// The points of the label edge should be part of the border.
includes: <Offset>[
borderBox.globalToLocal(labelRect.centerLeft),
borderBox.globalToLocal(labelRect.centerRight),
],
// The points inside the label should not be part of the border.
excludes: <Offset>[
borderBox.globalToLocal(labelRect.centerLeft) + const Offset(1, 0),
borderBox.globalToLocal(labelRect.centerRight) + const Offset(-1, 0),
],
)
..restore(),
);
});
testWidgets('OutlineBorder does not draw over label when input decorator is focused and has an icon', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/18111.
Widget buildFrame(TextDirection textDirection) {