티스토리 뷰
반응형
때때로 새로운 화면에서 이전 화면에 데이터를 반환하고 싶을 때가 있습니다.
예를 들어, 새 화면에서 사용자가 두 가지 옵션 중 하나를 선택할 수 있고, 사용자가 옵션을 선택하면 이전 화면에 그 선택을 알려주어 해당 정보를 기반으로 작업을 수행하게 됩니다.
다음 단계로 Navigator.pop() 메서드를 사용하여 이를 수행할 수 있습니다:
- 홈 화면 정의
- 선택 화면을 여는 버튼 추가
- 두 개의 버튼이 있는 선택 화면 표시
- 버튼이 눌리면 선택 화면 닫기
- 홈 화면에 선택 사항을 스낵바로 표시하기
1. 홈 화면 정의
홈 화면에는 버튼이 표시됩니다. 이 버튼을 탭하면 선택 화면이 시작됩니다.
class HomeScreen extends StatelessWidget {
const HomeScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Returning Data Demo'),
),
// 다음 단계에서 SelectionButton 위젯을 생성합니다.
body: const Center(
child: SelectionButton(),
),
);
}
}
2. 선택 화면을 여는 버튼 추가
이제 SelectionButton을 생성합니다. 이 버튼은 다음을 수행합니다:
- 탭하면 SelectionScreen을 시작합니다.
- SelectionScreen이 결과를 반환할 때까지 대기합니다.
class SelectionButton extends StatefulWidget {
const SelectionButton({super.key});
@override
State<SelectionButton> createState() => _SelectionButtonState();
}
class _SelectionButtonState extends State<SelectionButton> {
@override
Widget build(BuildContext context) {
return ElevatedButton(
onPressed: () {
_navigateAndDisplaySelection(context);
},
child: const Text('Pick an option, any option!'),
);
}
Future<void> _navigateAndDisplaySelection(BuildContext context) async {
// Navigator.push는 SelectionScreen에서 Navigator.pop을 호출한 후에
// 완료되는 Future를 반환합니다.
final result = await Navigator.push(
context,
// 다음 단계에서 SelectionScreen을 생성합니다.
MaterialPageRoute(builder: (context) => const SelectionScreen()),
);
}
}
3. 두 개의 버튼이 있는 선택 화면 표시
이제 두 개의 버튼이 있는 선택 화면을 만듭니다. 사용자가 버튼을 탭하면 선택 화면이 닫히고 홈 화면에 어떤 버튼이 눌렸는지 반환합니다.
이 단계에서는 UI를 정의합니다. 다음 단계에서는 데이터를 반환하는 코드를 추가합니다.
class SelectionScreen extends StatelessWidget {
const SelectionScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Pick an option'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsets.all(8),
child: ElevatedButton(
onPressed: () {
// "Yep"으로 팝업...
},
child: const Text('Yep!'),
),
),
Padding(
padding: const EdgeInsets.all(8),
child: ElevatedButton(
onPressed: () {
// "Nope"으로 팝업...
},
child: const Text('Nope.'),
),
)
],
),
),
);
}
}
4. 버튼이 눌리면 선택 화면 닫기
이제 두 버튼 모두의 onPressed() 콜백을 업데이트합니다. 첫 번째 화면에 데이터를 반환하려면 선택적 두 번째 인수로 result를 받아들이는 Navigator.pop() 메서드를 사용합니다. 어떤 결과든 SelectionButton의 Future로 반환됩니다.
Yep 버튼
ElevatedButton(
onPressed: () {
// 화면을 닫고 "Yep!"을 결과로 반환합니다.
Navigator.pop(context, 'Yep!');
},
child: const Text('Yep!'),
)
Nope 버튼
ElevatedButton(
onPressed: () {
// 화면을 닫고 "Nope."을 결과로 반환합니다.
Navigator.pop(context, 'Nope.');
},
child: const Text('Nope.'),
)
5. 홈 화면에 선택 사항을 스낵바로 표시하기
이제 선택 화면을 시작하고 결과를 대기하고 있으므로 반환된 정보를 처리해야 합니다.
이 경우, SelectionButton의 _navigateAndDisplaySelection() 메서드를 사용하여 결과를 표시하는 스낵바를 보여줍니다:
// SelectionScreen을 시작하고 Navigator.pop의 결과를
// 대기하는 메서드입니다.
Future<void> _navigateAndDisplaySelection(BuildContext context) async {
// Navigator.push는 SelectionScreen에서 Navigator.pop을 호출한 후에
// 완료되는 Future를 반환합니다.
final result = await Navigator.push(
context,
MaterialPageRoute(builder: (context) => const SelectionScreen()),
);
// StatefulWidget에서 BuildContext를 사용할 때는 비동기로 작동 후에는
// mounted 속성을 확인해서 위젯이 화면에 보이는지 확인해야 한다.
// mounted 속성이 false이면 위젯이 더 이상 화면에 표시되지 않음을 의미한다.
if (!context.mounted) return;
// SelectionScreen이 결과를 반환한 후, 이전 스낵바를 숨기고
// 새로운 결과를 표시합니다.
ScaffoldMessenger.of(context)
..removeCurrentSnackBar()
..showSnackBar(SnackBar(content: Text('$result')));
}
전체 코드
import 'package:flutter/material.dart';
void main() {
runApp(
const MaterialApp(
title: 'Returning Data',
home: HomeScreen(),
),
);
}
class HomeScreen extends StatelessWidget {
const HomeScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Returning Data Demo'),
),
body: const Center(
child: SelectionButton(),
),
);
}
}
class SelectionButton extends StatefulWidget {
const SelectionButton({super.key});
@override
State<SelectionButton> createState() => _SelectionButtonState();
}
class _SelectionButtonState extends State<SelectionButton> {
@override
Widget build(BuildContext context) {
return ElevatedButton(
onPressed: () {
_navigateAndDisplaySelection(context);
},
child: const Text('Pick an option, any option!'),
);
}
// SlectionScreen을 시작하고 Navigator.pop의 결과를 대기하는 메서드입니다.
Future<void> _navigateAndDisplaySelection(BuildContext context) async {
// Navigator.push는 SelectionScreen에서 Navigator.pop을 호출한 후에
// 완료되는 Future를 반환합니다.
final result = await Navigator.push(
context,
MaterialPageRoute(builder: (context) => const SelectionScreen()),
);
// StatefulWidget에서 BuildContext를 사용할 때는 비동기로 작동 후에는
// mounted 속성을 확인해서 위젯이 화면에 보이는지 확인해야 한다.
// mounted 속성이 false이면 위젯이 더 이상 화면에 표시되지 않음을 의미한다.
if (!context.mounted) return;
// SelectionScreen이 결과를 반환한 후, 이전 스낵바를 숨기고
// 새로운 결과를 표시합니다.
ScaffoldMessenger.of(context)
..removeCurrentSnackBar()
..showSnackBar(SnackBar(content: Text('$result')));
}
}
class SelectionScreen extends StatelessWidget {
const SelectionScreen({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Pick an option'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Padding(
padding: const EdgeInsets.all(8),
child: ElevatedButton(
onPressed: () {
// 화면을 닫고 "Yep!"을 결과로 반환합니다.
Navigator.pop(context, 'Yep!');
},
child: const Text('Yep!'),
),
),
Padding(
padding: const EdgeInsets.all(8),
child: ElevatedButton(
onPressed: () {
// 화면을 닫고 "Nope."을 결과로 반환합니다.
Navigator.pop(context, 'Nope.');
},
child: const Text('Nope.'),
),
)
],
),
),
);
}
}
반응형
'Flutter > 네비게이션' 카테고리의 다른 글
플러터] 네비게이션과 라우팅 - 화면에 드로어(drawer) 추가하기 (0) | 2024.06.30 |
---|---|
플러터] 네비게이션과 라우팅 - 새로운 화면에 데이터 보내기 (0) | 2024.06.29 |
플러터] 네비게이션과 라우팅 - 새로운 화면으로 이동하고 돌아오기 (0) | 2024.06.29 |
플러터] 네비게이션과 라우팅 - 탭(Tap) 작업하기 (0) | 2024.06.29 |
플러터] 네비게이션과 라우팅 - 개요 (0) | 2024.06.29 |
댓글
공지사항