From ec97cb3bfb0daa0e6afbdc90f9f2ccf2e10a6b96 Mon Sep 17 00:00:00 2001 From: Victor Uvarov Date: Tue, 3 Nov 2020 10:44:09 -0800 Subject: [PATCH] Adds ability to add borders to badges - Remove material type because material cannot have both type and (radius or shape) - add badges with borders to example app - give borderRadius a default value, since it cannot be null - fix gradele distribution url so that example can be compiled on android with newer version of java - ignore generated script file in example/iOS --- CHANGELOG.md | 4 ++ README.md | 1 + .../gradle/wrapper/gradle-wrapper.properties | 2 +- example/ios/.gitignore | 1 + example/lib/main.dart | 62 +++++++++++++++--- lib/src/badge.dart | 65 +++++++++---------- 6 files changed, 90 insertions(+), 45 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c8da76b..a613a32 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## [1.1.5] - [November 3, 2020] +* Add borderSide parameter to customize the badge border +* Fix issue where null border radius was provided + ## [1.1.4] - [October 23, 2020] * Migrate Android embedding v2, fix overflow issue * Ignore pointer option for Badge diff --git a/README.md b/README.md index da600d5..6eae833 100644 --- a/README.md +++ b/README.md @@ -73,6 +73,7 @@ There are several options that allow for more control: | `bool showBadge` | Hide or show badge with animation using bool flag. | | `AlignmentGeometry alignment` | Alignment of the whole widget | | `bool ignorePointer` | Enable or disable (default) ignore pointer option | +| `BorderSide borderSide` | Adds a border to the badge |

