Flutter에서 네비게이션(Navigation)은 애플리케이션의 여러 화면 간에 이동할 수 있게 하는 중요한 기능입니다. 네비게이션을 통해 사용자는 애플리케이션 내의 다양한 페이지를 탐색하고 상호작용할 수 있습니다. 이번 글에서는 Flutter의 네비게이션 기능과 다양한 사용법에 대해 자세히 살펴보겠습니다.
1. 기본 네비게이션 사용법
Flutter의 기본 네비게이션은 Navigator 위젯을 사용하여 구현됩니다. Navigator.push와 Navigator.pop 메서드를 사용하여 화면을 이동하거나 돌아올 수 있습니다.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: FirstPage(),
);
}
}
class FirstPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('First Page')),
body: Center(
child: ElevatedButton(
child: Text('Go to Second Page'),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SecondPage()),
);
},
),
),
);
}
}
class SecondPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Second Page')),
body: Center(
child: ElevatedButton(
child: Text('Go back'),
onPressed: () {
Navigator.pop(context);
},
),
),
);
}
}
위 코드는 첫 번째 페이지에서 두 번째 페이지로 이동하고, 두 번째 페이지에서 다시 첫 번째 페이지로 돌아오는 간단한 네비게이션 예제입니다.
2. 네임드 라우트(Named Routes) 사용
네임드 라우트를 사용하면 경로 이름을 통해 네비게이션을 관리할 수 있습니다. 이는 네비게이션 구조가 복잡해질 때 유용합니다.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
initialRoute: '/',
routes: {
'/': (context) => FirstPage(),
'/second': (context) => SecondPage(),
},
);
}
}
class FirstPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('First Page')),
body: Center(
child: ElevatedButton(
child: Text('Go to Second Page'),
onPressed: () {
Navigator.pushNamed(context, '/second');
},
),
),
);
}
}
class SecondPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Second Page')),
body: Center(
child: ElevatedButton(
child: Text('Go back'),
onPressed: () {
Navigator.pop(context);
},
),
),
);
}
}
위 코드는 네임드 라우트를 사용하여 첫 번째 페이지에서 두 번째 페이지로 이동하는 예제입니다. MaterialApp의 routes 속성을 사용하여 경로와 해당 페이지를 정의합니다.
3. 데이터 전달
네비게이션 시에 데이터를 전달해야 하는 경우가 자주 발생합니다. Navigator.push 메서드의 두 번째 인자인 MaterialPageRoute의 settings 속성을 사용하여 데이터를 전달할 수 있습니다.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: FirstPage(),
);
}
}
class FirstPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('First Page')),
body: Center(
child: ElevatedButton(
child: Text('Go to Second Page'),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => SecondPage(data: 'Hello from First Page!'),
),
);
},
),
),
);
}
}
class SecondPage extends StatelessWidget {
final String data;
SecondPage({Key? key, required this.data}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Second Page')),
body: Center(
child: Text(data),
),
);
}
}
위 코드는 첫 번째 페이지에서 두 번째 페이지로 데이터를 전달하는 예제입니다. SecondPage 생성자에 데이터를 전달하고, 전달된 데이터를 화면에 표시합니다.
4. 비동기 네비게이션
네비게이션은 비동기적으로 처리될 수 있으며, Navigator.push 메서드의 반환 값을 사용하여 결과를 받을 수 있습니다.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: FirstPage(),
);
}
}
class FirstPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('First Page')),
body: Center(
child: ElevatedButton(
child: Text('Go to Second Page'),
onPressed: () async {
final result = await Navigator.push(
context,
MaterialPageRoute(builder: (context) => SecondPage()),
);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text('Result: $result')),
);
},
),
),
);
}
}
class SecondPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Second Page')),
body: Center(
child: ElevatedButton(
child: Text('Go back with result'),
onPressed: () {
Navigator.pop(context, 'Hello from Second Page!');
},
),
),
);
}
}
위 코드는 두 번째 페이지에서 결과를 반환하고, 첫 번째 페이지에서 그 결과를 받아 스낵바로 표시하는 예제입니다. Navigator.push는 비동기적으로 실행되며, await 키워드를 사용하여 결과를 받을 수 있습니다.
5. 네비게이션을 위한 라우트 보호 (Guarding Routes)
특정 조건을 만족할 때만 접근할 수 있는 페이지를 보호하기 위해, onGenerateRoute 콜백을 사용할 수 있습니다.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
final bool isLoggedIn = false;
@override
Widget build(BuildContext context) {
return MaterialApp(
home: FirstPage(),
onGenerateRoute: (settings) {
if (settings.name == '/protected') {
if (!isLoggedIn) {
return MaterialPageRoute(builder: (context) => LoginPage());
}
return MaterialPageRoute(builder: (context) => ProtectedPage());
}
return null;
},
);
}
}
class FirstPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('First Page')),
body: Center(
child: ElevatedButton(
child: Text('Go to Protected Page'),
onPressed: () {
Navigator.pushNamed(context, '/protected');
},
),
),
);
}
}
class LoginPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Login Page')),
body: Center(child: Text('Please log in')),
);
}
}
class ProtectedPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Protected Page')),
body: Center(child: Text('Welcome to the protected page')),
);
}
}
위 코드는 사용자가 로그인이 필요하지 않은 경우 로그인 페이지로 리디렉션하는 예제입니다. onGenerateRoute 콜백을 사용하여 라우트를 보호할 수 있습니다.
결론
Flutter의 네비게이션 시스템은 애플리케이션의 여러 화면 간에 쉽게 이동할 수 있는 다양한 방법을 제공합니다. 기본 네비게이션, 네임드 라우트, 데이터 전달, 비동기 네비게이션, 그리고 라우트 보호 등 다양한 기능을 활용하여 사용자 경험을 향상시킬 수 있습니다. Flutter의 네비게이션 기능을 통해 직관적이고 효율적인 사용자 인터페이스를 설계해보세요.
'Flutter' 카테고리의 다른 글
Flutter의 Bottom Navigation 사용법 (2) | 2024.07.20 |
---|---|
Flutter의 Drawer 사용법 (0) | 2024.07.19 |
Flutter의 탭바(Tabs) 사용법 (0) | 2024.07.19 |
Flutter의 스낵바(Snackbar) 사용법 (0) | 2024.07.18 |
Flutter의 다이얼로그(Dialog) 사용법 (0) | 2024.07.18 |