Add BorderRadiusGeometry to Divider Widget for Customisable Border Radius (#163414)

This PR fixes #162239 . Now, you can add border radius to divider. It is
needed when you have a thick divider and almost all the thick dividers
need a radius.

Example Usage:

```diff
  Divider(
    height: 20,
    thickness: 5,
    color: Colors.blue,
+   radius: BorderRadius.all(Radius.circular(20)), 
  );
```

```diff
  VerticalDivider(
    height: 20,
    thickness: 5,
    color: Colors.blue,
+   radius: BorderRadius.all(Radius.circular(20)), 
  );
```


## 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.
- [x] 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].
- [x] 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

---------

Co-authored-by: Tong Mu <dkwingsmt@users.noreply.github.com>
This commit is contained in:
Walid Ashik 2025-02-25 13:22:04 +06:00 committed by GitHub
parent 4e39d13a6f
commit 271cb8c8c5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 57 additions and 5 deletions

View File

@ -58,11 +58,18 @@ class Divider extends StatelessWidget {
///
/// The [height], [thickness], [indent], and [endIndent] must be null or
/// non-negative.
const Divider({super.key, this.height, this.thickness, this.indent, this.endIndent, this.color})
: assert(height == null || height >= 0.0),
assert(thickness == null || thickness >= 0.0),
assert(indent == null || indent >= 0.0),
assert(endIndent == null || endIndent >= 0.0);
const Divider({
super.key,
this.height,
this.thickness,
this.indent,
this.endIndent,
this.color,
this.radius,
}) : assert(height == null || height >= 0.0),
assert(thickness == null || thickness >= 0.0),
assert(indent == null || indent >= 0.0),
assert(endIndent == null || endIndent >= 0.0);
/// The divider's height extent.
///
@ -94,6 +101,11 @@ class Divider extends StatelessWidget {
/// also null, then this defaults to 0.0.
final double? endIndent;
/// The amount of radius for the border of the divider.
///
/// If this is null, then the default radius of [BoxDecoration] will be used.
final BorderRadiusGeometry? radius;
/// The color to use when painting the line.
///
/// If this is null, then the [DividerThemeData.color] is used. If that is
@ -177,6 +189,7 @@ class Divider extends StatelessWidget {
height: thickness,
margin: EdgeInsetsDirectional.only(start: indent, end: endIndent),
decoration: BoxDecoration(
borderRadius: radius,
border: Border(bottom: createBorderSide(context, color: color, width: thickness)),
),
),
@ -227,6 +240,7 @@ class VerticalDivider extends StatelessWidget {
this.indent,
this.endIndent,
this.color,
this.radius,
}) : assert(width == null || width >= 0.0),
assert(thickness == null || thickness >= 0.0),
assert(indent == null || indent >= 0.0),
@ -277,6 +291,11 @@ class VerticalDivider extends StatelessWidget {
/// {@end-tool}
final Color? color;
/// The amount of radius for the border of the divider.
///
/// If this is null, then the default radius of [BoxDecoration] will be used.
final BorderRadiusGeometry? radius;
@override
Widget build(BuildContext context) {
final ThemeData theme = Theme.of(context);
@ -295,6 +314,7 @@ class VerticalDivider extends StatelessWidget {
width: thickness,
margin: EdgeInsetsDirectional.only(top: indent, bottom: endIndent),
decoration: BoxDecoration(
borderRadius: radius,
border: Border(left: Divider.createBorderSide(context, color: color, width: thickness)),
),
),

View File

@ -40,6 +40,22 @@ void main() {
expect(decoration.border!.bottom.width, 5.0);
});
testWidgets('Divider custom radius', (WidgetTester tester) async {
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
child: Center(child: Divider(radius: BorderRadius.circular(5))),
),
);
final Container container = tester.widget(find.byType(Container));
final BoxDecoration decoration = container.decoration! as BoxDecoration;
final BorderRadius borderRadius = decoration.borderRadius! as BorderRadius;
expect(borderRadius.bottomLeft, const Radius.circular(5));
expect(borderRadius.bottomRight, const Radius.circular(5));
expect(borderRadius.topLeft, const Radius.circular(5));
expect(borderRadius.topRight, const Radius.circular(5));
});
testWidgets('Horizontal divider custom indentation', (WidgetTester tester) async {
const double customIndent = 10.0;
Rect dividerRect;
@ -183,6 +199,22 @@ void main() {
expect(lineRect.bottom, dividerRect.bottom - customIndent);
});
testWidgets('VerticalDivider custom radius', (WidgetTester tester) async {
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
child: Center(child: VerticalDivider(radius: BorderRadius.circular(5))),
),
);
final Container container = tester.widget(find.byType(Container));
final BoxDecoration decoration = container.decoration! as BoxDecoration;
final BorderRadius borderRadius = decoration.borderRadius! as BorderRadius;
expect(borderRadius.bottomLeft, const Radius.circular(5));
expect(borderRadius.bottomRight, const Radius.circular(5));
expect(borderRadius.topLeft, const Radius.circular(5));
expect(borderRadius.topRight, const Radius.circular(5));
});
// Regression test for https://github.com/flutter/flutter/issues/39533
testWidgets('createBorderSide does not throw exception with null context', (
WidgetTester tester,