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

如何在KivyMD中实现折叠式图标菜单(含展开效果)?

实现可折叠侧边菜单(仅图标/完整内容切换)

直接上可行方案,基于Flutter Material3组件实现需求:

核心思路

通过状态变量控制菜单宽度,结合动画过渡实现折叠/展开效果;菜单列表项根据状态决定是否显示文本,MDTopAppBar的按钮负责切换状态。

完整代码示例

import 'package:flutter/material.dart';

void main() => runApp(const MyApp());

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      theme: ThemeData(useMaterial3: true),
      home: const MenuDemoPage(),
    );
  }
}

class MenuDemoPage extends StatefulWidget {
  const MenuDemoPage({super.key});

  @override
  State<MenuDemoPage> createState() => _MenuDemoPageState();
}

class _MenuDemoPageState extends State<MenuDemoPage> {
  bool _isMenuExpanded = false;
  final double _collapsedWidth = 60; // 折叠状态宽度
  final double _expandedWidth = 240; // 展开状态宽度

  // 构建菜单列表项
  Widget _buildMenuItem(IconData icon, String label) {
    return ListTile(
      leading: Icon(icon, size: 28),
      title: _isMenuExpanded ? Text(label) : null,
      onTap: () {
        // 这里添加菜单点击逻辑
        setState(() {
          _isMenuExpanded = false; // 点击后可自动折叠菜单
        });
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: MDTopAppBar(
        leading: IconButton(
          icon: Icon(_isMenuExpanded ? Icons.close : Icons.menu),
          onPressed: () => setState(() => _isMenuExpanded = !_isMenuExpanded),
        ),
        title: const Text('我的应用'),
      ),
      body: Row(
        children: [
          // 侧边菜单
          AnimatedContainer(
            duration: const Duration(milliseconds: 300),
            width: _isMenuExpanded ? _expandedWidth : _collapsedWidth,
            color: Theme.of(context).colorScheme.surfaceVariant,
            child: ListView(
              padding: EdgeInsets.zero,
              children: [
                // 菜单头部(折叠时仅显示图标)
                SizedBox(
                  height: 80,
                  child: Center(
                    child: _isMenuExpanded
                        ? const Text('用户中心', style: TextStyle(fontSize: 18))
                        : const Icon(Icons.account_circle, size: 40),
                  ),
                ),
                const Divider(),
                _buildMenuItem(Icons.home_outlined, '首页'),
                _buildMenuItem(Icons.settings_outlined, '设置'),
                _buildMenuItem(Icons.notifications_outlined, '通知'),
                _buildMenuItem(Icons.person_outlined, '个人中心'),
              ],
            ),
          ),
          // 主内容区域
          Expanded(
            child: Container(
              color: Theme.of(context).colorScheme.background,
              child: const Center(child: Text('主内容区域')),
            ),
          ),
        ],
      ),
    );
  }
}

关键要点

  1. 动画过渡:用AnimatedContainer实现菜单宽度的平滑变化,避免切换时的生硬感
  2. 状态联动:MDTopAppBar的按钮点击切换_isMenuExpanded状态,同步控制菜单宽度和文本显示
  3. 灵活定制:可根据需求调整折叠/展开的宽度、动画时长,或修改菜单头部的显示内容

为何之前结合失败?

大概率是没绑定状态变量来控制菜单的显示逻辑,或是直接使用MDNavigationDrawer默认样式未做自定义,导致无法实现“仅图标/完整内容”的切换效果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 21:10:51