Рубрики
Flutter

Flutter Drawer — гамбургер-меню

Это статья о меню Flutter Drawer, как его добавить в ваш проект и минимальные настройки данного виджета.

Создайте новый проект Flutter Project в Android Studio или в редакторе которым, вы пользуетесь.

Для того, чтобы создать гамбургер-меню, вам понадобится добавить в свой код всего лишь одну строку:

drawer: Drawer(),

Полный код выглядит следующим образом:

import 'package:flutter/material.dart';

void main() {
  runApp(
    MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          centerTitle: true,
          title: Text('Меню-гамбургер'),
          backgroundColor: Colors.green[600],
        ),
        body: App(),
        drawer: Drawer(), // <- сюда надо будет добавить примеры из статьи
      ),
    ),
  );
}

class App extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container();
  }
}
Drawer, меню-гамбургер

Попробуйте покликать, оно раскрывается и закрывается. Согласитесь, что это чудесно, что нет необходимости писать много кода, а мы уже получили нужный результат.

Дальше мы совсем быстро добавим в открывающееся меню список с выбором действий.

drawer: Drawer(
  child: 
),

Мы можем добавить любое количество дочерних объектов в меню, просто дополняя список:

drawer: Drawer(
          child: ListView(
            children: <Widget>[
              ListTile(
                title: Text("Меню 1"),
                trailing: Icon(Icons.arrow_back),
              ),
              ListTile(
                title: Text("Меню 2"),
                trailing: Icon(Icons.arrow_downward),
              ),
            ],
          ),
      ),

Теперь посмотрите как просто добавить в ваше меню заголовок. Мы просто создаем DrawerHeader и создаем виджет Text:

drawer: Drawer(
          child: new DrawerHeader(
            child: new Text("Заголовок меню"),
            decoration: BoxDecoration (
                color: Colors.green),)
      ),
DrawerHeader flutter

В приведенном примере заголовок занимает все 100% экрана. Это все из за того, что у нас никаких дочерних объектов. Для того чтобы поместить заголовок вверх, нам надо использовать виджеты, которые могут содержать несколько виджетов (например children:), такие как Column или ListView.

Давайте в этом примере используем ListView:

drawer: new Drawer(
  child: new ListView(
    children: <Widget>[
      new DrawerHeader(
        child: new Text("Заголовок меню"),
        decoration: new BoxDecoration(
            color: Colors.green
        ),
      )
    ],
  )
),

Теперь это стало похоже на приложения, к которым мы привыкли. Будь то почтовый клиент Google или Telegram или любое другое приложение.

Приведем полный код, для того чтобы вы могли его просто вставить:

import 'package:flutter/material.dart';

void main() {
  runApp(
    MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          centerTitle: true,
          title: Text('Меню-гамбургер'),
          backgroundColor: Colors.green[600],
        ),
        body: App(),
        drawer: Drawer(
          child: new ListView(
            children: <Widget>[
              new DrawerHeader (
                child: new Text("Ваш заголовок вверху"),
                decoration: BoxDecoration (
                color: Colors.green),
        )],
      ),
    ),
  )));
}

class App extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container();
  }
}

Добавление списка в меню #

Теперь добавим в наше меню некоторый список с меню. Список добавляется с помощью ListTile. Посмотрите как это красиво получается. Событие onTap пока обрабатывать не будем, рассмотрим его в другой статье.

        drawer: Drawer(
          child: new ListView(
            children: <Widget>[
              new DrawerHeader (
                child: new Text("Ваш заголовок вверху"),
                decoration: BoxDecoration (
                color: Colors.green),
        ),
            new ListTile(
              title: new Text("О себе"),
              onTap: (){}
            ), 
            new ListTile(
                title: new Text("Настройки"),
                onTap: (){}
              )
            ],
      ),
    ),
Drawer LisrTile Flutter

