플러터/Packages
[Package] go_router를 사용한 화면 이동
sam-ss
2024. 4. 22. 02:35
go_router 란?
애플리케이션 내에서 라우팅 및 탐색을 처리하는 데 사용되는 패키지
기본 셋팅
pubspec.yaml 에 추가
dependencies:
go_router: ^13.2.4
router.dart 추가
// router.dart
final router = GoRouter(
routes: [
GoRoute(path: '/', builder: (context, state) => const MainPage()),
GoRoute(
name: "Home",
path: "/home",
builder: (context, state) {
return const HomePage();
},
)
],
);
main.dart 수정
- MaterialApp.router로 수정
- routerConfig 추가
// main.dart
void main() {
runApp(const _App());
}
class _App extends StatelessWidget {
const _App({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp.router(
routerConfig: router,
);
}
}
화면 이동 방법
이동 함수
- go : 페이지 대체
- push : 페이지 스택에 푸시
- pushReplacement : 페이지 스택의 가장 위에 있는 페이지를 대체
- replace : 페이지 스택의 가장 위에 있는 페이지와 교체, 페이지 키가 재사용되서 상태를 보존하고 페이지 애니메이션을 실행하지 않음
- ..Named : GoRoute 내부에 있는 name을 사용하여 이동
context.go('/home');
context.goNamed('Home')
context.push('/home')
context.pushNamed('Home')
context.replace('/home')
context.replaceNamed('Home')
context.pushReplacement('/home')
context.pushReplacementNamed('Home')
context.go(context.namedLocation('Home'));
사용 예시
// 사용 예시
class HomePage extends StatelessWidget {
const HomePage({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
OutlinedButton(
onPressed: () {
context.push('/first');
},
child: Text("1")),
OutlinedButton(
onPressed: () {
context.push('/second');
},
child: Text("2"))
],
));
}
}
화면 이동 - Path 파라미터
GoRoute(
path: '/home/:id',
builder: (BuildContext context, GoRouterState state) =>
HomePage(id: state.pathParameters['id']!),
),
// 화면 이동
context.go("/home/hi");
화면 이동 - Query 파라미터
GoRoute(
path: '/home',
builder: (context, state) {
return HomePage(id: state.uri.queryParameters['id']!);
},
),
// 화면 이동
context.go('/home?id=hi');
화면 이동 - extra 데이터
객체 데이터를 넘길수도 있다.
GoRoute(
path: "/home",
builder: (context, state) {
final id = (state.extra as Map)['id'] as String;
return HomePage(id: id);
}
),
// 화면 이동
context.push('/home', extra: {
"id": "hi"
});
ShellRoute
다수의 Navigator이동에 사용
화면 구조
-> Scaffold with Bottom Navigation Bar
-> First page
-> Second page
-> Third page
router 선언
final GlobalKey<NavigatorState> rootNavKey = GlobalKey<NavigatorState>();
final GlobalKey<NavigatorState> projectNavKey = GlobalKey<NavigatorState>();
final GoRouter router = GoRouter(
navigatorKey: rootNavKey,
initialLocation: "/",
routes: <RouteBase>[
GoRoute(
path: '/',
builder: (BuildContext context, GoRouterState state) {
return const HomePage();
},
),
ShellRoute(
parentNavigatorKey: rootNavKey,
navigatorKey: projectNavKey,
builder: (context, state, child) => GnbScaffold(state: state, child: child),
routes: [
GoRoute(
path: '/first',
builder: (context, state) {
return const FirstPage();
},
),
GoRoute(
path: '/second',
builder: (context, state) {
return const SecondPage();
},
),
GoRoute(
path: '/third',
builder: (context, state) {
return const ThirdPage();
},
),
],
)
],
);
bottomNavigationBar 가지는 화면
class GnbScaffold extends StatefulWidget {
final GoRouterState state;
final Widget child;
const GnbScaffold(
{required this.state, required this.child, super.key});
@override
State<GnbScaffold> createState() => _GnbScaffoldState();
}
class _GnbScaffoldState extends State<GnbScaffold> {
int currentIndex = 0;
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
body: widget.child,
bottomNavigationBar: BottomNavigationBar(
onTap: changeTab,
currentIndex: currentIndex,
items: const [
BottomNavigationBarItem(icon: Icon(Icons.home), label: 'first'),
BottomNavigationBarItem(icon: Icon(Icons.ac_unit), label: 'second'),
BottomNavigationBarItem(icon: Icon(Icons.access_time_filled), label: 'third'),
],
),
);
}
void changeTab(int index) {
switch(index){
case 0:
context.go('/first');
break;
case 1:
context.go('/second');
break;
default:
context.go('/third');
break;
}
setState(() {
currentIndex = index;
});
}
}
네이게이션 화면으로 이동.
context.push('/first');
위와 같이 사용하면 쉽게 화면 이동이 가능하다.