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

如何使用Flutter GetX实现侧边栏及类网页标签式导航菜单

嘿,我来帮你搞定用Flutter GetX实现侧边栏和标签页式导航菜单的问题!下面分两部分一步步来,代码示例都给你写好啦。

一、用Flutter GetX实现基础侧边栏

GetX的状态管理可以轻松控制侧边栏的显示/隐藏,咱们先从最简单的抽屉式侧边栏开始:

1. 创建侧边栏状态控制器

先写一个SidebarController来管理侧边栏的展开状态:

import 'package:get/get.dart';

class SidebarController extends GetxController {
  // 用Rx变量监听侧边栏是否展开
  final RxBool isSidebarOpen = false.obs;

  // 切换侧边栏状态的方法
  void toggleSidebar() {
    isSidebarOpen.value = !isSidebarOpen.value;
  }
}

2. 在主页面使用控制器

在主页面中,我们可以用Obx或GetBuilder来监听状态变化,控制侧边栏的显示。这里用抽屉式的Drawer为例:

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

class MainPage extends StatelessWidget {
  // 初始化控制器(GetX会自动管理生命周期)
  final SidebarController sidebarController = Get.put(SidebarController());

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("GetX侧边栏示例"),
        // 点击按钮切换侧边栏
        leading: IconButton(
          icon: const Icon(Icons.menu),
          onPressed: sidebarController.toggleSidebar,
        ),
      ),
      // 用Obx监听状态,控制抽屉是否展开(也可以直接用Scaffold的drawer)
      drawer: Obx(() => Offstage(
        offstage: !sidebarController.isSidebarOpen.value,
        child: Drawer(
          child: ListView(
            padding: EdgeInsets.zero,
            children: [
              const DrawerHeader(
                decoration: BoxDecoration(color: Colors.blue),
                child: Text("侧边栏头部"),
              ),
              ListTile(
                title: const Text("首页"),
                onTap: () {
                  // 点击菜单项的逻辑
                  sidebarController.toggleSidebar();
                  Get.toNamed("/home");
                },
              ),
              ListTile(
                title: const Text("设置"),
                onTap: () {
                  sidebarController.toggleSidebar();
                  Get.toNamed("/settings");
                },
              ),
            ],
          ),
        ),
      )),
      body: const Center(child: Text("主内容区域")),
    );
  }
}

如果是桌面端想要固定侧边栏,可以用Row布局,把侧边栏和主内容放在一起,用Obx控制侧边栏的宽度切换折叠状态。

二、实现类似网页标签页的侧边栏导航菜单

这种场景下,侧边栏是垂直的导航菜单,点击菜单项后,主内容区域切换对应页面,同时菜单项保持选中状态,就像网页的侧边标签导航。咱们用GetX来管理选中状态和页面切换:

1. 创建导航控制器

这个控制器要管理当前选中的标签索引,以及侧边栏的状态(如果需要折叠):

import 'package:get/get.dart';

class NavigationController extends GetxController {
  // 当前选中的标签索引
  final RxInt currentTabIndex = 0.obs;

  // 切换标签的方法
  void switchTab(int index) {
    currentTabIndex.value = index;
  }
}

2. 构建侧边栏和主内容区域

这里用Row布局适配桌面端(移动端可以改成抽屉+主内容),侧边栏是垂直菜单,主内容用IndexedStack保持页面状态:

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

// 示例页面
class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) => const Center(child: Text("首页"));
}

class ProfilePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) => const Center(child: Text("个人中心"));
}

class SettingsPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) => const Center(child: Text("设置"));
}

class TabSidebarPage extends StatelessWidget {
  final NavigationController navController = Get.put(NavigationController());

  // 页面列表
  final List<Widget> pages = const [
    HomePage(),
    ProfilePage(),
    SettingsPage(),
  ];

  // 菜单列表
  final List<Map<String, dynamic>> menuItems = [
    {"title": "首页", "icon": Icons.home},
    {"title": "个人中心", "icon": Icons.person},
    {"title": "设置", "icon": Icons.settings},
  ];

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Row(
        children: [
          // 侧边栏导航
          Container(
            width: 250,
            color: Colors.grey[100],
            child: ListView.builder(
              itemCount: menuItems.length,
              itemBuilder: (context, index) {
                // 用Obx监听当前选中状态,动态改变样式
                return Obx(() => ListTile(
                  leading: Icon(
                    menuItems[index]["icon"],
                    color: navController.currentTabIndex.value == index
                        ? Colors.blue
                        : Colors.grey,
                  ),
                  title: Text(
                    menuItems[index]["title"],
                    style: TextStyle(
                      color: navController.currentTabIndex.value == index
                          ? Colors.blue
                          : Colors.black,
                      fontWeight: navController.currentTabIndex.value == index
                          ? FontWeight.bold
                          : FontWeight.normal,
                    ),
                  ),
                  tileColor: navController.currentTabIndex.value == index
                      ? Colors.blue[50]
                      : null,
                  onTap: () => navController.switchTab(index),
                ));
              },
            ),
          ),
          // 主内容区域
          Expanded(
            child: Obx(() => IndexedStack(
              index: navController.currentTabIndex.value,
              children: pages,
            )),
          ),
        ],
      ),
    );
  }
}

关键细节说明

  • 用IndexedStack可以保持每个页面的状态,切换时不会重新初始化页面;
  • 通过Obx监听currentTabIndex的变化,自动更新侧边栏的选中样式和主内容页面;
  • 如果是移动端,可以把侧边栏改成抽屉,点击菜单按钮弹出,逻辑和上面一致,只是布局调整成Scaffold的drawer即可。

内容的提问来源于stack exchange,提问作者j.itD

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 08:31:36