Основы компоновки Flutter

Компоновка — ключевая концепция в разработке UI на Flutter.

В этом разделе будут представлены наиболее часто используемые виджеты компоновки, включая Row, Column, Stack, Flex и т. д.


Обзор виджетов компоновки

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

ВиджетНазначение
RowРасположение дочерних виджетов по горизонтали
ColumnРасположение дочерних виджетов по вертикали
СтекДочерние виджеты Stack
FlexГибкая линейная компоновка (базовый класс для Row/Column)
GridViewСеточная компоновка
ListViewСписочная компоновка

Row - горизонтальная компоновка

Row используется для размещения дочерних виджетов в горизонтальном направлении.

Пример: базовое использование Row

// Разместить три иконки по горизонтали
Row(
  children: [
    Icon(Icons.home, color: Colors.blue),
    Icon(Icons.search, color: Colors.green),
    Icon(Icons.settings, color: Colors.grey),
  ],
)

// Row с интервалами
Row(
  mainAxisAlignment: MainAxisAlignment.spaceEvenly,  // Выравнивание по главной оси
  children: [
    Icon(Icons.home, color: Colors.blue),
    Icon(Icons.search, color: Colors.green),
    Icon(Icons.settings, color: Colors.grey),
  ],
)

mainAxisAlignment - Выравнивание по главной оси

ЗначениеОписание
MainAxisAlignment.startВыравнивание по левому краю (по умолчанию)
MainAxisAlignment.centerВыравнивание по центру
MainAxisAlignment.endВыравнивание по правому краю
MainAxisAlignment.spaceBetweenПространство между, равные интервалы между элементами
MainAxisAlignment.spaceEvenlyРавные интервалы между элементами и по краям
MainAxisAlignment.spaceAroundРавные интервалы между элементами, больше, чем отступы по краям

Column — вертикальная компоновка

Column используется для размещения дочерних виджетов в вертикальном направлении.

Пример: базовое использование Column

// Расположить три текста вертикально
Column(
  children: [
    Text('Первая строка', style: TextStyle(fontSize: 20)),
    Text('Вторая строка', style: TextStyle(fontSize: 20)),
    Text('Третья строка', style: TextStyle(fontSize: 20)),
  ],
)

// Column с промежутками и выравниванием
Column(
  mainAxisAlignment: MainAxisAlignment.center,  // По центру по вертикали
  crossAxisAlignment: CrossAxisAlignment.start,  // По левому краю по горизонтали
  children: [
    Text('Заголовок', style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold)),
    const SizedBox(height: 8),
    Text('содержимое содержимое содержимое'),
    const SizedBox(height: 8),
    Text('Описание внизу'),
  ],
)

crossAxisAlignment - выравнивание по поперечной оси

ЗначениеОписание
CrossAxisAlignment.startВыровнять по верхнему/левому краю
CrossAxisAlignment.centerВыравнивание по центру
CrossAxisAlignment.endВыровнять по нижнему/правому краю
CrossAxisAlignment.stretchРастянуть, чтобы заполнить родительский контейнер

Expanded и Flexible

Expanded и Flexible используются, чтобы дочерние виджеты заполняли оставшееся пространство.

Пример: использование Expanded

// Фиксированная ширина + адаптивная ширина
Row(
  children: [
    // Фиксированная ширина 100
    Container(width: 100, height: 50, color: Colors.red),
    // Занимает оставшееся пространство
    Expanded(
      child: Container(height: 50, color: Colors.green),
    ),
    // Фиксированная ширина 50
    Container(width: 50, height: 50, color: Colors.blue),
  ],
)

// Коэффициент распределения
Row(
  children: [
    // Занимает 1 часть
    Expanded(
      flex: 1,
      child: Container(height: 50, color: Colors.red),
    ),
    // Занять 2 части
    Expanded(
      flex: 2,
      child: Container(height: 50, color: Colors.green),
    ),
    // Занимает 1 часть
    Expanded(
      flex: 1,
      child: Container(height: 50, color: Colors.blue),
    ),
  ],
)

Stack - Макет с наложением

Stack используется для наложения дочерних виджетов друг на друга; часто используется для создания таких эффектов, как плавающие элементы и наложение слоёв.

Пример: использование Stack

// Базовый Stack
Стек(
  children: [
    // Нижний слой: фоновое изображение
    Контейнер(
      width: 200,
      height: 200,
      color: Colors.blue,
    ),
    // Средний слой: полупрозрачный оверлей
    Контейнер(
      width: 180,
      height: 180,
      color: Colors.white.withOpacity(0.5),
    ),
    // Верхний слой: текст
    const Center(
      child: Text(
        'Содержимое оверлея',
        style: TextStyle(color: Colors.white, fontSize: 24),
      ),
    ),
  ],
)

// Stack с позиционированием
Стек(
  children: [
    Container(color: Colors.grey[300]),
    // Расположено в правом верхнем углу
    Positioned(
      right: 10,
      top: 10,
      child: Icon(Icons.close, color: Colors.red),
    ),
    // Расположено в левом нижнем углу
    Positioned(
      left: 10,
      bottom: 10,
      child: Text('Текст в левом нижнем углу'),
    ),
  ],
)

Padding и Margin

Используйте Padding и Margin для управления отступами и полями элементов.

Пример: Padding и Margin

// Используйте Padding для установки padding
Внутренний отступ(
  padding: const EdgeInsets.all(16.0),  // Все четыре стороны 16 пикселей
  child: Text('Текст с отступами'),
)

// Установить каждую сторону отдельно
Внутренний отступ(
  padding: EdgeInsets.only(
    left: 10,
    right: 20,
    top: 5,
    bottom: 5,
  ),
  child: Text('Пользовательские отступы'),
)

// Используйте EdgeInsets.symmetric для симметричных отступов
Внутренний отступ(
  padding: EdgeInsets.symmetric(horizontal: 16, vertical: 8),
  child: Text('По горизонтали 16, по вертикали 8'),
)

// Container, объединяющий margin и padding
Контейнер(
  margin: const EdgeInsets.all(10),  // Внешний отступ
  padding: const EdgeInsets.all(16),  // Внутренний отступ
  decoration: BoxDecoration(
    color: Colors.blue[100],
    borderRadius: BorderRadius.circular(8),
  ),
  child: Text('Содержимое контейнера'),
)

Scaffold и AppBar

Scaffold обеспечивает базовую структуру страницы Material Design, AppBar — это верхняя панель приложения.

Пример: Базовая структура Scaffold

// Каркас страницы Material Design
Scaffold(
  // Верхняя панель приложения
  appBar: AppBar(
    title: const Text('Моё приложение'),
    backgroundColor: Colors.blue,
    elevation: 4,  // Глубина тени
    actions: [
      IconButton(
        icon: const Icon(Icons.search),
        onPressed: () {},
      ),
      IconButton(
        icon: const Icon(Icons.settings),
        onPressed: () {},
      ),
    ],
  ),
  // Тело страницы
  body: const Center(
    child: Text('содержимое страницы'),
  ),
  // Плавающая кнопка действия
  floatingActionButton: FloatingActionButton(
    onPressed: () {},
    child: const Icon(Icons.add),
  ),
  // Нижняя панель навигации
  bottomNavigationBar: BottomNavigationBar(
    items: const [
      BottomNavigationBarItem(icon: Icon(Icons.home), label: 'Главная'),
      BottomNavigationBarItem(icon: Icon(Icons.search), label: 'Поиск'),
      BottomNavigationBarItem(icon: Icon(Icons.person), label: 'Мой'),
    ],
  ),
)
Другие расширения