Какими виджетами в Flutter пользуешься чаще всего?

«Какими виджетами в Flutter пользуешься чаще всего?» — вопрос из категории Flutter виджеты, который задают на 29% собеседований Flutter Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Я условно делю часто используемые виджеты на несколько категорий:

1. Виджеты компоновки (Layout): Базовый строительный блок любого UI.

  • Column / Row: Для вертикального и горизонтального расположения дочерних виджетов.
  • Stack: Для наложения виджетов друг на друга (например, кнопка поверх изображения).
  • Expanded / Flexible: Для управления тем, как дочерние виджеты внутри Column/Row занимают доступное пространство.
  • Container: Универсальный виджет для отступов (padding), границ (decoration), ограничений по размеру (constraints).

2. Виджеты для списков и скролла:

  • ListView: Основной виджет для скроллируемых списков. Чаще всего использую ListView.builder для эффективного рендеринга больших списков.
  • GridView: Для отображения данных в виде сетки.
  • SingleChildScrollView: Для добавления скролла к экрану, который не помещается в область просмотра.

3. Базовые виджеты содержимого и интерактива:

  • Text с TextStyle: Для любого текста.
  • ElevatedButton, TextButton, IconButton: Для интерактивных элементов.
  • TextField: Для ввода текста.
  • Image (.asset, .network): Для отображения изображений.

4. Структурные виджеты:

  • Scaffold: Каркас экрана, предоставляет AppBar, Drawer, BottomNavigationBar, FloatingActionButton.
  • MaterialApp / CupertinoApp: Корневой виджет, задающий дизайн-систему и навигацию всего приложения.

Пример типичной структуры экрана:

Scaffold(
  appBar: AppBar(title: Text('Список товаров')),
  body: Column(
    crossAxisAlignment: CrossAxisAlignment.stretch,
    children: [
      Padding(
        padding: EdgeInsets.all(16.0),
        child: TextField(decoration: InputDecoration(hintText: 'Поиск...')),
      ),
      Expanded(
        child: ListView.builder(
          itemCount: products.length,
          itemBuilder: (context, index) {
            return ProductCard(product: products[index]);
          },
        ),
      ),
    ],
  ),
  floatingActionButton: FloatingActionButton(
    onPressed: () => _addNewProduct(),
    child: Icon(Icons.add),
  ),
)