From e8cbd444e4e9cd77531417092164f715fbd85866 Mon Sep 17 00:00:00 2001 From: Hans Muller Date: Thu, 17 Nov 2022 06:02:42 -0800 Subject: [PATCH] Added Badge.isLabelVisible flag (#115292) --- packages/flutter/lib/src/material/badge.dart | 11 ++++++++ .../flutter/test/material/badge_test.dart | 26 +++++++++++++++++-- 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/packages/flutter/lib/src/material/badge.dart b/packages/flutter/lib/src/material/badge.dart index 1cb3d68f8647..e4fd4c29e5d1 100644 --- a/packages/flutter/lib/src/material/badge.dart +++ b/packages/flutter/lib/src/material/badge.dart @@ -36,6 +36,7 @@ class Badge extends StatelessWidget { this.padding, this.alignment, this.label, + this.isLabelVisible = true, this.child, }); @@ -102,6 +103,12 @@ class Badge extends StatelessWidget { /// this is a [StadiumBorder] shaped "large" badge with height [largeSize]. final Widget? label; + /// If false, the badge's [label] is not included. + /// + /// This flag is true by default. It's intended to make it convenient + /// to create a badge that's only shown under certain conditions. + final bool isLabelVisible; + /// The widget that the badge is stacked on top of. /// /// Typically this is an default sized [Icon] that's part of a @@ -110,6 +117,10 @@ class Badge extends StatelessWidget { @override Widget build(BuildContext context) { + if (!isLabelVisible) { + return child ?? const SizedBox(); + } + final BadgeThemeData badgeTheme = BadgeTheme.of(context); final BadgeThemeData defaults = _BadgeDefaultsM3(context); final double effectiveSmallSize = smallSize ?? badgeTheme.smallSize ?? defaults.smallSize!; diff --git a/packages/flutter/test/material/badge_test.dart b/packages/flutter/test/material/badge_test.dart index 6dce589e96d3..b5de83731bbc 100644 --- a/packages/flutter/test/material/badge_test.dart +++ b/packages/flutter/test/material/badge_test.dart @@ -20,7 +20,7 @@ void main() { alignment: Alignment.topLeft, child: Builder( builder: (BuildContext context) { - // theme.textTtheme is updated when the MaterialApp is built. + // theme.textTheme is updated when the MaterialApp is built. theme = Theme.of(context); return const Badge( label: Text('0'), @@ -71,7 +71,7 @@ void main() { alignment: Alignment.topLeft, child: Builder( builder: (BuildContext context) { - // theme.textTtheme is updated when the MaterialApp is built. + // theme.textTheme is updated when the MaterialApp is built. theme = Theme.of(context); return const Badge( label: Text('0'), @@ -202,5 +202,27 @@ void main() { expect(tester.renderObject(find.byType(Badge)), paints..rrect(color: black)); }); + testWidgets('isLabelVisible', (WidgetTester tester) async { + await tester.pumpWidget( + MaterialApp( + theme: ThemeData.light(useMaterial3: true), + home: const Align( + alignment: Alignment.topLeft, + child: Badge( + label: Text('0'), + isLabelVisible: false, + child: Icon(Icons.add), + ), + ), + ), + ); + + expect(find.text('0'), findsNothing); + expect(find.byType(Icon), findsOneWidget); + expect(tester.getSize(find.byType(Badge)), const Size(24, 24)); // default Icon size + expect(tester.getTopLeft(find.byType(Badge)), Offset.zero); + final RenderBox box = tester.renderObject(find.byType(Badge)); + expect(box, isNot(paints..rrect())); + }); }