diff --git a/lib/bottom_navy_bar.dart b/lib/bottom_navy_bar.dart index 277447e..f66c01f 100644 --- a/lib/bottom_navy_bar.dart +++ b/lib/bottom_navy_bar.dart @@ -9,7 +9,6 @@ import 'package:flutter/widgets.dart'; /// Update [selectedIndex] to change the selected item. /// [selectedIndex] is required and must not be null. class BottomNavyBar extends StatelessWidget { - BottomNavyBar({ Key? key, this.selectedIndex = 0, @@ -23,8 +22,8 @@ class BottomNavyBar extends StatelessWidget { required this.items, required this.onItemSelected, this.curve = Curves.linear, - }) : assert(items.length >= 2 && items.length <= 5), - super(key: key); + }) : assert(items.length >= 2 && items.length <= 5), + super(key: key); /// The selected item is index. Changing this property will change and animate /// the item being selected. Defaults to zero. @@ -125,10 +124,17 @@ class _ItemWidget extends StatelessWidget { required this.itemCornerRadius, required this.iconSize, this.curve = Curves.linear, - }) : super(key: key); + }) : super(key: key); @override Widget build(BuildContext context) { + + List? stops; + if (item.activeBackgroundColorGradient != null) { + int gradientLength = item.activeBackgroundColorGradient!.length; + stops = List.generate(gradientLength, (index) => index / (gradientLength - 1)); + } + return Semantics( container: true, selected: isSelected, @@ -138,8 +144,17 @@ class _ItemWidget extends StatelessWidget { duration: animationDuration, curve: curve, decoration: BoxDecoration( - color: - isSelected ? item.activeColor.withOpacity(0.2) : backgroundColor, + gradient: isSelected && item.activeBackgroundColorGradient != null && item.activeBackgroundColorGradient!.length > 0 + ? LinearGradient( + colors: item.activeBackgroundColorGradient!, + stops: stops, + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + ) + : null, + color: isSelected + ? item.activeColor?.withOpacity(item.activeColorOpacityLevel) + : backgroundColor, borderRadius: BorderRadius.circular(itemCornerRadius), ), child: SingleChildScrollView( @@ -157,7 +172,7 @@ class _ItemWidget extends StatelessWidget { data: IconThemeData( size: iconSize, color: isSelected - ? item.activeColor.withOpacity(1) + ? item.activeColor?.withOpacity(1) : item.inactiveColor == null ? item.activeColor : item.inactiveColor, @@ -190,14 +205,15 @@ class _ItemWidget extends StatelessWidget { /// The [BottomNavyBar.items] definition. class BottomNavyBarItem { - BottomNavyBarItem({ required this.icon, required this.title, - this.activeColor = Colors.blue, + this.activeColor, this.textAlign, this.inactiveColor, - }); + this.activeColorOpacityLevel = 0.2, + this.activeBackgroundColorGradient, + }) : assert(activeColor == null || activeBackgroundColorGradient == null); /// Defines this item's icon which is placed in the right side of the [title]. final Widget icon; @@ -207,14 +223,19 @@ class BottomNavyBarItem { /// The [icon] and [title] color defined when this item is selected. Defaults /// to [Colors.blue]. - final Color activeColor; + final Color? activeColor; /// The [icon] and [title] color defined when this item is not selected. final Color? inactiveColor; + /// Used to configure active background opacity, if not set, it defaults to 0.2. + final double activeColorOpacityLevel; + + /// Color gradient for background + final List? activeBackgroundColorGradient; + /// The alignment for the [title]. /// /// This will take effect only if [title] it a [Text] widget. final TextAlign? textAlign; - } diff --git a/test/bottom_navy_bar_test.dart b/test/bottom_navy_bar_test.dart index 36c265c..6746515 100644 --- a/test/bottom_navy_bar_test.dart +++ b/test/bottom_navy_bar_test.dart @@ -134,4 +134,33 @@ void main() { expect((containerFinder.decoration as BoxDecoration).boxShadow!.length, 1); expect((containerFinder.decoration as BoxDecoration).boxShadow!.first.blurRadius, 2); }); + + testWidgets('throws assertion error if both activeColor and activeBackgroundColorGradient are set', (WidgetTester tester) async { + expect(() async { + await tester.pumpWidget( + MaterialApp( + home: Scaffold( + floatingActionButton: BottomNavyBar( + onItemSelected: onItemSelected, + items: [ + BottomNavyBarItem( + icon: Icon(Icons.apps), + title: Text('Item 1'), + activeBackgroundColorGradient: [Colors.pink, Colors.deepPurple, Colors.blue.shade900], + activeColor: Colors.yellow, + textAlign: TextAlign.center, + ), + BottomNavyBarItem( + icon: Icon(Icons.people), + title: Text('Item 2'), + activeBackgroundColorGradient: [Colors.red, Colors.orange, Colors.yellow, Colors.green, Colors.blue, Colors.purple], + textAlign: TextAlign.center, + ), + ], + ), + ), + ), + ); + }, throwsAssertionError); + }); }