如何在 Flutter 中创建垂直滚动菜单效果

Posted

技术标签:

【中文标题】如何在 Flutter 中创建垂直滚动菜单效果【英文标题】:How to create a vertical scrolling menu effect in Flutter 【发布时间】:2021-02-22 16:01:21 【问题描述】:

这个问题是对this 问题的改进。在这种情况下,我想重现您可以在我们基础的this 左侧看到的垂直菜单。如果您单击与左侧示例相关的链接,您会看到一些菜单。例如,单击Base,您将看到一个垂直菜单出现和消失。我也想知道如何重现它。一个示例代码将不胜感激。

谢谢大家

【问题讨论】:

这能回答你的问题吗? How to create an admin UI left menu with Flutter 【参考方案1】:

您只需使用StatefulWidget 并使用布尔值管理隐藏/显示功能即可实现此目的。

这是更新后的代码:

import 'package:flutter/material.dart';

final Color darkBlue = Color.fromARGB(255, 18, 32, 47);

void main() 
  runApp(MyApp());


class MyApp extends StatelessWidget 
  @override
  Widget build(BuildContext context) 
    return MaterialApp(
      theme: ThemeData.dark().copyWith(scaffoldBackgroundColor: darkBlue),
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        body: Center(
          child: MyWidget(),
        ),
      ),
    );
  


class MyWidget extends StatefulWidget 
  @override
  _MyWidgetState createState() => _MyWidgetState();


class _MyWidgetState extends State<MyWidget>
    with SingleTickerProviderStateMixin 
  final colors = <Color>[Colors.indigo, Colors.blue, Colors.orange, Colors.red];

  double _size = 250.0;

  bool _large = true;

  void _updateSize() 
    setState(() 
      _size = _large ? 250.0 : 0.0;
      _large = !_large;
    );
  

  @override
  Widget build(BuildContext context) 
    return Scaffold(
      body: Row(
        children: [
          AnimatedSize(
              curve: Curves.easeIn,
              vsync: this,
              duration: Duration(seconds: 1),
              child: LeftDrawer(size: _size)),
          Expanded(
            flex: 4,
            child: Container(
              child: Column(
                children: [
                  Container(
                    color: Colors.white,
                    padding: const EdgeInsets.all(8),
                    child: Row(
                      children: [
                        IconButton(
                          icon: Icon(Icons.menu, color: Colors.black87),
                          onPressed: () 
                            _updateSize();
                          ,
                        ),
                        FlatButton(
                          child: Text(
                            'Dashboard',
                            style: const TextStyle(color: Colors.black87),
                          ),
                          onPressed: () ,
                        ),
                        FlatButton(
                          child: Text(
                            'User',
                            style: const TextStyle(color: Colors.black87),
                          ),
                          onPressed: () ,
                        ),
                        FlatButton(
                          child: Text(
                            'Settings',
                            style: const TextStyle(color: Colors.black87),
                          ),
                          onPressed: () ,
                        ),
                        const Spacer(),
                        IconButton(
                          icon: Icon(Icons.brightness_3, color: Colors.black87),
                          onPressed: () ,
                        ),
                        IconButton(
                          icon: Icon(Icons.notification_important,
                              color: Colors.black87),
                          onPressed: () ,
                        ),
                        CircleAvatar(),
                      ],
                    ),
                  ),
                  Container(
                    height: 1,
                    color: Colors.black12,
                  ),
                  Card(
                    margin: EdgeInsets.zero,
                    shape: RoundedRectangleBorder(
                      borderRadius: BorderRadius.circular(0),
                    ),
                    child: Container(
                      color: Colors.white,
                      padding: const EdgeInsets.all(20),
                      child: Row(
                        children: [
                          Text(
                            'Home / Admin / Dashboard',
                            style: const TextStyle(color: Colors.black),
                          ),
                        ],
                      ),
                    ),
                  ),
                  Expanded(
                    child: ListView(
                      children: [
                        Row(
                          children: [
                            _container(0),
                            _container(1),
                            _container(2),
                            _container(3),
                          ],
                        ),
                        Container(
                          height: 400,
                          color: Color(0xFFE7E7E7),
                          padding: const EdgeInsets.all(16),
                          child: Card(
                            color: Colors.white,
                            child: Container(
                              padding: const EdgeInsets.all(16),
                              child: Text(
                                'Traffic',
                                style: const TextStyle(color: Colors.black87),
                              ),
                            ),
                          ),
                        ),
                      ],
                    ),
                  ),
                ],
              ),
            ),
          ),
        ],
      ),
    );
  

  Widget _container(int index) 
    return Expanded(
      child: Container(
        padding: const EdgeInsets.all(20),
        color: Color(0xFFE7E7E7),
        child: Card(
          color: Color(0xFFE7E7E7),
          child: Container(
            color: colors[index],
            width: 250,
            height: 140,
            padding: const EdgeInsets.all(20),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Row(
                  children: [
                    Expanded(
                        child: Text(
                      '9.823',
                      style: TextStyle(fontSize: 24),
                    )),
                    Icon(Icons.more_vert),
                  ],
                ),
                Text('Members online')
              ],
            ),
          ),
        ),
      ),
    );
  


