Понимание жизненного цикла Flutter: состояния виджетов (Часть 2)
FlutterPulseFlutterPulse
Этот материал был переведён специально для канала
На канале вы найдёте массу интересного о Flutter. Подписывайтесь! 🚀
Введение
В Flutter виджеты — это строительные блоки пользовательского интерфейса. Они определяют, как UI выглядит и реагирует на действия пользователя.
Понимание различий между Stateless и Stateful виджетами — основа для создания эффективных и динамичных Flutter-приложений.
Эта статья разбирает особенности обоих типов, их различия и то, когда использовать каждый из них.
Что такое State?
Прежде чем обсуждать два типа виджетов, нужно понять термин State.
State — это данные или состояние, определяющие внешний вид или поведение виджета в конкретный момент.
Так как Flutter использует ООП, состояние обычно является свойством класса. Например:
class ExampleWidget extends StatelessWidget{
final String _title;
...
}
StatelessWidget VS StatefulWidget
StatelessWidget
Используется для статического контента, который не меняется после построения (текст, иконки).
Не имеет внутреннего состояния и пересоздаётся только при изменении родителя.
Когда использовать:
— Когда виджет не должен меняться.
StatefulWidget
Используется для динамического контента (счётчик, формы).
Имеет внутреннее состояние и пересобирается при его изменении.
Когда использовать:
— Когда UI должен обновляться.
StatelessWidget
StatelessWidget создаётся один раз.
Он может изменять значения, но не состояние.
То есть он неизменяем (immutable).
Жизненный цикл StatelessWidget
У StatelessWidget простой жизненный цикл, так как он неизменяем. После построения он не меняется.
Пример:
class Heading extends StatelessWidget {
final String text;
Heading({this.text});
@override
Widget build(BuildContext context){
return Text(
text,
style: TextStyle(
fontSize: 24.0,
fontWeight: FontWeight.bold,
),
);
}
}
StatefulWidget
StatefulWidget, в отличие от StatelessWidget, может менять свой внешний вид или поведение на основе динамических данных или действий пользователя.
initState()
Первый вызываемый метод в State — initState().
Обычно используется для:
— объявления переменных
— загрузки данных
— API-запросов
— инициализации анимаций и т.п.
class MyStatefulWidget extends StatefulWidget {
...
}
class _MyStatefulWidgetState extends State<MyStatefulWidget> {
late final int _index;
@override
void initState() {
super.initState();
_index = 0;
}
...
}
didChangeDependencies()
Вызывается при изменении зависимостей виджета (например, когда меняются данные из контекста или родителя).
class MyStatefulWidget extends StatefulWidget {
...
}
class _MyStatefulWidgetState extends State<MyStatefulWidget> {
@override
void didChangeDependencies() {
super.didChangeDependencies();
// Логика при изменении зависимостей
}
...
}
build()
Метод, который вызывается каждый раз, когда нужно построить UI.
class MyStatefulWidget extends StatefulWidget {
...
}
class _MyStatefulWidgetState extends State<MyStatefulWidget> {
@override
Widget build(BuildContext context) {
return const Container();
}
...
}
setState()
Сообщает Flutter о том, что состояние изменилось.
После вызова setState() происходит повторный запуск build(), и UI обновляется.
class MyStatefulWidget extends StatefulWidget {
...
}
class _MyStatefulWidgetState extends State<MyStatefulWidget> {
int _index = 0;
@override
Widget build(BuildContext context) {
return TextButton(
onPressed: () => setState(() {
_index = _index + 1;
}),
child: const Text("Increment Button with Index: $_index"),
);
}
}
didUpdateWidget()
Вызывается, когда родительский виджет передаёт новые значения в дочерний.
class MyStatefulWidget extends StatefulWidget {
...
}
class _MyStatefulWidgetState extends State<MyStatefulWidget> {
@override
void didUpdateWidget(covariant MyStatefulWidget oldWidget) {
super.didUpdateWidget(oldWidget);
// Логика при обновлении
}
...
}
dispose()
Вызывается при удалении виджета.
Используется для очистки ресурсов (анимации, контроллеры, стримы).
class MyStatefulWidget extends StatefulWidget {
...
}
class _MyStatefulWidgetState extends State<MyStatefulWidget> {
...
@override
void dispose() {
// ваш код
super.dispose();
}
}