Skip to content

Instantly share code, notes, and snippets.

@talamaska
Created June 10, 2020 18:44
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save talamaska/29dc643bcdc0d4df15634cc6b7625b82 to your computer and use it in GitHub Desktop.
Save talamaska/29dc643bcdc0d4df15634cc6b7625b82 to your computer and use it in GitHub Desktop.
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