Created
June 10, 2020 18:44
-
-
Save talamaska/29dc643bcdc0d4df15634cc6b7625b82 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'package:flutter/material.dart'; | |
class CustomBarItem { | |
const CustomBarItem({ | |
this.icon, | |
this.title, | |
}); | |
final Icon icon; | |
final String title; | |
} | |
class CustomBottomBarItem extends StatelessWidget { | |
const CustomBottomBarItem({ | |
Key key, | |
this.icon, | |
this.title, | |
this.isActive, | |
this.onTap, | |
}) : super(key: key); | |
final Icon icon; | |
final String title; | |
final bool isActive; | |
final VoidCallback onTap; | |
@override | |
Widget build(BuildContext context) { | |
return Expanded( | |
child: GestureDetector( | |
onTap: onTap, | |
child: Column( | |
crossAxisAlignment: CrossAxisAlignment.center, | |
mainAxisAlignment: MainAxisAlignment.center, | |
children: <Widget>[ | |
AnimatedContainer( | |
child: Icon( | |
icon.icon, | |
color: isActive | |
? Theme.of(context).primaryColor | |
: Colors.grey.shade600, | |
semanticLabel: icon.semanticLabel ?? title, | |
), | |
transform: Matrix4.identity() | |
..translate( | |
isActive ? -0.10 * 24.0 : 0.0, | |
isActive ? -0.10 * 24.0 : 0.0, | |
) | |
..scale(isActive ? 1.2 : 1.0, isActive ? 1.2 : 1.0), | |
duration: const Duration(milliseconds: 300), | |
), | |
Text( | |
title, | |
style: TextStyle( | |
color: isActive | |
? Theme.of(context).primaryColor | |
: Colors.grey.shade600, | |
fontWeight: isActive ? FontWeight.bold : FontWeight.normal, | |
), | |
), | |
], | |
), | |
), | |
); | |
} | |
} | |
class CustomBottomBar extends StatefulWidget { | |
const CustomBottomBar({ | |
Key key, | |
this.height, | |
this.onTap, | |
this.currentIndex, | |
this.items, | |
}) : super(key: key); | |
final double height; | |
final Function(int) onTap; | |
final List<CustomBarItem> items; | |
final int currentIndex; | |
@override | |
_CustomBottomBarState createState() => _CustomBottomBarState(); | |
} | |
class _CustomBottomBarState extends State<CustomBottomBar> { | |
@override | |
Widget build(BuildContext context) { | |
return Container( | |
height: widget.height, | |
margin: const EdgeInsets.fromLTRB(3.0, 0, 3.0, 3.0), | |
decoration: const BoxDecoration( | |
borderRadius: BorderRadius.all(Radius.circular(3.0))), | |
child: Row( | |
mainAxisAlignment: MainAxisAlignment.spaceBetween, | |
children: List<CustomBottomBarItem>.generate(widget.items.length, | |
(int index) { | |
return CustomBottomBarItem( | |
icon: widget.items[index].icon, | |
title: widget.items[index].title, | |
isActive: widget.currentIndex == index, | |
onTap: () => widget.onTap(index), | |
); | |
}), | |
), | |
); | |
} | |
} | |
testWidgets('bottom bar selects on tap', (WidgetTester tester) async { | |
await prepareWidgetTaps(tester); | |
await tester.pump(); | |
await tester.pump(); | |
final WidgetPredicate widgetSelectedPredicate = (Widget widget) => | |
widget is CustomBottomBarItem && widget.isActive == true; | |
expect(find.byWidgetPredicate(widgetSelectedPredicate), findsOneWidget); | |
expect( | |
tester.widget(find.byType(CustomBottomBarItem).at(0)), | |
isA<CustomBottomBarItem>() | |
.having((t) => t.isActive, 'isActive', equals(true))); | |
await tester.tap(find.text('test2')); | |
await tester.pumpAndSettle(); | |
expect( | |
tester.widget(find.byType(CustomBottomBarItem).at(1)), | |
isA<CustomBottomBarItem>() | |
.having((t) => t.isActive, 'isActive', equals(true))); | |
}); | |
Future<void> prepareWidgetTaps(WidgetTester tester) async { | |
await tester.pumpWidget(const TestBottomBarTaps()); | |
} | |
class TestBottomBarTaps extends StatefulWidget { | |
const TestBottomBarTaps({Key key}) : super(key: key); | |
@override | |
_TestBottomBarTapsState createState() => _TestBottomBarTapsState(); | |
} | |
class _TestBottomBarTapsState extends State<TestBottomBarTaps> { | |
@override | |
Widget build(BuildContext context) { | |
int selectedIndex = 0; | |
return MaterialApp( | |
theme: AppThemes.themeData['light'], | |
home: Scaffold( | |
body: Container(), | |
bottomNavigationBar: CustomBottomBar( | |
currentIndex: selectedIndex, | |
onTap: (int index) { | |
print('test ${index}'); | |
setState(() { | |
selectedIndex = index; | |
}); | |
}, | |
height: 48.0, | |
items: <CustomBarItem>[ | |
CustomBarItem( | |
icon: Icon( | |
Icons.calendar_today, | |
size: 24.0, | |
semanticLabel: 'test1', | |
), | |
title: 'test1', | |
), | |
CustomBarItem( | |
icon: Icon( | |
Icons.list, | |
size: 24.0, | |
semanticLabel: 'test2', | |
), | |
title: 'test2', | |
), | |
CustomBarItem( | |
icon: Icon( | |
Icons.show_chart, | |
size: 24.0, | |
semanticLabel: 'test3', | |
), | |
title: 'test3', | |
), | |
], | |
), | |
), | |
); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment