一般实现需要有两种方式,一个是bottomNavigationBar一个是BottomAppBar。因为bottomNavigationBar会保留底部可以点击的区域,在凸起的样式中显得比较奇怪,所以使用第二种实现方式。如果只是普通的导航栏直接使用第一种最简单,大致思路就是利用Row组件结合Expanded(主要是扩展可点击区域),shape设置为凹槽结合floatingActionButton设置在中间位置
效果图
less
import 'package:flutter/material.dart';
import './widget/business_page.dart';//简单的StatelessWidget,只包含一个text
import './widget/home_page.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
int currentIndex = 0;
final pages = const [HomePage(), BusinessPage(), BusinessPage()];
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(primaryColor: Colors.blue),
home: Scaffold(
appBar: AppBar(title: const Text('Flutter demo')),
body: pages[currentIndex],
bottomNavigationBar: BottomAppBar(
shape: const CircularNotchedRectangle(),//凹槽
notchMargin: 5.0,
padding: const EdgeInsets.fromLTRB(0, 6, 0, 6),
child: Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: [
Expanded(
flex: 1,
child: InkWell(
onTap: () {
changeCurrentIndex(0);
},
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Icon(Icons.home, color: getColor(0)),
Text('Home', style: TextStyle(color: getColor(0))),
],
),
)),
const SizedBox(width: 80),
Expanded(
flex: 1,
child: InkWell(
onTap: () {
changeCurrentIndex(1);
},
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Icon(Icons.business, color: getColor(1)),
Text('Business', style: TextStyle(color: getColor(1)))
],
),
))
],
),
),
floatingActionButton: FloatingActionButton(
elevation: 10,
onPressed: () {},
child: const Icon(Icons.add, size: 36),
),
floatingActionButtonLocation: FloatingActionButtonLocation.centerDocked,//位置底下中间
),
);
}
Color getColor(int value) {
return currentIndex == value ? Theme.of(context).primaryColor : const Color(0XFFBBBBBB);
}
void changeCurrentIndex(int index) {
setState(() {
currentIndex = index;
});
}
}