Теперь немного добавим информацию о себе. По умолчанию, если вы задавали тему для приложения, цвет UserAccountsDrawerHeader будет светло-голубым. Мы сразу изменили цвет на green.

 new DrawerHeader(
              child: UserAccountsDrawerHeader (
                decoration: BoxDecoration(
                color: Colors.green,),
                accountName: Text('Мистер Твистер'),
                accountEmail: Text("home@dartflutter.ru"),
 ),)

Как видим у нас после изменения цвета появился отступ. Для того чтобы его убрать нам необходимо задать в виджете Drawer следующие свойства:

margin: EdgeInsets.zero,
padding: EdgeInsets.zero,

Приведем полностью код проекта

import 'package:flutter/material.dart';
void main() {
  runApp(
    MaterialApp(
     home: Scaffold(
        appBar: AppBar(
          centerTitle: true,
          title: Text('Меню-гамбургер'),
          backgroundColor: Colors.green[600],
        ),
        body: App(),
        drawer: Drawer(
          child: new ListView(
            children: <Widget>[
              new DrawerHeader(
                margin: EdgeInsets.zero,
                padding: EdgeInsets.zero,
                child: UserAccountsDrawerHeader (
                  decoration: BoxDecoration(color: Colors.green),
                  accountName: Text('Мистер Твистер'),
                  accountEmail: Text("home@dartflutter.ru"),
 ),
 ),
            new ListTile(
              title: new Text("О себе"),
              onTap: (){}
            ),
            new ListTile(
                title: new Text("Настройки"),
                onTap: (){}
              )
            ],
      ),
    ),
  )));
}
class App extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container();
  }
}

Теперь давайте добавим значки слева от пунктов меню (добавим значение leading для каждого ListTile :

new ListTile(
              title: new Text("О себе"),
                leading: Icon(Icons.account_box),
              onTap: (){}
            ),
            new ListTile(
                title: new Text("Настройки"),
                leading: Icon(Icons.settings),
                onTap: (){}
              )

Добавляем аватарку во Flutter Drawer #

Итак, данное меню, становится похоже на настоящее. Кажется не хватает места для аватарки. Мы не будем вас смущать своим фото, просто закрасим место под аватарку красным цветом. На просторах интернета вы найдете много вариантов с круглой аватаркой, мы же вам покажем как сделать квадратную.

currentAccountPicture: Container(
                    decoration: BoxDecoration(
                      shape: BoxShape.rectangle,
                      color: Colors.red,
                    )
                  ),

В виджете UserAccountsDrawerHeader мы добавляем свойство currentAccountPicture, затем создаем контейнер и строкой shape: BoxShape.rectangle мы изменяем место под фото со стандартного круга на прямоугольник.

Drawer UserAccountsDrawerHeader

Cобственно, на этом на сегодня остановимся. Приведу полностью получившийся код:

import 'package:flutter/material.dart';

void main() {
  runApp(
    MaterialApp(
      home: Scaffold(
       appBar: AppBar(
          centerTitle: true,
          title: Text('Меню-гамбургер'),
          backgroundColor: Colors.green[600],
        ),
        body: App(),
        drawer: Drawer(
          child: new ListView(
            children: <Widget>[
              new DrawerHeader(
                margin: EdgeInsets.zero,
                padding: EdgeInsets.zero,
                child: UserAccountsDrawerHeader (
                  decoration: BoxDecoration(color: Colors.green),
                  accountName: Text('Мистер Твистер'),
                  accountEmail: Text("home@dartflutter.ru"),
                  currentAccountPicture: Container(
                    decoration: BoxDecoration(
                      shape: BoxShape.rectangle,
                      color: Colors.red,
                    )
                  ),
              ),
                ),
            new ListTile(
              title: new Text("О себе"),
                leading: Icon(Icons.account_box),
              onTap: (){}
            ),
            new ListTile(
                title: new Text("Настройки"),
                leading: Icon(Icons.settings),
                onTap: (){}
              )
            ],
      ),
    ),
  )));
}
class App extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container();
  }
}