From 6aed693c4c961c6f3c16703ea231d01497812095 Mon Sep 17 00:00:00 2001 From: Nayeem Hasan <71181265+nayeemtby@users.noreply.github.com> Date: Thu, 3 Feb 2022 21:40:15 +0600 Subject: [PATCH] Add splashBorderRadius to TabBar (#97204) --- packages/flutter/lib/src/material/tabs.dart | 23 ++++++++++ packages/flutter/test/material/tabs_test.dart | 44 +++++++++++++++++++ 2 files changed, 67 insertions(+) diff --git a/packages/flutter/lib/src/material/tabs.dart b/packages/flutter/lib/src/material/tabs.dart index 8dedd77c60..1727efbc3f 100644 --- a/packages/flutter/lib/src/material/tabs.dart +++ b/packages/flutter/lib/src/material/tabs.dart @@ -644,6 +644,7 @@ class TabBar extends StatefulWidget implements PreferredSizeWidget { this.onTap, this.physics, this.splashFactory, + this.splashBorderRadius, }) : assert(tabs != null), assert(isScrollable != null), assert(dragStartBehavior != null), @@ -720,6 +721,11 @@ class TabBar extends StatefulWidget implements PreferredSizeWidget { /// occupied by the tab in the tab bar. If [indicatorSize] is /// [TabBarIndicatorSize.label], then the tab's bounds are only as wide as /// the tab widget itself. + /// + /// See also: + /// + /// * [splashBorderRadius], which defines the clipping radius of the splash + /// and is generally used with [BoxDecoration.borderRadius]. final Decoration? indicator; /// Whether this tab bar should automatically adjust the [indicatorColor]. @@ -849,6 +855,22 @@ class TabBar extends StatefulWidget implements PreferredSizeWidget { /// ``` final InteractiveInkFeatureFactory? splashFactory; + /// Defines the clipping radius of splashes that extend outside the bounds of the tab. + /// + /// This can be useful to match the [BoxDecoration.borderRadius] provided as [indicator]. + /// ```dart + /// TabBar( + /// indicator: BoxDecoration( + /// borderRadius: BorderRadius.circular(40), + /// ), + /// splashBorderRadius: BorderRadius.circular(40), + /// ... + /// ) + /// ``` + /// + /// If this property is null, it is interpreted as [BorderRadius.zero]. + final BorderRadius? splashBorderRadius; + /// A size whose height depends on if the tabs have both icons and text. /// /// [AppBar] uses this size to compute its own preferred size. @@ -1206,6 +1228,7 @@ class _TabBarState extends State { enableFeedback: widget.enableFeedback ?? true, overlayColor: widget.overlayColor ?? tabBarTheme.overlayColor, splashFactory: widget.splashFactory ?? tabBarTheme.splashFactory, + borderRadius: widget.splashBorderRadius, child: Padding( padding: EdgeInsets.only(bottom: widget.indicatorWeight), child: Stack( diff --git a/packages/flutter/test/material/tabs_test.dart b/packages/flutter/test/material/tabs_test.dart index 6241d3096c..1c12c41b2e 100644 --- a/packages/flutter/test/material/tabs_test.dart +++ b/packages/flutter/test/material/tabs_test.dart @@ -4378,6 +4378,50 @@ void main() { expect(tester.widget(find.byType(InkWell)).splashFactory, splashFactory); expect(tester.widget(find.byType(InkWell)).overlayColor, overlayColor); }); + + testWidgets('splashBorderRadius is passed to InkWell.borderRadius', (WidgetTester tester) async { + const Color hoverColor = Color(0xfff44336); + const double radius = 20; + await tester.pumpWidget( + boilerplate( + child: DefaultTabController( + length: 1, + child: TabBar( + overlayColor: MaterialStateProperty.resolveWith( + (Set states) { + if (states.contains(MaterialState.hovered)) { + return hoverColor; + } + return Colors.black54; + }, + ), + splashBorderRadius: BorderRadius.circular(radius), + tabs: const [ + Tab( + child: Text(''), + ), + ], + ), + ), + ), + ); + await tester.pumpAndSettle(); + final TestGesture gesture = await tester.createGesture(kind: PointerDeviceKind.mouse, pointer: 1); + await gesture.moveTo(tester.getCenter(find.byType(Tab))); + await tester.pumpAndSettle(); + final RenderObject object = tester.allRenderObjects.firstWhere((RenderObject element) => element.runtimeType.toString() == '_RenderInkFeatures'); + expect( + object, + paints..rrect( + color: hoverColor, + rrect: RRect.fromRectAndRadius( + tester.getRect(find.byType(InkWell)), + const Radius.circular(radius) + ), + ), + ); + gesture.removePointer(); + }); } class KeepAliveInk extends StatefulWidget {