Открывай и закрывай экраны через Navigator.push и pop, передавай данные через конструкторы и получай результат, когда экран закрывается.
Открыть этот урок в KodokonFlutter управляет твоими экранами как стеком: Navigator.push кладёт новый экран сверху, Navigator.pop убирает верхний и показывает предыдущий. Каждый экран - это маршрут (route), а MaterialPageRoute даёт нативный переход платформы. Кнопка «Назад» на Android вызывает pop за тебя, без единой строчки кода.
import 'package:flutter/material.dart';
class HomeScreen extends StatelessWidget {
const HomeScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Home')),
body: Center(
child: FilledButton(
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) {
return const DetailScreen(
productName: 'Headphones',
);
},
),
);
},
child: const Text('View product'),
),
),
);
}
}Чтобы передать данные на следующий экран, никакого волшебного механизма нет: экран назначения - это такой же виджет, как любой другой, и он получает свои данные через конструктор. Это типизировано, явно, и компилятор поймает тебя, если поля не хватает. Заметь, что AppBar открытого экрана показывает кнопку «Назад» без единой написанной тобой строчки.
import 'package:flutter/material.dart';
class DetailScreen extends StatelessWidget {
const DetailScreen({
super.key,
required this.productName,
});
final String productName;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text(productName)),
body: Center(
child: FilledButton(
onPressed: () {
Navigator.pop(context, true);
},
child: const Text('Add to cart'),
),
),
);
}
}Navigator.push возвращает Future, который завершается при закрытии экрана значением, переданным в pop. Значит, ты можешь дождаться результата экрана: подтверждения, выбранного из списка элемента, заполненной формы. Обобщённый тип push<bool> документирует, что именно ты ожидаешь получить назад.
import 'package:flutter/material.dart';
Future<void> openDetail(BuildContext context) async {
final added = await Navigator.push<bool>(
context,
MaterialPageRoute<bool>(
builder: (context) {
return const DetailScreen(
productName: 'Headphones',
);
},
),
);
if (!context.mounted) return;
final message = (added ?? false)
? 'Product added to cart'
: 'No product added';
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(message)),
);
}