アクティブおよび非アクティブでの色の変更で完全に機能する BottomNavigationBar がありますが、色を変更したくはありませんが、アクティブおよび非アクティブのアイコンを SVG イメージで変更します。以下は私のコードです:
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;
}
}
ご覧
のとおり_tabColor
、アクティブと非アクティブで色を青から灰色に切り替えますが、上記の宣言された SVG イメージを使用してアイコンを切り替えたいと思います。アクティブassetHome
なときと非アクティブなとき、アクティブなときと非アクティブなとき、最後にアクティブなときと非アクティブなとき。MyDealApp()
assetHome1
MyDealApp()
assetRedemptions
MyRedemptionApp()
assetRedemptions1
MyRedemptionApp()
assetProfile
MyProfileApp()
assetProfile1
MyProfileApp()