如何在Flutter中实现侧边悬浮按钮(类似bottom-navigation样式)
Flutter 实现侧边悬浮导航按钮(替代底部导航)
要实现这种固定在屏幕侧边的悬浮导航,核心思路是用Stack布局让导航栏悬浮在页面内容上方,配合Positioned固定位置,再通过状态管理切换页面。下面是完整的实现方案:
1. 封装导航项模型
先把导航按钮需要的图标和对应页面封装成统一模型:
class NavItem { final IconData icon; final IconData activeIcon; final Widget page; NavItem({required this.icon, required this.activeIcon, required this.page}); }
2. 主页面完整实现
用StatefulWidget维护选中状态,通过Stack布局承载页面内容和侧边导航:
import 'package:flutter/material.dart'; class SideNavScreen extends StatefulWidget { const SideNavScreen({super.key}); @override State<SideNavScreen> createState() => _SideNavScreenState(); } class _SideNavScreenState extends State<SideNavScreen> { // 当前选中的导航索引 int _selectedIndex = 0; // 导航项列表,可根据需求自定义 final List<NavItem> _navItems = [ NavItem( icon: Icons.home_outlined, activeIcon: Icons.home, page: const Center(child: Text("首页")), ), NavItem( icon: Icons.search_outlined, activeIcon: Icons.search, page: const Center(child: Text("搜索")), ), NavItem( icon: Icons.favorite_outline, activeIcon: Icons.favorite, page: const Center(child: Text("收藏")), ), NavItem( icon: Icons.person_outlined, activeIcon: Icons.person, page: const Center(child: Text("我的")), ), ]; @override Widget build(BuildContext context) { return Scaffold( body: Stack( children: [ // 页面内容区域,根据选中索引切换页面 IndexedStack( index: _selectedIndex, children: _navItems.map((item) => item.page).toList(), ), // 侧边悬浮导航栏,固定在屏幕右侧 Positioned( top: MediaQuery.of(context).size.height * 0.3, // 垂直位置可自定义 right: 12, // 距离右侧的间距 child: Container( padding: const EdgeInsets.symmetric(vertical: 8), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(30), boxShadow: [ BoxShadow( color: Colors.grey.withOpacity(0.3), blurRadius: 8, offset: const Offset(0, 2), ) ], ), child: Column( mainAxisSize: MainAxisSize.min, children: List.generate(_navItems.length, (index) { return InkWell( onTap: () { setState(() { _selectedIndex = index; }); }, borderRadius: BorderRadius.circular(30), child: Padding( padding: const EdgeInsets.all(12), child: Icon( _selectedIndex == index ? _navItems[index].activeIcon : _navItems[index].icon, color: _selectedIndex == index ? Colors.blue : Colors.grey, size: 24, ), ), ); }), ), ), ), ], ), ); } }
自定义调整说明
- 位置调整:修改
Positioned的top/right属性,可将导航栏移到左侧(把right改成left),或调整垂直位置 - 样式自定义:修改
Container的decoration可以调整导航栏的背景色、圆角、阴影;修改Icon的size/color可以调整按钮样式 - 交互优化:可以给选中的按钮添加圆形背景、点击动画,进一步提升体验
内容的提问来源于stack exchange,提问作者Ali Ahmed
相关产品推荐
相关产品推荐