diff --git a/example/android/gradle/wrapper/gradle-wrapper.properties b/example/android/gradle/wrapper/gradle-wrapper.properties index ece66b4..d1a59cd 100644 --- a/example/android/gradle/wrapper/gradle-wrapper.properties +++ b/example/android/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.7-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-5.5-bin.zip diff --git a/example/ios/.gitignore b/example/ios/.gitignore index 79cc4da..c096a2d 100644 --- a/example/ios/.gitignore +++ b/example/ios/.gitignore @@ -40,6 +40,7 @@ Icon? /Flutter/Flutter.framework /Flutter/Generated.xcconfig /ServiceDefinitions.json +/Flutter/flutter_export_environment.sh Pods/ .symlinks/ diff --git a/example/lib/main.dart b/example/lib/main.dart index cc18405..266bf81 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -60,6 +60,7 @@ class _HomeScreenState extends State { _chipWithZeroPadding(), expandedBadge(), _badgeWithZeroPadding(), + _badgesWithBorder(), _listView(), ], ), @@ -127,15 +128,15 @@ class _HomeScreenState extends State { return BottomNavigationBar( items: [ BottomNavigationBarItem( - title: Text('Events'), + label: 'Events', icon: Icon(Icons.event), ), BottomNavigationBarItem( - title: Text('Messages'), + label: 'Messages', icon: Icon(Icons.message), ), BottomNavigationBarItem( - title: Text('Settings'), + label: 'Settings', icon: Badge( shape: BadgeShape.circle, borderRadius: BorderRadius.circular(100), @@ -253,6 +254,47 @@ class _HomeScreenState extends State { ); } + Widget _badgesWithBorder() { + return Padding( + padding: const EdgeInsets.symmetric(vertical: 24), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + Text('Badges with borders:'), + Badge( + position: BadgePosition.topEnd(top: 0, end: 2), + elevation: 0, + shape: BadgeShape.circle, + badgeColor: Colors.red, + borderSide: BorderSide(color: Colors.black), + child: Icon( + Icons.person, + size: 30, + ), + ), + Badge( + position: BadgePosition.topEnd(top: -5, end: -5), + shape: BadgeShape.square, + badgeColor: Colors.blue, + badgeContent: SizedBox( + height: 5, + width: 5, + ), + elevation: 0, + borderSide: BorderSide( + color: Colors.black, + width: 3, + ), + child: Icon( + Icons.games_outlined, + size: 30, + ), + ), + ], + ), + ); + } + Widget _listView() { Widget _listTile(String title, String value) { return ListTile( @@ -290,12 +332,14 @@ class _HomeScreenState extends State { itemCount: 3, separatorBuilder: (BuildContext context, int index) => Divider(), itemBuilder: (BuildContext context, int index) { - if (index == 0) { - return _listTile('Messages', '2'); - } else if (index == 1) { - return _listTile('Friends', '7'); - } else if (index == 2) { - return _listTile('Events', '!'); + switch (index) { + case 0: + return _listTile('Messages', '2'); + case 1: + return _listTile('Friends', '7'); + case 2: + default: + return _listTile('Events', '!'); } }, ), diff --git a/lib/src/badge.dart b/lib/src/badge.dart index 04b3220..cf3065d 100644 --- a/lib/src/badge.dart +++ b/lib/src/badge.dart @@ -19,24 +19,26 @@ class Badge extends StatefulWidget { final BadgeAnimationType animationType; final bool showBadge; final bool ignorePointer; - - Badge( - {Key key, - this.badgeContent, - this.child, - this.badgeColor = Colors.red, - this.elevation = 2, - this.toAnimate = true, - this.position, - this.shape = BadgeShape.circle, - this.padding = const EdgeInsets.all(5.0), - this.animationDuration = const Duration(milliseconds: 500), - this.borderRadius, - this.alignment = Alignment.center, - this.animationType = BadgeAnimationType.slide, - this.showBadge = true, - this.ignorePointer = false}) - : super(key: key); + final BorderSide borderSide; + + Badge({ + Key key, + this.badgeContent, + this.child, + this.badgeColor = Colors.red, + this.elevation = 2, + this.toAnimate = true, + this.position, + this.shape = BadgeShape.circle, + this.padding = const EdgeInsets.all(5.0), + this.animationDuration = const Duration(milliseconds: 500), + this.borderRadius = BorderRadius.zero, + this.alignment = Alignment.center, + this.animationType = BadgeAnimationType.slide, + this.showBadge = true, + this.ignorePointer = false, + this.borderSide = BorderSide.none, + }) : super(key: key); @override BadgeState createState() { @@ -97,24 +99,17 @@ class BadgeState extends State with SingleTickerProviderStateMixin { } Widget _getBadge() { - MaterialType type; - if (widget.shape == BadgeShape.circle) { - type = MaterialType.circle; - } else if (widget.shape == BadgeShape.square) { - type = MaterialType.card; - } else { - print('Unknown material type for badge. Used Card'); - type = MaterialType.card; - } - final border = type == MaterialType.circle - ? null - : RoundedRectangleBorder(borderRadius: widget.borderRadius); + final border = widget.shape == BadgeShape.circle + ? CircleBorder(side: widget.borderSide) + : RoundedRectangleBorder( + side: widget.borderSide, + borderRadius: widget.borderRadius, + ); Widget badgeView() { return AnimatedOpacity( child: Material( shape: border, - type: type, elevation: widget.elevation, color: widget.badgeColor, child: Padding( @@ -152,8 +147,8 @@ class BadgeState extends State with SingleTickerProviderStateMixin { @override void didUpdateWidget(Badge oldWidget) { if (widget.badgeContent is Text && oldWidget.badgeContent is Text) { - Text newText = widget.badgeContent as Text; - Text oldText = oldWidget.badgeContent as Text; + final newText = widget.badgeContent as Text; + final oldText = oldWidget.badgeContent as Text; if (newText.data != oldText.data) { _animationController.reset(); _animationController.forward(); @@ -161,8 +156,8 @@ class BadgeState extends State with SingleTickerProviderStateMixin { } if (widget.badgeContent is Icon && oldWidget.badgeContent is Icon) { - Icon newIcon = widget.badgeContent as Icon; - Icon oldIcon = oldWidget.badgeContent as Icon; + final newIcon = widget.badgeContent as Icon; + final oldIcon = oldWidget.badgeContent as Icon; if (newIcon.icon != oldIcon.icon) { _animationController.reset(); _animationController.forward();