flutter 3.x中实现底部导航凸起样式

一般实现需要有两种方式,一个是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;
    });
  }
}
相关推荐
陈随易1 天前
有生之年系列,Nodejs进程管理pm2 v7.0发布
前端·后端·程序员
冰暮流星1 天前
javascript之事件代理/事件委托
前端
陈随易1 天前
AI时代,你还在坚持手搓文章吗
前端·后端·程序员
jiejiejiejie_1 天前
Flutter for OpenHarmony 心情日记功能实战指南
flutter·华为
jiejiejiejie_1 天前
Flutter for OpenHarmony 倒计时功能实战开发
flutter
Math_teacher_fan1 天前
Flutter 跨平台开发实战:鸿蒙与音乐律动艺术(六)、Lissajous 利萨茹曲线:频率耦合的轨迹艺术
flutter·ui·数学建模·华为·harmonyos·鸿蒙系统
里欧跑得慢1 天前
17. Flutter Hero动画实现:让界面过渡更加优雅
前端·css·flutter·web
IT_陈寒1 天前
Vue的这个响应式陷阱,我debug了一整天才爬出来
前端·人工智能·后端
kyriewen1 天前
前端测试:别为了100%覆盖率而写测试,那是自欺欺人
前端·javascript·单元测试
liulian09161 天前
Flutter for OpenHarmony 跨平台开发:秒表功能实战指南
flutter