I have a BottomNavigationBar which works perfectly with color change on active and inactive but I don't want to change color but change icons on active and inactive with SVG image. Below is my code:
class AppNavigation extends StatefulWidget {
@override
State<StatefulWidget> createState() => AppState();
}
const assetHome = 'assets/home_off.svg';
const assetRedemptions = 'assets/redeemed_off.svg';
const assetProfile = 'assets/profile_off.svg';
const assetHome1 = 'assets/home_on.svg';
const assetRedemptions1 = 'assets/redeemed_on.svg';
const assetProfile1 = 'assets/profile_on.svg';
class AppState extends State<AppNavigation> {
static int currentTab = 0;
// list tabs here
final List<TabItem> tabs = [
TabItem(
tabName: "Home",
icon: Icons.home,
page: MyDealApp(),
),
TabItem(
tabName: "Announcement",
icon: Icons.announcement,
page: MyRedemptionApp(),
),
TabItem(
tabName: "Notification",
icon: Icons.notifications,
page: MyProfileApp(),
),
];
AppState() {
tabs.asMap().forEach((index, details) {
details.setIndex(index);
});
}
void _selectTab(int index) {
if (index == currentTab) {
tabs[index].key.currentState.popUntil((route) => route.isFirst);
} else {
setState(() => currentTab = index);
debugPrint("currentTabber:$currentTab");
}
}
@override
Widget build(BuildContext context) {
// WillPopScope handle android back btn
return WillPopScope(
onWillPop: () async {
final isFirstRouteInCurrentTab =
!await tabs[currentTab].key.currentState.maybePop();
if (isFirstRouteInCurrentTab) {
// if not on the 'main' tab
if (currentTab != 0) {
// select 'main' tab
_selectTab(0);
// back button handled by app
return false;
}
}
return isFirstRouteInCurrentTab;
},
child: Scaffold(
// indexed stack shows only one child
body: IndexedStack(
index: currentTab,
children: tabs.map((e) => e.page).toList(),
),
// Bottom navigation
bottomNavigationBar: BottomNavigation(
onSelectTab: _selectTab,
tabs: tabs,
),
),
);
}
}
class TabItem {
// you can customize what kind of information is needed
// for each tab
final String tabName;
final IconData icon;
final GlobalKey<NavigatorState> key = GlobalKey<NavigatorState>();
int _index = 0;
Widget _page;
TabItem({
@required this.tabName,
@required this.icon,
@required Widget page,
}) {
_page = page;
}
void setIndex(int i) {
_index = i;
}
int getIndex() => _index;
Widget get page {
return Visibility(
// only paint this page when currentTab is active
visible: _index == AppState.currentTab,
// important to preserve state while switching between tabs
maintainState: true,
child: Navigator(
// key tracks state changes
key: key,
onGenerateRoute: (routeSettings) {
return MaterialPageRoute(
builder: (_) => _page,
);
},
),
);
}
}
class BottomNavigation extends StatelessWidget {
BottomNavigation({
this.onSelectTab,
this.tabs,
});
final ValueChanged<int> onSelectTab;
final List<TabItem> tabs;
@override
Widget build(BuildContext context) {
return BottomNavigationBar(
type: BottomNavigationBarType.fixed,
items: tabs
.map(
(e) => _buildItem(
index: e.getIndex(),
icon: e.icon,
tabName: e.tabName,
),
)
.toList(),
onTap: (index) => onSelectTab(
index,
),
);
}
BottomNavigationBarItem _buildItem(
{int index, IconData icon, String tabName}) {
return BottomNavigationBarItem(
icon: Icon(
icon,
color: _tabColor(index: index),
),
title: Text(
tabName,
style: TextStyle(
color: _tabColor(index: index),
fontSize: 12,
),
),
);
}
Color _tabColor({int index}) {
return AppState.currentTab == index ? colorGreen : Colors.grey;
}
}
As you can see
_tabColor
switch from color from blue to grey on active and inactive but rather I want a switch in icon with declared SVG images above. assetHome
for MyDealApp()
when it is active and assetHome1
for MyDealApp()
when it is inactive, assetRedemptions
for MyRedemptionApp()
when it is active and assetRedemptions1
for MyRedemptionApp()
when it is inactive and finally assetProfile
for MyProfileApp()
when it is active and assetProfile1
for MyProfileApp()
when it is inactive.
You can use
activeIcon
andicon
parameters ofBottomNavigationBarItem
. IfactiveIcon
is provided,icon
will only be displayed when the item is not selected.