I used the navigation bar provided by flutter, NavigationBar, but it feels not very convenient to use.
For example:
- You cannot use image resources directly, you need to add several layers of conversion in the middle to convert the image into an icon
- Text size and color are not well controlled
- There is no corresponding style for a horizontal line on the top of the status bar, and so on.
So after much deliberation or write one yourself.
The effect is as follows:
The control code is as follows:
import 'package:flutter/material.dart';
import 'dart:developer' as developer;
class XXNaviIcon {
XXNaviIcon(
{
required this.normalImage,
required this.selectedImage,
required this.title});
final String selectedImage;
final String normalImage;
final String title;
}
class XXNaviBar extends StatefulWidget {
const XXNaviBar({
super.key, required this.icons, this.onDestinationSelected})
: currentIndex = 0;
final List<XXNaviIcon> icons;
final ValueChanged<int>? onDestinationSelected;
final int currentIndex;
State<XXNaviBar> createState() => _XXNaviBarState();
}
class _XXNaviBarState extends State<XXNaviBar> {
int currentIndex = 0;
Widget build(BuildContext context) {
return SafeArea(
child: SizedBox(
height: 48,
child: Container(
decoration: const BoxDecoration(
border:
Border(top: BorderSide(width: 0.5, color: Color(0xffbbbbbb)))),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
for (int i = 0; i < widget.icons.length; i++)
Expanded(
child: GestureDetector(
onTap: () => {
developer.log("tap $i"),
setState(() {
currentIndex = i;
}),
if (widget.onDestinationSelected != null)
{
widget.onDestinationSelected!(i)}
},
child: Container(
color: Colors.white,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset(
currentIndex == i
? widget.icons[i].selectedImage
: widget.icons[i].normalImage,
height: 24,
),
Text(
widget.icons[i].title,
style: const TextStyle(
fontSize: 10, fontWeight: FontWeight.bold),
),
],
),
),
))
],
),
),
));
}
}
The usage is as follows:
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
bottomNavigationBar: XXNaviBar(
onDestinationSelected: (value) => {
developer.log("click tab $value"),
if (currentPageIndex != value)
{
setState(() {
currentPageIndex = value;
})
}
},
icons: [
XXNaviIcon(
normalImage: "assets/images/tabbar/home.png",
selectedImage: "assets/images/tabbar/home-selected.png",
title: "首页",
),
XXNaviIcon(
normalImage: "assets/images/tabbar/data.png",
selectedImage: "assets/images/tabbar/data-selected.png",
title: "数据",
),
XXNaviIcon(
normalImage: "assets/images/tabbar/mine.png",
selectedImage: "assets/images/tabbar/mine-selected.png",
title: "我的",
),
],
),
body: <Widget>[
Container(
color: Colors.white,
alignment: Alignment.center,
child: const Text('Page 1'),
),
Container(
color: Colors.white,
alignment: Alignment.center,
child: const Text('Page 2'),
),
Container(
color: Colors.white,
alignment: Alignment.center,
child: const Text('Page 3'),
),
][currentPageIndex],
);
}
Customization can be changed according to your actual needs.