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 天前
谁说终端只能敲键盘?我用 Rust 给小说阅读器加上了鼠标
前端·后端·rust
陈随易1 天前
C++26 草案被否,二十八年来头一回
前端·后端·程序员
ZhengEnCi1 天前
Agent 工具怎么折叠海量输出才「爽」:Trae、Claude Code 的渐进式披露设计原理
前端·agent
IT_陈寒1 天前
Redis内存暴涨,没想到是AOF重写捣的鬼
前端·人工智能·后端
ikoala1 天前
让 Codex 自己查账:一个省 token 的小技巧
前端·后端·ai编程
ikoala1 天前
AI 写页面像说明书,修 Bug 像贴膏药?把这两句话写进 AGENTS.md
前端·javascript·ai编程
好的佩奇1 天前
Dart 之扩展方法
android·flutter·dart
去伪存真1 天前
AI Agent Harness 深度测评与技术选型实战
前端·agent
好的佩奇1 天前
蓝牙之经典蓝牙
android·flutter·蓝牙
FRing031 天前
vue2干货总结7(自定义指令、插槽、单页应用程序、路由的使用(VueRouter))
开发语言·前端·vue.js·vue2