Оживи свои экраны, реагируя на нажатия кнопок и обновляя изображение через setState.
Открыть этот урок в KodokonНаши экраны красивые, но застывшие: пора реагировать на действия пользователя. Стандартная кнопка Material 3 - это ElevatedButton. Она принимает два ключевых параметра: child, её отображаемое содержимое (часто Text), и onPressed, функцию, которая выполняется при нажатии. Функция, переданная вот так в качестве параметра, называется колбэком: ты не вызываешь её сам, Flutter вызывает её за тебя в нужный момент. Синтаксис () { ... } создаёт анонимную функцию, без имени, написанную прямо на месте.
import 'package:flutter/material.dart';
Widget buildHelloButton() {
return ElevatedButton(
onPressed: () {
debugPrint("Button pressed!");
},
child: const Text("Tap here"),
);
}debugPrint пишет в консоль... но сам экран не меняется. Почему? Потому что StatelessWidget (виджет без состояния) застывший: однажды построенный, он больше не может измениться. Чтобы показывать меняющееся значение, нужен StatefulWidget (виджет с состоянием). Состояние - это набор данных, которые могут меняться в течение жизни виджета: счётчик, отмеченный флажок, введённый текст... StatefulWidget всегда идёт в паре с классом State, который хранит эти данные и содержит метод build. Вот великая классика первых шагов: счётчик.
import 'package:flutter/material.dart';
void main() {
runApp(const CounterApp());
}
class CounterApp extends StatelessWidget {
const CounterApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(useMaterial3: true),
home: const CounterPage(),
);
}
}
class CounterPage extends StatefulWidget {
const CounterPage({super.key});
@override
State<CounterPage> createState() =>
_CounterPageState();
}
class _CounterPageState extends State<CounterPage> {
int count = 0;
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
"Counter: $count",
style: const TextStyle(fontSize: 32),
),
const SizedBox(height: 16),
ElevatedButton(
onPressed: () {
setState(() {
count = count + 1;
});
},
child: const Text("+1"),
),
],
),
),
);
}
}Механизм состоит из трёх шагов. 1) Переменная count живёт в _CounterPageState: это и есть состояние. 2) При каждом нажатии колбэк вызывает setState: этот метод меняет состояние и сообщает Flutter, что что-то изменилось. 3) Тогда Flutter заново выполняет build, который перерисовывает экран с новым значением count. Запомни философию: ты никогда не меняешь экран напрямую, ты меняешь данные, а Flutter берёт на себя отображение.