From 271cb8c8c5c7c023e35fa982e9a1d32dfaccdf68 Mon Sep 17 00:00:00 2001 From: Walid Ashik Date: Tue, 25 Feb 2025 13:22:04 +0600 Subject: [PATCH] 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]. [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 --- .../flutter/lib/src/material/divider.dart | 30 ++++++++++++++--- .../flutter/test/material/divider_test.dart | 32 +++++++++++++++++++ 2 files changed, 57 insertions(+), 5 deletions(-) diff --git a/packages/flutter/lib/src/material/divider.dart b/packages/flutter/lib/src/material/divider.dart index 3a0ac9868d..c9229eb24c 100644 --- a/packages/flutter/lib/src/material/divider.dart +++ b/packages/flutter/lib/src/material/divider.dart @@ -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)), ), ), diff --git a/packages/flutter/test/material/divider_test.dart b/packages/flutter/test/material/divider_test.dart index 7dec6fa0c7..040df20f19 100644 --- a/packages/flutter/test/material/divider_test.dart +++ b/packages/flutter/test/material/divider_test.dart @@ -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,