Ответ
Виджеты (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
],
),
);
}
} Ответ 18+ 🔞
Э, слушай, давай разберёмся с этими вашими виджетами во Flutter, а то народ путается, как будто в первый раз слышит. Представь, что ты строишь интерфейс из кубиков Лего, только цифровых. Вот эти кубики — и есть виджеты. Всё, что ты видишь на экране: текст, кнопка, картинка, даже пустое место — это ёпта виджет. Овердохуища их там, на любой вкус.
Главная фишка в том, что ты не лезешь вручную и не говоришь: «Эй, кнопка, измени цвет!». Ты просто описываешь, как вся эта сбруя должна выглядеть прямо сейчас. А движок Flutter, хитрая жопа, сам соображает, что поменялось с прошлого раза, и перерисовывает только нужные куски. Эффективно, чёрт возьми. Это называется декларативный подход — ты не командуешь, а заявляешь.
А собирается всё это добро через композицию. То есть ты берешь простые виджеты и вкладываешь их друг в друга, как матрёшку, пока не получится целый экран. Ебать копать, даже тема приложения или отступ — это тоже виджеты, просто невидимые.
Теперь, внимание, блядь, самое важное разделение. Виджеты бывают двух сортов, как люди: спокойные и нервные.
-
StatelessWidget— это как монах-отшельник. Создали его один раз, передали какие-то параметры (например, заголовок текста), и всё. У него внутри нет своего изменяемого состояния. Он посмотрел на переданные данные и отрисовался. Хоть сто раз его перестраивай — он будет одинаковым, пока ему не скормят новые параметры. Доверия ебать ноль к его самостоятельности, но зато надёжный. -
StatefulWidget— вот это уже персонаж с характером. Он состоит из двух половинок. Первая — сам виджет, такой же иммутабельный кореш. А вторая — объектState, это его личный дневник и бардак в одной комнате. Там хранятся изменяемые данные (например, счётчик нажатий). Когда данные меняются, этотStateкричитsetState()— и Flutter понимает, что пора перерисовать эту часть интерфейса заново, с новыми данными. Без этого вызова — нихуя не изменится, хоть обосрись.
Смотри на примере, тут всё станет понятнее. Вот тебе Stateless — заголовок, который просто показывает то, что ему дали:
class MyHeader extends StatelessWidget {
final String title; // Параметр, который ему передали. Final — менять низя.
const MyHeader({super.key, required this.title});
@override
Widget build(BuildContext context) {
return Text( // Возвращает виджет Text
title, // с переданным заголовком
style: Theme.of(context).textTheme.headlineMedium,
);
}
}
А вот его нервный братан Stateful — кнопка-счётчик:
class CounterButton extends StatefulWidget {
const CounterButton({super.key});
@override
State<CounterButton> createState() => _CounterButtonState(); // Создаёт свой State
}
class _CounterButtonState extends State<CounterButton> {
int _counter = 0; // Вот оно, состояние! Менять можно.
void _increment() {
setState(() { // КРИЧИМ движку: "Бля, состояние поменялось, перерисуй меня!"
_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
],
),
);
}
}
Вот и вся магия. Сначала терпения ноль ебать кажется, что много буков, но потом втягиваешься. Главное — понять эту разницу между Stateless и Stateful и что setState() — это волшебный пендель для перерисовки. Всё остальное — просто комбинирование этих кубиков. Пизда рулю, когда осознаёшь.