Flutter Stack Menu

When hamburger menu is clicked, the main content slides left and scale smaller to reveal sidebar.

import 'package:flutter/material.dart';

class StackPage extends StatefulWidget {
  @override
  _StackPageState createState() => _StackPageState();
}

class _StackPageState extends State<StackPage>
    with SingleTickerProviderStateMixin {
  AnimationController _controller;

  @override
  void initState() {
    _controller =
        AnimationController(vsync: this, duration: Duration(milliseconds: 500));
    super.initState();
  }

  void _toggle() {
    setState(() {
      _controller.isDismissed ? _controller.forward() : _controller.reverse();
    });
  }

  FlatButton _menuItem(IconData icon, String text, VoidCallback onPressed){
    return FlatButton(onPressed: onPressed, child: Row(
      children: [
        Icon(icon, color: Colors.white,),
        SizedBox(width: 8,),
        Text(text, style: TextStyle(color: Colors.white),)
      ],
    ));
  }

  @override
  Widget build(BuildContext context) {
    return AnimatedBuilder(
      animation: _controller,
      builder: (BuildContext context, Widget child) {
        double slide = 50 * _controller.value;
        double scale = 1 - (_controller.value * 0.5);
        return Stack(
          children: [
            Container(
              width: double.infinity,
              color: Colors.lightBlueAccent,
              child: Padding(
                padding: const EdgeInsets.only(
                    top: 50.0, left: 16.0, right: 16.0, bottom: 16.0),
                child: Row(
                  mainAxisAlignment: MainAxisAlignment.start,
                  crossAxisAlignment: CrossAxisAlignment.start,
                  children: [
                    Expanded(
                      child: Column(
                        crossAxisAlignment: CrossAxisAlignment.start,
                        children: [
                          Text(
                            'Navigation',
                            style: Theme.of(context).textTheme.headline6,
                          ),
                          _menuItem(Icons.home, 'Home', (){}),
                          _menuItem(Icons.pages, 'Page 1', (){}),
                          _menuItem(Icons.palette, 'Page 2', (){}),
                          _menuItem(Icons.close, 'Close Menu', () => _toggle()),
                        ],
                      ),
                      flex: 5,
                    ),
                    Expanded(
                      child: Container(),
                      flex: 5,
                    )
                  ],
                ),
              ),
            ),
            Transform(
              transform: Matrix4.identity()
                ..translate(slide)
                ..scale(scale),
              alignment: Alignment.centerRight,
              child: Scaffold(
                appBar: AppBar(
                  title: Text('Example'),
                  actions: [
                    IconButton(
                      icon: Icon(Icons.dehaze),
                      onPressed: () {
                        _toggle();
                      },
                    )
                  ],
                ),
                body: Center(
                  child: Text('Main page'),
                ),
              ),
            ),
          ],
        );
      },
    );
  }
@override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }
}
Scroll to Top