Ответ
Виджеты (Widgets) — это фундаментальные, иммутабельные строительные блоки пользовательского интерфейса во Flutter. Всё в UI является виджетом: от структурных элементов (столбцов, строк) до визуальных компонентов (текст, кнопки) и даже тем, отступов.
Основные концепции:
- Декларативный подход: Вы описываете, как UI должен выглядеть при текущем состоянии, а фреймворк сам эффективно обновляет экран.
- Композиция: Сложные интерфейсы создаются путем вложения простых виджетов друг в друга.
- Иммутабельность: Виджеты не изменяются после создания. При изменении состояния или конфигурации создается новый дерево виджетов, а Flutter Framework интеллектуально обновляет только те части экрана, которые действительно изменились.
Два основных типа виджетов:
StatelessWidget: Описывает часть UI, которая зависит только от своей собственной конфигурации (переданных в конструктор параметров). Не имеет внутреннего изменяемого состояния.StatefulWidget: Состоит из двух объектов: самого (иммутабельного) виджета и связанного с ним объектаState, который хранит изменяемые данные и может инициировать перерисовку через вызовsetState().
Пример, демонстрирующий композицию и типы:
// StatelessWidget — зависит только от переданного 'title'
class MyHeader extends StatelessWidget {
final String title;
const MyHeader({super.key, required this.title});
@override
Widget build(BuildContext context) {
return Text(
title,
style: Theme.of(context).textTheme.headlineMedium,
);
}
}
// StatefulWidget — управляет внутренним состоянием '_counter'
class CounterButton extends StatefulWidget {
const CounterButton({super.key});
@override
State<CounterButton> createState() => _CounterButtonState();
}
class _CounterButtonState extends State<CounterButton> {
int _counter = 0;
void _increment() {
setState(() { // Вызов setState заставляет Flutter перестроить этот виджет
_counter++;
});
}
@override
Widget build(BuildContext context) {
// Композиция: кнопка содержит текст
return ElevatedButton(
onPressed: _increment,
child: Text('Нажато $_counter раз'),
);
}
}
// Главный виджет, компонирующий другие
class MyScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
MyHeader(title: 'Демо приложение'), // Stateless
const SizedBox(height: 20),
CounterButton(), // Stateful
],
),
);
}
}