728x90
페이지 이동
학습 목표
- Flutter의 기본 내비게이션(Navigator) 개념 이해
- 화면 간 이동(push, pop) 구현
- MaterialPageRoute와 Named Route 설정 방법 학습
- 간단한 데이터 전달(Arguments) 준비
1. 프로젝트 준비
- Flutter 프로젝트 생성
- pubspec.yaml에 특별한 패키지 추가는 필요 없고, 기본 material 위젯 사용
2. 화면 구성
기본 화면(메인) 일기 작성 화면 상세 화면(DetailPage)
🛠 예제 코드
1. MaterialApp 설정
import 'package:flutter/material.dart';
void main() => runApp(const DiaryApp());
class DiaryApp extends StatelessWidget {
const DiaryApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Diary App',
// Named Routes 등록
routes: {
'/': (context) => const HomePage(),
'/write': (context) => const WritePage(),
'/detail': (context) => const DetailPage(),
},
initialRoute: '/',
);
}
}
2. HomePage – 메인 화면
// 기본 화면(메인) 구성
class HomePage extends StatelessWidget {
const HomePage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('메인 화면')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {
Navigator.pushNamed(context, '/write');
},
child: const Text('✍️ 일기 작성 화면으로 이동'),
),
ElevatedButton(
onPressed: () {
Navigator.pushNamed(
context,
'/detail',
arguments: '2025년 5월 14일의 일기',
);
},
child: const Text('📖 상세 화면으로 이동'),
),
],
),
),
);
}
}
3. WritePage – 작성 화면
// 일기 작성 화면 - 일기 작성
class WritePage extends StatelessWidget {
const WritePage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('일기 작성')),
body: Center(
child: ElevatedButton(
onPressed: () {
Navigator.pop(context); // 작성 완료 후 돌아가기
},
child: const Text('✅ 작성 완료'),
),
),
);
}
}
4. DetailPage – 전달 받은 데이터를 보여주는 화면
// 상세 화면 - 일기 상세 보기
class DetailPage extends StatelessWidget {
const DetailPage({super.key});
@override
Widget build(BuildContext context) {
// arguments 받기
final itemTitle = ModalRoute.of(context)!.settings.arguments as String?;
return Scaffold(
appBar: AppBar(title: const Text('상세 화면')),
body: Center(
child: Text(
itemTitle != null ? '$itemTitle 상세 보기' : '상세 정보를 불러올 수 없음',
style: const TextStyle(fontSize: 18),
),
),
);
}
}
home_page.dart 전체 코드
더보기
import 'package:flutter/material.dart';
void main() => runApp(const DiaryApp());
class DiaryApp extends StatelessWidget {
const DiaryApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Diary App',
// Named Routes 등록
routes: {
'/': (context) => const HomePage(),
'/write': (context) => const WritePage(),
'/detail': (context) => const DetailPage(),
},
initialRoute: '/',
);
}
}
// 기본 화면(메인) 구성
class HomePage extends StatelessWidget {
const HomePage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('메인 화면')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
ElevatedButton(
onPressed: () {
Navigator.pushNamed(context, '/write');
},
child: const Text('✍️ 일기 작성 화면으로 이동'),
),
ElevatedButton(
onPressed: () {
Navigator.pushNamed(
context,
'/detail',
arguments: '2025년 5월 14일의 일기',
);
},
child: const Text('📖 상세 화면으로 이동'),
),
],
),
),
);
}
}
// 일기 작성 화면 - 일기 작성
class WritePage extends StatelessWidget {
const WritePage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('일기 작성')),
body: Center(
child: ElevatedButton(
onPressed: () {
Navigator.pop(context); // 작성 완료 후 돌아가기
},
child: const Text('✅ 작성 완료'),
),
),
);
}
}
// 상세 화면 - 일기 상세 보기
class DetailPage extends StatelessWidget {
const DetailPage({super.key});
@override
Widget build(BuildContext context) {
// arguments 받기
final itemTitle = ModalRoute.of(context)!.settings.arguments as String?;
return Scaffold(
appBar: AppBar(title: const Text('상세 화면')),
body: Center(
child: Text(
itemTitle != null ? '$itemTitle 상세 보기' : '상세 정보를 불러올 수 없음',
style: const TextStyle(fontSize: 18),
),
),
);
}
}
3.🧭 Named Route와 Arguments
📌 Named Route란?
Flutter 앱은 여러 화면(Route)으로 구성돼요.
각 화면을 MaterialApp의 routes 속성에 등록해두면, 경로 이름만으로 간편하게 화면 전환을 할 수 있습니다.
✅ 기본 구조
MaterialApp(
initialRoute: '/',
routes: {
'/': (context) => const HomePage(),
'/write': (context) => const WritePage(),
'/detail': (context) => const DetailPage(),
},
);
✅ 화면 이동
Navigator.pushNamed(context, '/write');
📦 화면 간 데이터 전달 (Arguments)
📨 전달
화면 이동 시 데이터를 함께 보내고 싶다면 arguments를 활용하세요:
Navigator.pushNamed(
context,
'/detail',
arguments: '전달할 텍스트 또는 데이터',
);
📬 수신
받는 쪽에서는 다음과 같이 데이터를 꺼낼 수 있어요:
final data = ModalRoute.of(context)!.settings.arguments as String;
@override
Widget build(BuildContext context) {
final data = ModalRoute.of(context)!.settings.arguments as String;
return Scaffold(
appBar: AppBar(title: const Text('상세 화면')),
body: Center(child: Text('전달 받은 값: $data')),
);
}
🧭 요약 표
항목 | 사용 방법 |
📘 Named Route 등록 | MaterialApp(routes: {...}) |
📤 데이터 전달 | Navigator.pushNamed(context, '/route', arguments: data) |
📥 데이터 수신 | ModalRoute.of(context)!.settings.arguments |
✏️ 실습 과제
🛠 메인 화면 (HomePage)
- "일기 작성" 버튼 → /write로 이동
Navigator.pushNamed(context, '/write');
🛠 일기 작성 화면 (WritePage)
- "작성 완료" 버튼 → pop()으로 홈으로 복귀
Navigator.pop(context); // 데이터 전달은 아직 없음
🛠 상세 화면 (DetailPage)
- 목록 클릭 시 /detail로 이동하며 arguments 전달
Navigator.pushNamed(
context,
'/detail',
arguments: '예시 제목',
);
- 전달 받은 데이터를 활용해 화면 구성
- 추가로 “삭제”, “수정” 버튼을 아래처럼 배치
body: Padding(
padding: const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Text('$itemTitle 상세 보기'),
ElevatedButton(
onPressed: () {
Navigator.pop(context, {'action': 'delete', 'item': itemTitle});
},
child: const Text('삭제'),
),
ElevatedButton(
onPressed: () {
Navigator.pop(context, {'action': 'edit', 'item': itemTitle});
},
child: const Text('수정'),
),
],
),
),
4. 🔁 관련된 기능 소개
▶️ pushReplacement
기존 화면을 대체하고 새 화면으로 이동할 때 사용
Navigator.pushReplacementNamed(context, '/write');
▶️ arguments에 Map 전달
데이터를 좀 더 유연하게 전달할 수 있어요
Navigator.pushNamed(
context,
'/detail',
arguments: {
'title': 'Flutter 일기',
'id': 42,
},
);
5. 🌱 더 추가하고 싶은 기능 : 작성 데이터 전달 & 리스트 갱신
- WritePage에 TextField 추가
- TextEditingController 사용
- 작성 완료 시 pop(context, controller.text)
- HomePage에서 then()으로 결과 받기
- 리스트에 추가하고 setState 호출
Navigator.push<String>(
context,
MaterialPageRoute(builder: (_) => const WritePage()),
).then((result) {
if (result != null && result.isNotEmpty) {
setState(() {
entries.add(result);
});
}
});
기능 | 설명 |
🧠 Map으로 복합 데이터 전달 | {title: ..., id: ...} 형태 |
🔁 pushReplacementNamed | 기존 화면 스택을 덮는 방식 |
🔄 pop(context, result) | 결과 반환으로 리스트 갱신 |
🗃️ sqflite 연동 | 데이터 영구 저장 |
📝 수정 기능 | 텍스트 초기값 지정해 TextField에 주입 |
'Flutter + Dart > Flutter + Dart 공부' 카테고리의 다른 글
스크롤과 페이지 네비게이션 가이드 (1) | 2025.05.14 |
---|---|
리스트뷰 및 그리드뷰 학습, 상태 관리 소개 (StatefulWidget) (0) | 2025.05.14 |
비동기 및 특수 위젯 (1) | 2025.05.14 |
기본 위젯 학습 및 사용자 입력 처리 기초 (0) | 2025.05.13 |
위젯과 기본적인 레이아웃 (0) | 2025.05.12 |