Warm tip: This article is reproduced from stackoverflow.com, please click
flutter flutter-layout flutter-web

How to create an admin UI left menu with Flutter

发布于 2021-03-01 12:22:55

I'm new to flutter but I have a curiosity. Considering the typical bootstrap admin UI that you can find online and the typical left menu, how would you recreate that with flutter? I'm particularly interested on a left menu that can be resized clicking on a button and on a sub-menu that can appear and disappear.

An example can be found here

Edit:

I want to be be clear about the effect I'm trying to reproduce as well. If you click the link relative to the example on the left you see a number of menu. For instance, clicking on Base you are going to see a vertical menu appearing and disappearing. I would like to know how to reproduce it as well.

Thanks

Thanks

Questioner
Alberto
Viewed
0
Ravi Singh Lodhi 2020-11-10 20:37

I have tried to re-create the same design with some minor changes in Flutter. I have to enable flutter web support by following the instructions here: Flutter Web

Flutter Web sample

Regarding the left menu, I have used AnimatedSize widget to give the sliding drawer feel & placed it inside Row.

Please find the code below:

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 StatelessWidget {
  const LeftDrawer({
    Key key,
    this.size,
  }) : super(key: key);

  final double size;

  @override
  Widget build(BuildContext context) {
    return Expanded(
      flex: 1,
      child: Container(
        width: 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'),
            _tile('Base'),
            _tile('Buttons'),
          ],
        ),
      ),
    );
  }

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