class LeftDrawer extends StatefulWidget 
  LeftDrawer(
    Key key,
    this.size,
  ) : super(key: key);

  final double size;

  @override
  _LeftDrawerState createState() => _LeftDrawerState();


class _LeftDrawerState extends State<LeftDrawer> 
  bool dropdownVisible = false;

  @override
  Widget build(BuildContext context) 
    return Expanded(
      flex: 1,
      child: Container(
        width: widget.size,
        color: const Color(0xFF2C3C56),
        child: ListView(
          children: [
            Container(
              alignment: Alignment.center,
              padding: const EdgeInsets.all(16),
              color: Color(0xFF223047),
              child: Text('CORE UI'),
            ),
            _tile('Dashboard'),
            Container(
                padding: const EdgeInsets.only(left: 10),
                margin: const EdgeInsets.only(top: 30),
                child: Text('THEME',
                    style: TextStyle(
                      color: Colors.white54,
                    ))),
            _tile('Colors'),
            _tile('Typography'),
            _tileDropdown('Base'),
            _tile('Buttons'),
          ],
        ),
      ),
    );
  

  Widget _tile(String label) 
    return ListTile(
      title: Text(label),
      onTap: () ,
    );
  

  Widget _option(String label) 
    return ListTile(
      tileColor: Color(0xFF223047),
      contentPadding: const EdgeInsets.only(left: 40),
      title: Text(label),
      onTap: () ,
    );
  

  Widget _tileDropdown(String label) 
    return Column(
      mainAxisSize: MainAxisSize.min,
      children: [
        ListTile(
          title: Text(label),
          onTap: () 
            setState(() 
              dropdownVisible = !dropdownVisible;
            );
          ,
          trailing: dropdownVisible
              ? Icon(Icons.arrow_drop_up)
              : Icon(Icons.chevron_left),
        ),
        Visibility(
          visible: dropdownVisible,
          child: _option('Breadcrumbs'),
        ),
        Visibility(
          visible: dropdownVisible,
          child: _option('Cloud'),
        ),
        Visibility(
          visible: dropdownVisible,
          child: _option('Carousel'),
        ),
        Visibility(
          visible: dropdownVisible,
          child: _option('Collapse'),
        ),
      ],
    );
  

【讨论】:

以上是关于如何在 Flutter 中创建垂直滚动菜单效果的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Flutter 中创建具有固定列的水平滚动表格?

如何在 Swift 中创建单页垂直滚动 PDFView

如何在 Tkinter 中创建垂直菜单栏?

在Flutter中创建有意思的滚动效果 - Sliver系列

在 Flutter 中创建双向 PageView 滚动?

如何在flutter android开发中创建这种布局?