You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从独立文件中渲染Flutter底部导航栏Widget?

如何将Flutter底部导航栏抽成独立可复用Widget(遵循DRY原则)

当然可以把重复的底部导航栏封装成独立Widget,彻底消除代码冗余,下面是具体实现步骤:

1. 新建独立的导航栏Widget文件

创建custom_bottom_navbar.dart文件,把导航栏代码封装成一个可配置的StatelessWidget,将动态参数(当前选中索引、点击回调)暴露给外部:

import 'package:flutter/material.dart';

class CustomBottomNavbar extends StatelessWidget {
  final int currentIndex;
  final void Function(int) onItemTapped;

  const CustomBottomNavbar({
    super.key,
    required this.currentIndex,
    required this.onItemTapped,
  });

  @override
  Widget build(BuildContext context) {
    return BottomNavigationBar(
      items: const <BottomNavigationBarItem>[
        BottomNavigationBarItem(
          icon: Icon(Icons.home),
          label: 'Home',
          backgroundColor: Colors.green,
        ),
        BottomNavigationBarItem(
          icon: Icon(Icons.search),
          label: 'Search',
          backgroundColor: Colors.yellow,
        ),
        BottomNavigationBarItem(
          icon: Icon(Icons.person),
          label: 'Profile',
          backgroundColor: Colors.blue,
        ),
      ],
      type: BottomNavigationBarType.shifting,
      currentIndex: currentIndex,
      selectedItemColor: Colors.black,
      iconSize: 40,
      onTap: onItemTapped,
      elevation: 5,
    );
  }
}

2. 在页面中复用该Widget

修改你的Home页面(以及其他需要底部导航的页面),导入自定义导航栏,替换原有的硬编码导航栏:

import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';
// 导入自定义导航栏文件
import 'custom_bottom_navbar.dart';

class Home extends StatefulWidget {
  const Home({Key? key}) : super(key: key);

  @override
  _HomeState createState() => _HomeState();
}

class _HomeState extends State<Home> {
  int _selectedIndex = 0;
  final List<String> pages = ['home', 'search', 'profile'];

  void _onItemTapped(int index) {
    String page = pages[index];
    context.go('/$page');
    // 更新选中索引,保持导航栏状态同步
    setState(() => _selectedIndex = index);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: const SafeArea(
        child: Center(
          child: Text("Home page", style: TextStyle(fontSize: 50)),
        ),
      ),
      // 直接复用自定义导航栏
      bottomNavigationBar: CustomBottomNavbar(
        currentIndex: _selectedIndex,
        onItemTapped: _onItemTapped,
      ),
    );
  }
}

3. 进阶优化:统一管理导航状态(可选)

如果不想每个页面都维护_selectedIndex,可以利用GoRouter的当前路由自动判断选中项,进一步简化代码:

修改custom_bottom_navbar.dart,添加路由匹配逻辑:

import 'package:flutter/material.dart';
import 'package:go_router/go_router.dart';

class CustomBottomNavbar extends StatelessWidget {
  final void Function(int) onItemTapped;

  const CustomBottomNavbar({
    super.key,
    required this.onItemTapped,
  });

  // 根据当前路由自动获取选中索引
  int _getCurrentIndex(BuildContext context) {
    final location = GoRouterState.of(context).location;
    if (location.contains('/search')) return 1;
    if (location.contains('/profile')) return 2;
    return 0;
  }

  @override
  Widget build(BuildContext context) {
    return BottomNavigationBar(
      // 省略其他固定配置...
      currentIndex: _getCurrentIndex(context),
      onTap: onItemTapped,
    );
  }
}

这样每个页面就不需要维护_selectedIndex状态了,完全遵循DRY原则。

内容的提问来源于stack exchange,提问作者Duddy67

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 22:45:31