Назад к вопросам
Junior
172
questionbank

Что такое виджет в Flutter и как он отображается на экране?

Sobes Copilot

Получайте ответы в реальном времени

Ответ от нейросети

sobes.tech AI

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

Виджеты образуют дерево виджетов (Widget tree).

Отображение виджета на экране происходит в несколько этапов:

  1. Build: Flutter обходит дерево виджетов и строит дерево элементов (Element tree). Каждый виджет в дереве создает соответствующий ему Element. Element представляет собой конкретный экземпляр виджета, расположенный в определенном месте дерева.
  2. Layout: Для каждого элемента в дереве элементов определяется его размер и позиция. Этот процесс также происходит рекурсивно, снизу вверх. Дочерние элементы предлагают размеры своим родителям, а родители constraints (ограничения) своим дочерним.
  3. Paint: Element делегирует рисование Associated RenderObject. RenderObject — это объект, который знает, как нарисовать себя на экране, используя низкоуровневые API (например, Skia). RenderObject сохраняют размеры и позиции, определенные на этапе Layout.
  4. Composite: Различные RenderObjects объединяются в слои, которые затем отправляются в графический процессор для финального рендеринга.

Когда состояние виджета меняется (например, при вызове setState), Flutter помечает этот виджет как "dirty". В следующем кадре Flutter перестраивает только те виджеты, которые были помечены как "dirty" и их дочерние виджеты. При этом элементы (Element) и объекты рендеринга (RenderObject) переиспользуются, если возможно, что значительно повышает производительность.

// Пример простого виджета StatelessWidget
import 'package:flutter/material.dart';

class MyTextWidget extends StatelessWidget {
  const MyTextWidget({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    // build метод возвращает дерево виджетов
    return const Text('Привет, Flutter!');
  }
}
// Пример виджета StatefulWidget
import 'package:flutter/material.dart';

class CounterWidget extends StatefulWidget {
  const CounterWidget({Key? key}) : super(key: key);

  @override
  _CounterWidgetState createState() => _CounterWidgetState();
}

class _CounterWidgetState extends State<CounterWidget> {
  int _counter = 0;

  void _incrementCounter() {
    // setState помечает виджет как "dirty" и вызывает перерисовку
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: <Widget>[
        const Text('Счетчик:'),
        Text(
          '$_counter',
          style: Theme.of(context).textTheme.headlineMedium,
        ),
        ElevatedButton(
          onPressed: _incrementCounter,
          child: const Text('Увеличить'),
        ),
      ],
    );
  }
}

Виджеты бывают двух основных типов:

Тип Виджета Описание Пример
StatelessWidget Виджеты без внутреннего изменяемого состояния. Зависят только от входных параметров. Text, Icon, Padding
StatefulWidget Виджеты, которые могут изменять свое состояние в течение жизни. Checkbox, Slider, TextField