ํ๋ฉด ์ด๋์ ์ํ ๋ฐฉ๋ฒ ์ ๋ฆฌ (Router)
์ด๋ฒ ๊ธ์์๋ Flutter์์ ๋ผ์ฐํ ์ ๊ด๋ฆฌํด์ฃผ๋ ํจํค์ง์ธ go_router์ ๋ํด์ ์ดํด๋ณด๋ ค๊ณ ํ๋ค.
Flutter ์์ ํ๋ฉด ์ ํ์ ์ฒ๋ฆฌํ ๋์ ๊ธฐ๋ณธ์ ์ผ๋ก ์ ๊ณตํ๋ Navigator๊ฐ ์๋ค. Navigator๋ ์ฌ์ฉ ๋ฐฉ๋ฒ๋ ๋ณต์กํ๊ณ , ์ฌํํ ๋ผ์ฐํ ์ฒด๊ณ์ ์ฌ์ฉํ๊ธฐ์๋ ๋ถํธํ ์ ์ด ๋ค์ ์๋ค.
์ ๋ ์ฃผ๋ก Get Router๋ฅผ ์ฌ์ฉํด ์๋๋ฐ, ์ฒ์์๋ context ์์ด ์ฒ๋ฆฌ๊ฐ ๊ฐ๋ฅํ๋ค๋ ๋ถ๋ถ ๋๋ฌธ์ ์ฅ์ ์ด๋ผ ์๊ฐํ์ง๋ง, Get ํจํค์ง ์์ฒด๊ฐ ๊ท๋ชจ๊ฐ ํฐ ํจํค์ง์ ์ํ๋ ํธ์ด๋ฉด์, ๋ผ์ฐํฐ ๋ง์ ์ํด Get์ ๋ฑ๋กํ๋ค๋ ๊ฒ์ด ๋ถ๋ด์ด ๋๊ธฐ ์์ํ๊ณ , ๊ฐ์ธ์ ์ผ๋ก Get ํจํค์ง์ ๋ํด์๋ ๊ธ์ ์ ์ด์ง ์์ ํธ์ด๋ผ ์๋ก์ด ๋ผ์ฐํฐ๋ฅผ ์ฐพ๊ฒ ๋์๋ค.
๋ผ์ฐํฐ๋ฅผ ์ ๊ณตํ๋ ํจํค์ง๋ ์ด๋ฏธ ๋ค์์ ํจํค์ง๊ฐ ์์๋๋ฐ, ์ฌ๋ฌ ๋ผ์ฐํฐ๋ค์ ์ฌ์ฉํด ๋ณด๋ค๊ฐ ๊ฐ์ธ์ ์ผ๋ก go_router์ ์ฒ๋ฆฌ ๋ฐฉ์์ด ๋ง์์ ๋ค์๊ณ , ๊ธฐ์กด ํ๋ก์ ํธ๋ค์ ๋ฆฌํํ๊ธฐ์๋ ๋ถ๋ด์ด ์์ด go_router๋ฅผ ์์ฃผ ์ฌ์ฉํ๊ณ ์๋ ํธ์ด๋ค.
๋ผ์ฐํฐ๋ฅผ ์ ํํ๋ ๊ฒ์ ํ๋ก์ ํธ์ ํน์ฑ๋ง๋ค ๋ค๋ฅด๊ณ , ๊ฐ์ธ์ ๊ฐ๋ฐ ์คํ์ผ์ด๋ ๋ผ์ฐํ ์ฒ๋ฆฌ ๋ฐฉ์์ ๋ํ ๊ฒฌํด๊ฐ ๋ค๋ฅด๊ธฐ์ go_router๋ ์ด๋ ๊ฒ ์ฌ์ฉํ๋ ๊ตฌ๋ ์ ๋๋ก๋ง ๋ด์ฃผ์๋ฉด ๋ ๊ฒ ๊ฐ๋ค.
๋ณธ๊ฒฉ์ ์ผ๋ก go_router์ ๋ํด์ ์ดํด๋ณด๋๋ก ํ์.
go_router ํจํค์ง๋ฅผ ์ถ๊ฐํด์ฃผ์. ์์ฑ ์์ ๊ธฐ์ค ์ต์ ๋ฒ์ ์ธ 13.1.0 ๋ฒ์ ์ ์ฌ์ฉํ๋ค.
flutter pub add go_router
dependencies:
go_router: ^13.1.0
๋จผ์ Router ์ฌ์ฉ์ ์ํด MaterialApp์ MaterialApp.router๋ก ๋ณ๊ฒฝ์ ํด์ฃผ๋๋ก ํ์.
๋ผ์ฐํฐ๋ฅผ ๋ฑ๋กํ๊ณ ์ฌ์ฉํ๊ธฐ ์ํด .router ๋ฉ์๋๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ด๋ค.
build(BuildContext context) {
return MaterialApp.router();
}
Widget
MaterialApp.router๋ ๊ธฐ์กด๊ณผ ๋์ผํ MaterialApp๋ค์ ์ฌ์ฉํ ์ ์๋ค. ์ฐจ์ด์ ์ด ์๋ค๋ฉด MaterialApp์ ๊ฐํธํ๊ฒ home์ ์ง์ ํ์ฌ ํ์ ์์ ฏ์ ์์์ ์ผ๋ก ์ง์ ํ ์ ์๋ ๋ฐ๋ฉด .router์๋ home ์ต์ ํ๋ผ๋ฏธํฐ๊ฐ ์๋ค.
ํ์๋ก routerConfig๋ฅผ ๋ฑ๋กํ์ฌ ์ฌ์ฉํด์ผ ํ๋ค.
MaterialApp.router(
routerConfig : null
);
RouterConfig๋ฅผ ์์ฑํด ์ค ๊ฒ์ธ๋ฐ, ํด๋น ํด๋์ค๋ ํธ์ถ๋ ์ผ์ด ์์ด์ ํด๋์ค ๋ช ์ ์์ ๋กญ๊ฒ ์์ฑํ์ ๋ ๋๋ค.
static ๋ฉ์๋๋ฅผ ์ฌ์ฉํ ์ ์ญ ๋ฉ์๋๋ก ๋ง๋ค์ด ์ฃผ์.
import 'package:go_router/go_router.dart';
class CustomRouter {
static GoRouter router = GoRouter(routes: routes);
}
GoRouter ๊ฐ์ฒด๋ ํ์ ๊ฐ์ผ๋ก routes ๊ฐ์ ์ ๋ฌํ๋ผ๊ณ ํ๋ค.
routes๋ RouteBase ํ์ ์ ๋ฐฐ์ด๋ก ์ ๋ฌ ๋ฐ๊ณ ์๋ค. HomePage๋ผ๋ ๊ธฐ๋ณธ ํ์ด์ง๋ฅผ ์์ฑํด ์ฃผ๊ณ , Router์ ๋ฑ๋ก์ ํด์ฃผ์.
RouteBase ํ์ ์ GoRoute๋ฅผ ๋ฃ์ด์ฃผ๋ฉด ๋๋๋ฐ, ํ์ ๊ฐ์ผ๋ก path๋ฅผ ์ง์ ํ๋๋ก ๋์ด์๋ค.
ํ์ง๋ง, path๋ง ๋ฑ๋กํด์๋ ์ฌ์ฉ์ด ๋์ง ์๊ณ , ์๋ฌ๊ฐ ๋ฐ์ํ ๊ฒ์ด๋ค. ๊ทธ ์ด์ ๋ ๋น์ฐํ๊ฒ๋ ์์ ฏ์ ๋ํ ์ ์๋ฅผ ํด์ฃผ์ง ์์๊ธฐ ๋๋ฌธ์ด๋ค.
์ํ๋ ๋ผ์ฐํฐ์ ํ์ด์ง๋ฅผ ๋ฑ๋กํด ์ฃผ๋ ๋ฐฉ๋ฒ์ด builder, pageBuilder ์ด๋ ๊ฒ ์๋๋ฐ, ์ด ๋์ ์ฐจ์ด๋ ์๋์์ ์ถ๊ฐ์ ์ผ๋ก ์ค๋ช ํ ์์ ์ด๊ณ , ์ฐ์ ์ builder๋ฅผ ์ฌ์ฉํด์ ์ฝ๋๋ฅผ ์ถ๊ฐํด ์ฃผ๋๋ก ํ๊ฒ ๋ค.
routes: [
GoRoute(
path: "/",
builder: (_, __) => const HomePage(),
),
],
์ด์ MaterialApp์ผ๋ก ๋์์์ ์์ฑํ RouterConfig๋ ๋ฑ๋กํด ์ฃผ๊ณ ๋น๋๋ฅผ ํด๋ณด์. ์ ์์ ์ผ๋ก HomePage๋ก ์ด๋๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.
return MaterialApp.router(
routerConfig: CustomRouter.router,
);
์ผ๋ฐ์ ์ผ๋ก Navigator๋ฅผ ์ฌ์ฉํ ๋์๋ home์ ์ง์ ํด์ฃผ๊ฑฐ๋ initialRoute ๋ฅผ ์ง์ ํ๋๋ก ๋์ด์๋๋ฐ, ์๋ฌด ๊ฒ๋ ์ง์ ํ์ง ์์ ์ํ์์ GoRouter๋ ๊ธฐ๋ณธ ํ์ด์ง๋ก HomePage๋ฅผ ์ฌ์ฉํ๊ณ ์์๊น ?
์ด ๋ถ๋ถ์ ๋ํด์ ์์๋ณด๋ ค๋ฉด GoRouter์ ์ด๊ธฐํ ๋ผ์ฐํฐ๋ฅผ ์ค์ ํ๋ ๋ถ๋ถ์ ์ค๋ช ์ ๋ด์ผํ๋ค.
GoRouter์๋ ์ต์ ํ๋ผ๋ฏธํฐ๋ก initialLocation์ ์ ์ํ ์ ์๊ฒ ๋์ด ์๋๋ฐ, ํ๋ผ๋ฏธํฐ์ ๋ํ ์ค๋ช ์ ์ดํด๋ณด๋ฉด ๊ธฐ๋ณธ ๋ก์ผ์ด์ ์ด NULL์ผ ๊ฒฝ์ฐ ๊ธฐ๋ณธ ๋ก์ผ์ด์ ์ ๋ฑ๋ก๋ routes์ "/" path๋ฅผ ์ฌ์ฉํ๋ค๊ณ ๋์ด์๋ค.
๊ทธ๋ ๋ค๋ฉด HomePage์ path๋ฅผ "/home" ์ผ๋ก ๋ณ๊ฒฝํ๊ณ ๋ค์ ์คํ์ ํด๋ณด์.
ํ์ด์ง๋ฅผ ์ฐพ์ง ๋ชปํ๋ค๋ ์๋ฌ ํ์ด์ง๊ฐ ๋ ธ์ถ์ด ๋์๋ค.
์์์ ํ ์คํธ ํด๋ณธ ๊ฒ ์ฒ๋ผ initialLocation์ผ๋ก "/" path๋ฅผ ์ฌ์ฉํ ๊ฒ์ด๋ผ๋ฉด, ์ง์ ํด ์ฃผ์ง ์์๋ ๋๊ธด ํ์ง๋ง "/home" path ์ฒ๋ผ ์ํ๋ path ๊ฒฝ๋ก๋ฅผ ๋ฃ์ด์ฃผ๊ณ ์ถ๋ค๋ฉด, ๊ฐ์ ์ง์ ํด ์ฃผ๋ฉด ๋๋ค.
static GoRouter router = GoRouter(
initialLocation: "/home",
routes: [
...
],
);
GoRoute์ ๋ํด์ ๊ธฐ๋ณธ์ ์ธ ์ฌํญ์ ์ถ๊ฐ์ ์ผ๋ก ์ดํด๋ณด๋๋ก ํ์.
์ด๋ฒ์๋ ์๋ก์ด ํ์ด์ง๋ฅผ ์ถ๊ฐํด์ฃผ๋๋ก ํ๊ฒ ๋ค. FirstPage๋ฅผ ์์ฑํด ์ฃผ๊ณ , path๋ "/first" ๋ผ๊ณ ํด์ฃผ์๋ค.
GoRoute(
path: "/first",
builder: (_, __) => const FirstPage(),
),
์ด์ HomePage์ ๊ฐ๋จํ ๋ฒํผ์ ๋ง๋ค์ด์ FirstPage๋ก ๋ผ์ฐํ ์ ํด์ฃผ๋๋ก ํ์.
go_router์์ ๋ผ์ฐํ ์ ํ๋ ๋ฐฉ๋ฒ์ Navigator๋ ํ ํจํค์ง ์ฒ๋ผ ๋ค์ํ ๋ฐฉ์์ ์ ๊ณตํ๊ณ ์๋๋ฐ, ์ด ๋ถ๋ถ์ ์๋์์ ์์ธํ ๋ค๋ฃฐ ์์ ์ด๋ ์ฐ์ ๊ธฐ๋ณธ ๋ฐฉ์์ผ๋ก ๋ผ์ฐํ ์ ์งํํด ๋ณด์.
context๋ฅผ ์ฌ์ฉํด go๋ฅผ ํธ์ถํด์ฃผ๋ฉด ๋๋๋ฐ, ์ด ๋์ ๋ฑ๋กํ path๋ฅผ ๋ฃ์ด์ฃผ๋ฉด ๋๋ค. ๋ผ์ฐํ ์ด ์ ์์ ์ผ๋ก ์ฒ๋ฆฌ๋๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.
context.go("/first");
์ด๋ฒ์๋ named๋ก ๋ผ์ฐํ ์ ํ๋ ๋ค๋ฅธ ๋ฐฉ์์ผ๋ก๋ ๋ผ์ฐํ ์ ํด์ฃผ๋๋ก ํ์. ๋ณด๊ธฐ์๋ context.go์ ์ฐจ์ด๊ฐ ์์ด ๋ณด์ด์ง๋ง ์ด๋ค ์ฐจ์ด์ ์ด ์๋์ง ํ ์คํธ๋ฅผ ํด๋ณด์.
context.goNamed("/first");
ํด๋น ๋ฐฉ์์ผ๋ก๋ ๋ผ์ฐํ ์ฒ๋ฆฌ์ ์คํจํ๊ณ ์๋์ ๊ฐ์ ์๋ฌ๊ฐ ๋ฐ์ํ์๋ค.
ํด๋น ์๋ฌ๋ route name์ผ๋ก "/first"๊ฐ ๋ฑ๋ก๋์ง ์์๋ค๋ ๊ฒ์ด๋ค. name์ ๋ฑ๋กํด์ฃผ๋๋ก ํ์.
GoRoute(
path: "/first",
name: "first",
builder: (_, __) => const FirstPage(),
์ด๋ฒ์๋ ์ ์์ ์ผ๋ก ๋ผ์ฐํ ์ ์ฑ๊ณตํ์๋ค.
GoRouter.of(context).goNamed("first");
์ด์ฒ๋ผ path๋ฅผ ์ฌ์ฉํ์ฌ ๋ผ์ฐํ ์ ์ฒ๋ฆฌํ ์๋ ์๊ณ , name์ ์ง์ ํ์ฌ ์ฌ์ฉํ ์๋ ์๋ค.
path, name ์ด๋ค ๊ฑธ ์ฌ์ฉํด์ผ ํ๋ ๊ฑธ๊น ? ์๋์์ ์์ธํ ๋ด์ฉ์ ์ดํด๋ณด๋ฉด ์ฝ๊ฒ ์ดํด๊ฐ ๋ ๊ฒ์ธ๋ค. path์๋ ํ๋ผ๋ฏธํฐ๋ฅผ ์ถ๊ฐํด์ ๋์ ์ธ ๊ฐ์ ๋ฐ์์ฌ ์ ์๋ ๋ฐ๋ฉด, name์ ํ๋ผ๋ฏธํฐ๋ฅผ ์ถ๊ฐ๋ก ๊ฒฝ๋ก์ ๋ฃ์ ์ ์๋ค.
์ธ์คํ ์ฑ์ ๊ฐ๋ฐํด์ ํผ๋๋ฅผ ๊ณต์ ํ ์ ์๋ค๊ณ ํด๋ณด์.
์ด๋์ ๊ณต์ ๋๋ ํผ๋์ path๋ฅผ "/feed/{feedNo}" ์ด๋ ๊ฒ ์์ฑํ๋ค๊ณ ํ๋ฉด feedNo์๋ ๋์ ์ธ ๊ฐ๋ค์ด ์ ๋ฌ๋ ์ ์๋ ๋ฐ๋ฉด, name์ path ์ฒ๋ผ ์์ฑํ ์๊ฐ ์๋ค.
name์ ๋ช ๋ช ๋ ์ฒด๊ณ๋ฅผ ์ฌ์ฉํ๊ฒ ๋๋๋ฐ, ํ์ฌ ํ์ด์ง๊ฐ ์ด๋ค ํ์ด์ง์ธ์ง ๋ผ์ฐํฐ๋ฅผ ํ์ธํ๊ณ ์ถ์ ๋, path๋ง ์ฌ์ฉํ๊ฒ ๋๋ฉด ๋ผ์ฐํฐ๋ฅผ ํ์ธํ๊ธฐ ์ํด path ๊ฐ์ contains๋ฅผ ์ฌ์ฉํด ๊ฒฝ๋ก๋ฅผ ํ์ธํ๊ฑฐ๋, ๋ฌด์ธ๊ฐ ๋ค๋ฅธ ๋ฐฉ๋ฒ์ ์ฌ์ฉํด์ ๋ผ์ฐํฐ๋ฅผ ํ์ธํด์ผ ํ ๊ฒ์ด๋ค. ๋ฐ๋ฉด name์ "feed" ๋ผ๊ณ ์ง์ ํ๊ฒ ๋๋ฉด ๋น๊ต๋ฅผ ์ฝ๊ฒ ํ ์ ์๊ฒ ๋๋ค.
๋ ์์ธํ ๋ด์ฉ์ ๊ณ์ํด์ ์ฌ์ฉํด ๋ณด๋ฉด์ ์ถ๊ฐ์ ์ธ ์ค๋ช ์ ํ๋๋ก ํ๊ฒ ๋ค.
์ถ๊ฐ๋ก GoRouter.of(context)๋ฅผ ์ฌ์ฉํด์ ๋ผ์ฐํ ์ ํ ์๋ ์๋ค.
GoRouter.of(context).go(location);
GoRoute์์ ํ์ด์ง๋ฅผ ์ ์ํ ๋์ ์ฌ์ฉํ๋ ๋ฐฉ์์ธ builder์ pageBuilder์ ๋ํด์ ๋น๊ตํด ๋ณด๋ฉด์ ์์๋ณด๋๋ก ํ์.
builder, pageBuilder๋ ๋ชจ๋ ๋์ผํ๊ฒ ๋ผ์ฐํ ์ ์ง์ ํ ๋์ ์ฌ์ฉํ๋ ๊ธฐ๋ฅ์ด๋ค.
builder
builder๋ ๊ฐ๋จํ๊ฒ ํ์ด์ง๋ฅผ ์ ๋ฌํด์ฃผ๋ฉด ๋๋ค. ์ฌํํ๊ฒ Router๋ฅผ ์ง์ ํ ์ ์์ง๋ง, ๋ผ์ฐํ ์ ๋ํ Transition์ ์ฒ๋ฆฌํ ์ ์๋ค.
ํ๋ผ๋ฏธํฐ๋ก BuildContext, GoRouterState๋ฅผ ์ฌ์ฉํ ์ ์๋๋ฐ, GoRouterState์ ๋ํด์๋ ์๋์์ ํด๋น ๊ธฐ๋ฅ์ ๋ํด์ ์ดํด๋ณผ ๋์ ์์ธํ ๋ค๋ฃจ๋๋ก ํ๊ฒ ๋ค.
์ด๋ฏธ Flutter๋ฅผ ์ฌ์ฉํด์ ์ฑ์ ๊ฐ๋ฐ ํ์
จ๊ฑฐ๋, ๋ค์ดํฐ๋ธ๋ก ์ฑ ๊ฐ๋ฐ์ ์งํํด ๋ณด์ ๋ถ๋ค์ ํ์ด์ง๊ฐ ๋ผ์ฐํ
๋ ๋์ ํ์ด์ง๊ฐ ์คํ๋๋ ๋ฐฉ์์ ๋ณ๊ฒฝํ ์ ์๋ค๋ ๊ฒ์ ์ด๋ฏธ ์๊ณ ์์ ๊ฒ์ด๋ค.
์ด๋ฌํ ๊ธฐ๋ฅ์ Flutter์์๋ PageTransition์ผ๋ก ์ฒ๋ฆฌํ ์ ์๋๋ฐ, builder๋ฅผ ์ฌ์ฉํ๋ค๋ฉด ๋ณ๋๋ก ์ง์ ํ ์ ์๊ณ , ํ๋ซํผ์ ๋ง๊ฒ ๋์ํ๊ฒ ๋๋ค.
GoRoute(
path: "/first",
builder: (BuildContext context, GoRouterState state) => const FirstPage(),
),
pageBuilder
pageBuilder๋ builder ์ฒ๋ผ ๋จ์ํ ์์ ฏ์ ์ ๋ฌํ๋ ๊ฒ์ด ์๋ MaterialPage ๋๋ CupertinoPage๋ฅผ ์ ๋ฌํด์ ์ฌ์ฉํ ์ ์๋๋ฐ, ์ด ๋์ PageTransition์ ๋ง๋ค์ด ์ค ์ ์๋ค.
GoRoute(
path: "/first",
pageBuilder: (BuildContext context, GoRouterState state) =>
const MaterialPage(child: FirstPage()),
),
Transition
Transition์ ์์์ ์ค๋ช ํ ๊ฒ์ฒ๋ผ ํ์ด์ง๊ฐ ์๋ํ๋ ์ ๋๋ฉ์ด์ ์ด๋ผ ์ดํดํ๋ฉด ์ฝ๋ค.
Android, iOS ํ๋ซํผ์ ๋ณ๋์ ๋์์ธ UI ์์คํ
์ด ์๋ค.
๊ฐ๊ฐ Material Design, Cupertino Design ์ด๋ผ๊ณ ํ๋ค.
๋์์ธ UI ์์คํ ์ ๋ฐ๋ผ ๋ฒํผ, ์ฑ๋ฐ, ๋ค์ด์ผ๋ก๊ทธ ๋ฑ์ ๋์์ธ์ด ๊ฐ๊ฐ ๋ค๋ฅด๊ฒ ์๋ํ๋ ๊ฒ์ ์ ์ ์๋๋ฐ, ํ์ด์ง์ ์ ๋๋ฉ์ด์ ๋ ๋ค๋ฅด๋ค.
Material ๋์์ธ์ ํ์ด์ง๋ฅผ ๋ผ์ฐํ
ํ ๋์ ์์ ํ๋ฉด์ด ์ปค์ง๋ฉด์ ์ ์ฒด ํ๋ฉด์ผ๋ก ๋ผ์ฐํ
๋๋ ์ ๋๋ฉ์ด์
์ ์ฌ์ฉํ๊ณ , iOS๋ ์ค๋์ ๋ถํฐ ์ฐ์ธก์์ ์ข์ธก์ผ๋ก ์ด๋ํ๋ ์ ๋๋ฉ์ด์
์ ์ฌ์ฉํ๊ณ ์๋ค.
Android๋ ๊ณผ๊ฑฐ์ ์๋์์ ์๋ก ์ฌ๋ผ์ค๋ ์ ๋๋ฉ์ด์
์ ์ฌ์ฉํ ์ ๋ ์๋ค.
iOS | Android |
---|---|
Flutter๋ ๋๋ถ๋ถ์ ํ๋ก์ ํธ๋ฅผ MaterialApp์ผ๋ก ๋น๋๋ฅผ ํ๋๊ฒ ์ผ๋ฐ์ ์ธ๋ฐ, Material์ ์ฌ์ฉ ํ๋๋ผ๋ ๋ณ๋๋ก ์ง์ ํ์ง ์์ผ๋ฉด PageTransition์ ๊ฐ ํ๋ซํผ์ ๊ธฐ๋ณธ Transition์ ์ ์ฉํ๊ณ ์๋ค.
ํ๋ซํผ Transition์ ๊ทธ๋ฅ ์ฌ์ฉํ๊ฒ ๋๋ค๋ฉด, ์์์ ์ดํด๋ณธ builder๋ฅผ ์ฌ์ฉํด์ ์ฌํํ๊ฒ ๋ผ์ฐํ
์ ์ ์ธํด์ฃผ๋ฉด ๋์ง๋ง ์ํ๋ Transition์ ๋ง๋ค๊ณ ์ถ๋ค๋ฉด
pageBuilder๋ฅผ ์ฌ์ฉํ๋ฉด ๋๋ค.
PageTransition์๋ ์ด๋ค ์๋ ๋ฐฉ์๋ค์ด ์๋์ง ์ดํด๋ณด์.
NoTransition
SlideTransition
FadeTransition
ScaleTransition
No | Slide |
---|---|
Fade | Scale |
---|---|
PageTransition์ ์ปค์คํ ํ๊ฒ ๋ง๋ค์ด ์ฃผ๋ ๋ฐฉ์์ ์์ 4๊ฐ์ง ๋ฐฉ๋ฒ์ผ๋ก ์ ๋๋ฉ์ด์ ์ ๋ง๋ค์ด ์ค ์ ์๋ค.
NoTransitionPage
NoTransition์ ์ ๋๋ฉ์ด์ ์ฒ๋ฆฌ๋ฅผ ํ์ง ์๋ ๋ฐฉ๋ฒ์ด๋ค. Page๊ฐ ๋ผ์ฐํ ๋ ๋์ ์ ๋๋ฉ์ด์ ์ฒ๋ฆฌ๋ฅผ ํ์ง ์๊ณ ์ถ์ ๊ฒฝ์ฐ๊ฐ ์๋ค. ๋ก๊ทธ์ธ ํ์ด์ง๋ก ๋ผ์ฐํ ์ ํ๊ฑฐ๋ BottomNavigationBar๋ฅผ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ์ ํด๋น Transition์ ์ฌ์ฉํ ์ ์๋ค.
GoRoute(
path: "/no",
pageBuilder: (BuildContext context, GoRouterState state) =>
const NoTransitionPage(child: NoPage()),
),
CustomTransitionPage
Fade, Scale, Slide์ ๊ฐ์ Transition์ ๋ง๋ค๊ณ ์ถ์ ๋, CustomTransition์ ์ฌ์ฉํด์ ๋ง๋ค์ด ์ค ์ ์๋ค.
CustomTranstionPage๋ฅผ ์ฌ์ฉํ๋ฉด, transitionsBuilder๋ฅผ ์์ฑํ ์ ์๋๋ฐ, ์ฌ๊ธฐ์์ Transtion์ ์ฌ์ฉํ ์ ๋๋ฉ์ด์ ์ฒ๋ฆฌ๋ฅผ ์ปค์คํ ํ๊ฒ ๊ตฌ์ฑํด์ฃผ๋ฉด ๋๋ค.
FadeTransition
GoRoute(
path: "/fade",
pageBuilder: (BuildContext context, GoRouterState state) => CustomTransitionPage(
child: const FadePage(),
transitionsBuilder: (
BuildContext context,
Animation<double> animation,
Animation<double> secondaryAnimation,
Widget child,
) => FadeTransition(
opacity: animation,
child: child,
),
),
),
ScaleTransition
GoRoute(
path: "/scale",
pageBuilder: (BuildContext context, GoRouterState state) =>
CustomTransitionPage(
child: const ScalePage(),
transitionsBuilder: (
BuildContext context,
Animation<double> animation,
Animation<double> secondaryAnimation,
Widget child,
) => ScaleTransition(
scale: animation,
child: child,
),
),
),
SlideTranstion
GoRoute(
path: "/slide",
pageBuilder: (BuildContext context, GoRouterState state) =>
CustomTransitionPage(
child: const SlidePage(),
transitionsBuilder: (
BuildContext context,
Animation<double> animation,
Animation<double> secondaryAnimation,
Widget child,
) => SlideTransition(
position: animation.drive(
Tween<Offset>(
begin: const Offset(1.25, 0),
end: Offset.zero,
).chain(CurveTween(curve: Curves.easeIn)),
),
child: child,
)),
),
CustomTransitionPage๋ก ์ํ๋ Transition์ ๋ง๋ค ์ ์์ง๋ง, Transtion์ ์ฌ์ฉํ๊ฒ ๋๋ฉด iOS์์ ๋ค๋ก๊ฐ๊ธฐ์ ์ฌ์ฉํ๋ Gesture๋ ๋นํ์ฑํ ์ฒ๋ฆฌ๋๋ ์ด ๋ถ๋ถ์ ๊ณ ๋ คํด์ ์ฌ์ฉํ๋ฉด ๋๋ค.
builder, pageBuilder ํจ๊ป ์ฌ์ฉ์
๋ง์ฝ์ builder์ pageBuilder๋ฅผ ๋ชจ๋ ์ฌ์ฉํ๊ฒ ๋๋ฉด ์ด๋ป๊ฒ ๋ ๊น ?
builder, pageBuilder๋ฅผ ์ฌ์ฉํ์ง ์์ผ๋ฉด, ์๋ฌ๊ฐ ๋ฐ์ํ์ง๋ง ๋ ๋ค ์ฌ์ฉํ๋ ๊ฒฝ์ฐ์๋ ์๋ฌ๊ฐ ๋ฐ์ํ์ง๋ ์๊ณ , pageBuilder๋ฅผ ์ฐ์ ์ผ๋ก ์ฒ๋ฆฌํ๊ฒ ๋๋ค.
Go
๋ผ์ฐํ ์ ํ๋ ๋ช ๋ น์ด์ ๋ํด์๋ ์์ง ์์ธํ ๋ค๋ฃจ์ง ์์์๋ค.
๊ฐ์ฅ ๊ธฐ๋ณธ์ ์ผ๋ก ๋ผ์ฐํ ์ ํ๋ ๋ฐฉ๋ฒ์ด go, push ์ด๋ ๊ฒ ์๋๋ฐ, ๊ธฐ๋ฅ๋ค์ ์ฐจ์ด์ ์ ์๊ณ ์์ด์ผ ํ๋ค.
go, push ๋ชจ๋ ํ์ด์ง๋ฅผ ์๋ก ์คํํ๋ ๊ฐ๋ ์ ๋์ผํ๋ฐ, ๋ผ์ฐํ ์คํ์๋ ์์ ํ ๋ค๋ฅธ ์ฐจ์ด๋ฅผ ๋ณด์ธ๋ค.
๋จผ์ go ๋ฐฉ์์ ๋ํด์ ์ดํด๋ณด์. ๊ฐ๋จํ๊ฒ go๋ฅผ ์ฌ์ฉํ๋ฉด ๋๊ณ , ํ์ ๊ฐ์ผ๋ก location, ์ฆ path๋ฅผ ๋ฃ์ด์ฃผ๋ฉด ๋๋ค.
context.go("/first");
์ด๋ฒคํธ๋ฅผ ํธ์ถํ๋ฉด ์๋ก์ด ํ์ด์ง๊ฐ ์คํ๋๊ณ , ํ์ด์ง๋ฅผ ๋ซ์๋ณด๋๋ก ํ์.
์ด๋ค์ผ์ด ์ผ์ด๋ ๊น ? ๋ซํ์ง ์์ ๊ฒ์ด๋ค. context.pop()์ ์ฌ์ฉํ๋ฉด ์๋ฌ๊ฐ ๋ฐ์ํ๋ค.
์๋ก ์คํํ ํ์ด์ง๋ฅผ ์ ๋ซ์ ์ ์์๊น ? ์ด์ ๋ ๋ฐ๋ก, ๋ ์ด์ ๋ซ์ ํ์ด์ง๊ฐ ์๊ธฐ ๋๋ฌธ์ด๋ค.
go ๋ผ์ฐํ ๋ฐฉ์์ ํ์ด์ง๋ฅผ ์๋ก์ด ํ์ด์ง๋ก ๋์ฒดํ์ฌ ๋ผ์ฐํ ์ ์ฒ๋ฆฌํ๋ ๊ฐ๋ ์ด๋ค.
์๋ฅผ ๋ค์ด, ๊ธฐ๋ณธ ๊ฒฝ๋ก๋ฅผ ์์์ผ๋ก, ์ฒซ ๋ฒ์งธ ํ์ด์ง๋ฅผ ์ด์ด์ฃผ๊ณ , go๋ฅผ ์ฌ์ฉํด ๋ ๋ฒ์งธ ํ์ด์ง๋ฅผ ์คํํ๋ค๊ณ ํด๋ณด์.
์ด๋ ๊ฒ ๋๋ฉด ๋ผ์ฐํฐ ์คํ์๋ ์์ฐจ์ ์ผ๋ก "/", "/first", "/second" ์ด๋ ๊ฒ ์คํ์ด ์ฒ๋ฆฌ ๋์ด์ผ ํ๋๋ฐ, go๋ก "/second"๋ฅผ ์คํํ๋ ์๊ฐ "/", "first" ์คํ์ ๋์ฒดํ๊ณ "/second" ์คํ๋ง ๋จ๊ธฐ๊ฒ ๋๋ค.
๋ผ์ฐํฐ ์คํ์ ์์ธ ๋ชจ๋ ์คํ์ ์ ๊ฑฐํ๊ณ ์๋ก์ด ํ์ด์ง๋ฅผ ์คํํ ๋์ ์ฌ์ฉํ๋ ๊ธฐ๋ฅ์ด ๋ฐ๋ก go ์ด๋ค.
์ด ๊ธฐ๋ฅ์ ํ ์คํธํ๋ ๊ฐ์ฅ ์ฌ์ด ๋ฐฉ๋ฒ์ go๋ก ์คํํ๊ธฐ ์ ๋ผ์ฐํธ ์คํ์ dispose ๊ธฐ๋ฅ์ ์ฌ์ฉํ์ฌ ์ด๋ฒคํธ๊ฐ ์๋ํ๋์ง๋ฅผ ์ถ๋ ฅํด ๋ณด๋ฉด์ ํ์ธํ๋ ๊ฒ์ด๋ค.
void dispose() {
super.dispose();
print("FirstPage Dispose");
}
Push
์ด๋ฒ์๋ push์ ๋ํด์ ์ดํด๋ณด์.
push ์ฐ๋ฆฌ๊ฐ ์ผ๋ฐ์ ์ผ๋ก ์ฌ์ฉํ๋ ๋ผ์ฐํฐ์คํ์ ๋ผ์ฐํฐ๋ฅผ ์ถ๊ฐํ๋ฉด์ ์ด๋ํ๋ ๋ฐฉ์์ด๋ค.
context.push("/first);
์๋ ๊ธฐ๋ฅ๊ณผ ๋์ผํ ๊ธฐ๋ฅ์ด๋ค.
Navigator.of(context).push(route);
goNamed
์์์ ์ดํด๋ณธ go๋ location์ผ๋ก ์ค์ ํ path ๊ฐ์ ๋ฃ์ด์ผ ํ์ง๋ง, named๋ฅผ ์ฌ์ฉํ๊ณ ์ถ๋ค๋ฉด goNamed๋ฅผ ์ฌ์ฉํ๋ฉด ๋๋ค.
context.go("first");
pushNamed
์ด๋ฒ์ push์ named ๋ฐฉ๋ฒ์ด๋ค.
context.pushNamed("first");
pushReplacement
์ด๋ฒ์ Replacement๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ ์ดํด๋ณด์. ์ฐ์ ๋ชจ๋ ๋ผ์ฐํธ ์คํ์ ๋์ฒดํ๋ go๋ ๋น์ฐํ Replacement ๊ฐ๋ ์ด ์๊ณ , push์๋ง ํด๋น ๊ธฐ๋ฅ์ด ์๋ค.
Replacement๋ ๋์ฒดํ์ฌ ์ด๋ํ๋ ๊ฐ๋ ์ธ๋ฐ, ์ผํ๋ณด๋ฉด go์ ๋์ผํด ๋ณด์ด์ง๋ง Replacement๋ ํ์ฌ ๋ผ์ฐํธ์คํ๋ง ์๋ก์ด ๋ผ์ฐํฐ๋ก ๋์ฒดํ๋ ๊ธฐ๋ฅ์ด๋ค.
context.pushReplacement("/second");
Push | PushReplacement |
---|---|
pushReplacementNamed
pushReplacement์ named ๋ฐฉ์์ด๋ค.
context.pushReplacementNamed("/second");
์ด๋ฒ์๋ go_router ํจํค์ง์ ํธํ ๋๋ฒ๊น ๊ธฐ๋ฅ์ธ Observer์ ๋ํด์ ์ดํด๋ณด์.
Bloc ํจํด์ ์ฌ์ฉํด ๋ณด์ ๋ถ๋ค์ Bloc์ด ๊ฐ์ง๋ ObserverPattern์ ๋ํด์ ์ข์ ๊ธฐ๋ฅ์ด๋ผ๋ ๊ฒ์ ์๊ณ ์์ ๊ฒ์ด๋ค.
go_router์์๋ ๋์ผํ Observer๋ฅผ ์์ ํ ์ ์๋๋ก ํด์ค๋ค.
๋จผ์ Observer๋ฅผ ๊ตฌ์ฑํด ์ฃผ๋๋ก ํ์.
NavigatorObserver๋ฅผ ์์๋ฐ์ ์ฌ์ฉํ ์ ์๊ณ , didPush, didPop, didRemove, didReplace๋ฅผ ์ฌ์ ์ ํ์ฌ ์ํ๋ ์ด๋ฒคํธ๋ฅผ ๋ฃ์ ์๋ ์๊ณ ๋๋ฒ๊น ๋ก๊ทธ๋ฅผ ์ถ๋ ฅํด ๋ณผ ์๋ ์๋ค.
class RouterObserver extends NavigatorObserver {
void didPush(Route<dynamic> route, Route<dynamic>? previousRoute) {
print("DidPush: $route");
}
void didPop(Route<dynamic> route, Route<dynamic>? previousRoute) {
print("DidPop: $route");
}
void didRemove(Route<dynamic> route, Route<dynamic>? previousRoute) {
print("DidRemove: $route");
}
void didReplace({Route<dynamic>? newRoute, Route<dynamic>? oldRoute}) {
print("DidReplace: $newRoute");
}
}
RouterObserver ๊ฐ์ฒด๋ฅผ GoRouter์ observers ํ๋ผ๋ฏธํฐ์ ์ถ๊ฐํด์ฃผ๋ฉด ๋๋ค.
observers ํ๋ผ๋ฏธํฐ๋ ๋ฐฐ์ด๋ก ๋ฐ์ ์ ์์ด ์ฌ๋ฌ ๊ฐ์ NavigatorObserver๋ฅผ ๊ตฌ์ฑํ ์๋ ์๋ค.
static GoRouter router = GoRouter(
initialLocation: "/",
observers: [RouterObserver()],
routes: [
...
],
);
์ด์ Observer๋ฅผ ์ถ๊ฐํ์์ผ๋, ์์์ ์ดํด๋ณธ go ๊ธฐ๋ฅ๊ณผ push ๊ธฐ๋ฅ์ ์ฐจ์ด๋ฅผ ๋ ์ฝ๊ฒ ๋ก๊ทธ๋ก ์ถ๋ ฅํด ๋ณผ ์ ์์ ๊ฒ์ด๋ค.
์ด์ด์ ๋ผ์ฐํฐ ๊ธฐ๋ฅ์ ์ค์ํ ๊ธฐ๋ฅ์ธ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ๋ ๋ฐฉ๋ฒ์ ๋ํด์ ์ดํด๋ณด๋๋ก ํ๊ฒ ๋ค.
Flutter๋ ์์ ฏ๊ฐ Constructor๋ผ๋ ์์ฑ์๋ฅผ ํตํด ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ ์ ์๊ณ , ๋น์ฐํ go_router์์๋ ๋ฐ์ดํฐ ์ ๋ฌ์ด ๊ฐ๋ฅํ๋ค.
Person์ด๋ผ๋ ํ์ด์ง๋ก name, age, email์ ๋๊ฒจ์ฃผ๋๋ก ํ์.
๋จผ์ Person ํ์ด์ง๋ฅผ ์์ฑํ๊ณ ์์ฑ์๋ฅผ ์ถ๊ฐํด ์ฃผ๋๋ก ํ์.
class PersonPage extends StatelessWidget {
final String name;
final int age;
final String email;
const PersonPage({
super.key,
required this.name,
required this.age,
required this.email,
});
...
}
์ด์ GoRoute๋ฅผ ์ ์ํด์ฃผ๋ฉด ๋๋๋ฐ, go_router ํจํค์ง๋ ๋ฐ์ดํฐ๋ฅผ GoRouterState ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํด ์ ๋ฌ ๋ฐ์ ์ ์๋ค.
GoRouteState ๊ฐ์ฒด์ extra๋ Object? ํ์ ์ ์ ๋ฌ ๋ฐ์ ์ฌ์ฉํ๊ธฐ์ ์๋์ ๊ฐ์ด ํ๋ผ๋ฏธํฐ๋ฅผ ์ ๋ฌํ์ฌ ๋ผ์ฐํธ๋ฅผ ์ ์ํด์ฃผ๋ฉด ๋๋ค.
GoRoute(
path: "/person",
name: "person",
builder: (BuildContext context, GoRouterState state) {
return PersonPage(
name: (state.extra as Map<String, dynamic>)["name"],
age: (state.extra as Map<String, dynamic>)["age"],
email: (state.extra as Map<String, dynamic>)["email"],
);
}
),
์ด์ ๋ผ์ฐํฐ๋ฅผ ํธ์ถํ ๋์ extra์ ๋ฐ์ดํฐ๋ฅผ ๋ฃ์ด์ฃผ๋ฉด ๋๋ค. ๊ฐ๋จํ๊ฒ ๋ฐ์ดํฐ๋ฅผ ๋๊ธฐ๋ ๋ฐฉ๋ฒ์ ๋ํด์ ์ดํด๋ดค๋ค.
context.push("/person",
extra: {
"name": name,
"age": age,
"email": email,
});
Map ํ์ ์ด ์๋ Object๋ฅผ ์ฌ์ฉํ๋๊ฒ ์ผ๋ฐ์ ์ด๊ธฐ ๋๋ฌธ์, Person ๊ฐ์ฒด๋ฅผ ์์ฑํด ์ฃผ๋๋ก ํ๊ฒ ๋ค.
class Person {
final String name;
final int age;
final String email;
const Person({
required this.name,
required this.age,
required this.email,
});
}
extra๋ฅผ Person ๊ฐ์ฒด๋ก ํ์ ์บ์คํธํด์ ์ฌ์ฉํ ์ ์๋ค.
GoRoute(
path: "/person",
name: "person",
builder: (BuildContext context, GoRouterState state) {
return PersonPage(
person: state.extra as Person,
);
}
),
์ด๋ฒ์ path์ ํ๋ผ๋ฏธํฐ๋ฅผ ์ถ๊ฐํ์ฌ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํด ์ฃผ๋๋ก ํ์.
path์ ํ๋ผ๋ฏธํฐ๋ฅผ ์ถ๊ฐํ๋ ์ด์ ๋ ๋์ ์ธ ๋ฐ์ดํฐ๋ฅผ ๊ฒฝ๋ก๋ก ์ฌ์ฉํ๊ณ ์ถ์ ๊ฒฝ์ฐ์ ์ฃผ๋ก ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ด๋ค.
๋ง์ฝ์ SNS ์๋น์ค๋ฅผ ๊ฐ๋ฐํ๋ค๊ณ ๊ฐ์ ํ์.
์ฌ์ฉ์๊ฐ ์์ฑํ ํผ๋๋ฅผ ํ์ด์ง์ ์ ๊ทผํ ๋์ ํด๋น ํผ๋์ ๊ณ ์ ํ ํผ๋ ๋ฒํธ๋ฅผ ์๊ณ ์์ด์ผ ๋ฐ์ดํฐ ์กฐํ๊ฐ ๊ฐ๋ฅํ ๊ฒ์ด๋ค. ํผ๋ ๋ฒํธ๋ฅผ path ๊ฒฝ๋ก์ ์ถ๊ฐํ์ฌ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌ ๋ฐ๊ณ ์ถ์ ๋์ ์ฌ์ฉ๋๋ฉฐ, ์น์์ ์ฌ์ฉํ๋ ๋ฐฉ์๊ณผ ๋์ผํ๋ค๊ณ ์๊ฐํ๋ฉด ๋๋ค.
FeedPage๋ฅผ ์์ฑํ๊ณ ํด๋น ํผ๋์ ๋ฒํธ๋ง ๋ฐ์์ฌ ์ ์๋๋ก ๋ผ์ฐํฐ๋ฅผ ์ ์ํด ์ฃผ๋๋ก ํ๊ฒ ๋ค.
path๋ฅผ ์์ฑ์ /:feedNo๋ผ๊ณ ํด์ค๋ค๋ฉด / ๋ค์์ ์ค๋ ๊ฐ์ GoRouterState์ pathParameters ์ ๋ณด์ ๋ด๊ฒจ์ ธ ์ ๊ณต๋๋ค.
ํด๋น ๊ฒฝ๋ก์ ์ค๋ ๊ฐ์ ์ ์ํด์ค feedNo๋ก ์ป์ ์ ์๊ฒ ๋๋ค.
GoRoute(
path: "/feed/:feedNo",
builder: (BuildContext context, GoRouterState state) =>
FeedPage(feedNo: int.parse(state.pathParameters["feedNo"]!),
),
),
๋น์ฐํ ์ฌ๋ฌ ๊ฐ์ ๊ฒฝ๋ก๋ฅผ ์ถ๊ฐํ ์ ์๋ค. ์ด๋ฒ์ ์ฌ์ฉ์์ ๊ณ ์ ID ๊ฐ๋ ๋ฐ์์ฌ ์ ์๊ฒ ํด๋ณด์.
์ด๋ฐ ๋ฐฉ๋ฒ์ผ๋ก ์ํ๋ path ๊ฒฝ๋ก์์ ๋์ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌ ๋ฐ์ ์ ์๊ฒ ๋๋ค.
GoRoute(
path: "/feed/:feedNo/:uid",
builder: (BuildContext context, GoRouterState state) =>
FeedPage(
feedNo: int.parse(state.pathParameters["feedNo"]!
uid: state.pathParameters["uid"]!,
),
),
),
์์ฑํ path ๊ฒฝ๋ก์ ๋ฐ์ดํฐ๊ฐ ์ ๋ฌ ๋์ง ์๋ ๊ฒฝ์ฐ์๋ ์๋ฌ๊ฐ ๋ฐ์ํ๊ฒ ๋๋, ๋ฐ๋์ ํ์๋ก ๋ฃ์ด์ฃผ์ด์ผ ํ๋ค.
์ด๋ฒ์๋ Query Parameter์ ๋ํด์ ์ดํด๋ณด์.
์์์ ์ดํด๋ณธ Path Parameter๋ ๋ฐ๋์ ํ์์ ์ผ๋ก path์ ๊ฐ์ ๋ฃ์ด์ฃผ์ด์ผ ํ๋ ๋ฐ๋ฉด, Query Parameter๋ก ์ ์๋ ๊ฐ์ ์ต์ ๋ํ๊ฒ ์ฒ๋ฆฌํ ์ ์๋ค.
๊ฒ์ ํ์ด์ง๋ฅผ ์์ฑํ๊ณ Optional Parameter๋ก keyword๋ฅผ ๋ฐ์์ฌ ์ ์๋๋ก ํด๋ณด์.
keyword๋ Nullable ํ์ ์ผ๋ก ์ ๋ฌ ๋ฐ์ผ๋ฉด ๋๊ณ , GoRouterState์ uri ์ ๋ณด์ ๋ด๊ธด queryParameters๋ฅผ ์ฌ์ฉํด keyword๋ฅผ ๊ฐ์ ธ์ฌ ์ ์๋ค.
GoRoute(
name: "search",
path: "/search",
builder: (BuildContext context, GoRouterState state) => SearchPage(
keyword: state.uri.queryParameters["keyword"],
)
),
Query Parameter๋ฅผ ๋ผ์ฐํ ํ๋ ๋ฐฉ๋ฒ์ ์ฌ๋ฌ๊ฐ์ง ๋ฐฉ๋ฒ์ด ์๋ค. ๋จผ์ named๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ด๋ค.
pushNamed ๋๋ goNamed์๋ ํ๋ผ๋ฏธํฐ๋ก queryParameters๋ฅผ ์ ๊ณตํ๋๋ฐ, ์ฌ๊ธฐ์ keyword๋ฅผ ์ ๋ฌํด ์ฃผ๋ฉด ๋๋ค.
context.pushNamed("search", queryParameters: {
"keyword": "๊ฒ์์ด",
});
์ด๋ฒ์๋ named๊ฐ ์๋ path๋ฅผ ๊ทธ๋๋ก ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ด๋ค. path ๊ฒฝ๋ก์ ์ต์ ๋ ํ๋ผ๋ฏธํฐ๋ฅผ ์ถ๊ฐํ๋ ๋ฐฉ๋ฒ์ธ ? annotation์ ์ฌ์ฉํด ์ฃผ๋ฉด ๋๋ค.
context.push("/search?keyword=๊ฒ์์ด");
์๋ก์ด ํ์ด์ง๋ฅผ ๋ผ์ฐํ ํ ๋์ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ๋ ๋ฐฉ๋ฒ์ ๋ํด์ ์ดํด๋ดค์ผ๋, ์ด๋ฒ์ ๋ฐ๋๋ก ํ์ด์ง๋ฅผ ๋ซ์ ๋ ๋ถ๋ชจ ์์ ฏ์ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌํ๋ ๋ฐฉ๋ฒ์ ๋ํด์ ์ดํด๋ณด์.
pop() ์ด๋ฒคํธ์ ๊ฒฐ๊ณผ ๊ฐ์ ์ ๋ฌํ๋ ๋ฐฉ๋ฒ์ ์ด๋ฏธ ๊ธฐ์กด ๋ผ์ฐํ ๋ฐฉ์์๋ ๊ฐ๋ฅํ ๊ธฐ๋ฅ๋ค์ด๋ค. go_router์์ ์ด๋ป๊ฒ ์ฒ๋ฆฌํ๋์ง ์์๋ณด๋๋ก ํ๊ฒ ๋ค.
pop() ์ด๋ฒคํธ ์์ ์ ๋ฌํ๊ณ ์ถ์ ๋ฐ์ดํฐ๋ฅผ ๋ฃ์ด์ฃผ๋ฉด ๋๋ค.
context.pop(true);
๋ผ์ฐํ ์ด๋ฒคํธ๋ฅผ ์คํํ๋ ๋ถ๋ถ์์ ์ฝ๋ฐฑ์ ๋ํด ์์ ์ ํ๋ฉด ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌ ๋ฐ์ ์ ์๋ค.
context.push("/test").then((value) {
print(value);
});
// flutter: true
Map ํ์ ์ ์ ๋ฌํ ์๋ ์๋ค.
context.pop({
"name": "Tyger",
"age": 100,
"email": "boglbbogl@gmail.com",
});
context.push("/test").then((value) {
print(value);
});
// flutter: {name: Tyger, age: 100, email: boglbbogl@gmail.com}
Object๋ฅผ ์์ฑํด์ ์ฌ์ฉํด ๋ณด๋๋ก ํ์.
class Person {
final String name;
final int age;
final String email;
final DateTime birthday;
const Person({
required this.name,
required this.age,
required this.email,
required this.birthday,
});
}
๊ฐ์ฒด๋ฅผ ์ ๋ฌํ ์ ์๋ค.
Person person = Person(
name: "Tyger",
age: 100,
email: "boglbbogl@gmail.com",
birthday: DateTime(2000, 01, 01),
);
context.pop(person);
context.push("/test").then((value) {
print(value);
});
// flutter: Person(name: Tyger, age: 100, email: boglbbogl@gmail.com, birthday: 2000-01-01 00:00:00.000)
๋ณ์, Map, Object ์ธ์๋ ๋ฐฐ์ด์ ์ฝ๋ฐฑ์ผ๋ก ์ ๋ฌํ ์๋ ์๋ค. ์ถ๊ฐ๋ก pushReplacement๋ ๋ผ์ฐํ ์ ์์ฒญํ ํ์ด์ง์ ์คํ์ด ์ฌ๋ผ์ ธ์ ๋ฐ์ดํฐ๋ฅผ ์ ๋ฌ ๋ฐ์ ์ ์์ผ๋, ์ฝ๋ฐฑ์ ๋ํ ๋ผ์ฐํธ ์คํ์ ์ ๊ณ ๋ คํด์ ์ค๊ฒ๋ฅผ ํด์ผ ํ๋ค.
์ด๋ฒ์๋ Redirect ๋ผ์ฐํ ์ ๋ํด์ ์ดํด๋ณด๋๋ก ํ์.
GoRouter๋ ๋ฑ๋ก๋ ๋ผ์ฐํฐ๋ฅผ ๋์์ํฌ ๋์ ์ํ๋ ์กฐ๊ฑด์ ๋ฐ๋ผ ๋ฆฌ๋ค์ด๋ ํธ๋ฅผ ์ค์ ํ ์ ์๋๋ก ๋์ด์๋ค.
Redirect ๊ธฐ๋ฅ์ ์ฌ์ฉํ์ง ์๊ณ ๋ ์ด๋ฌํ ๊ธฐ๋ฅ์ ์ถฉ๋ถํ ๊ฐ๋ฐํ ์ ์์ง๋ง, Redirect๋ฅผ ์ฌ์ฉํด ๋ณด๋ฉด, ๋ผ์ฐํฐ ๋ฑ๋ก ๋ฐ ์ ์ง ๊ด๋ฆฌ๋ฅผ ์ข ๋ ์์ํ๊ฒ ํ ์ ์๊ฒ ๋๋ค.
Redirect ์ฌ์ฉ ๋ฐฉ๋ฒ์ ๊ฐ๋จํ๋ค. Redirectํ๊ณ ์ถ์ path๋ฅผ ๋ฑ๋กํด ์ฃผ๊ธฐ๋ง ํ๋ฉด ๋๋ค.
FirstPage, RedirectPage๋ฅผ ๋ผ์ฐํฐ์ ๋ฑ๋กํ๋๋ก ํ์.
GoRoute(
path: "/first",
builder: (BuildContext context, GoRouterState state) => const FirstPage(),
),
GoRoute(
path: "/redirect",
builder: (BuildContext context, GoRouterState state) => const RedirctPage(),
),
FirstPage ๋ผ์ฐํฐ์ redirect ํ๋ผ๋ฏธํฐ๋ฅผ ์ฌ์ฉํด ๋ณด๋๋ก ํ์.
๊ฐ๋จํ๊ฒ path๋ง ๋ฑ๋กํด์ฃผ๋ฉด ๋๋ค.
GoRoute(
path: "/first",
builder: (BuildContext context, GoRouterState state) => const FirstPage(),
redirect: (BuildContext context, GoRouterState state) {
return "/redirect";
},
),
์ด์ push๋ฅผ ํด์ฃผ๊ฒ ๋๋ฉด, FirstPage๋ก ๋ผ์ฐํ ์ด ๋์ง ์๊ณ , Redirect ํ์ด์ง๋ก ๋ผ์ฐํ ์ด ๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.
context.push("/first");
redirect ํ๋ผ๋ฏธํฐ๋ก ๋ฑ๋ก๋ ๊ฒฝ๋ก๋ฅผ ๋ผ์ฐํ ํ๊ฒ ๋๋ค.
์ด๋ฒ์๋ ์กฐ๊ฑด์ ์ถ๊ฐํ์ฌ Redirect ๋ผ์ฐํ ์ ์งํํด ๋ณด๋๋ก ํ์.
์์ ๋ฐ์์์ ๋ด์ด๋ฉด SpringPage()๋ก Redirect ํ๊ณ , ์ฌ๋ฆ์ด๋ฉด SummerPage()๋ก, ๊ทธ ์ธ์ ๊ฒฝ์ฐ๋ Redirect๋ฅผ ํ์ง ์๋๋ก ํด๋ณด์.
MontlyPage ๋ผ์ฐํฐ๋ฅผ ๋ฑ๋กํด ์ฃผ๊ณ , path๋ก ํ์ฌ ํฐ์น๋ ์์ ๋ฐ์์ค๋๋ก ํ์.
GoRoute(
path: "/montly/:month",
builder: (BuildContext context, GoRouterState state) => MontlyPage(
title: state.pathParameters["month"]!,
),
),
Spring, Summer ํ์ด์ง์ ๋ํ ๋ผ์ฐํฐ๋ ๋ฑ๋กํด ๋์.
GoRoute(
path: "/summer/:content",
builder: (BuildContext context, GoRouterState state) => SummerPage(
content: state.pathParameters["content"]!,
)),
GoRoute(
path: "/spring/:content",
builder: (BuildContext context, GoRouterState state) => SpringPage(
content: state.pathParameters["content"]!,
)),
redirect ์กฐ๊ฑด์ MontlyPage์ ์ถ๊ฐํด์ฃผ์.
redirect: (BuildContext context, GoRouterState state) {
switch (state.pathParameters["month"]!) {
case "Mar" || "Apr" || "May":
return "/spring/${state.pathParameters["month"]}";
case "Jun" || "Jul" || "Aug":
return "/summer/${state.pathParameters["month"]}";
default:
return null;
}
},
Redirect | Redirect X |
---|---|
๋ค์ค ๋ผ์ฐํ ์ ๋ํด์ ์ดํด๋ณด์.
๋ค์ค ๋ผ์ฐํ ์ ํ๋์ ํ์ด์ง๋ฅผ ๋ผ์ฐํ ํ๋ ๊ฒ์ด ์๋, ์๋ธ ์คํ์ ์ถ๊ฐํ์ฌ ์ง์ ํ ํ์ด์ง๋ค์ ๋ผ์ฐํ ํ ์ ์๋ ๊ธฐ๋ฅ์ด๋ค.
๋ง์ฝ์ FirstPage(), SecondPage() ์ด๋ ๊ฒ ๋ ๊ฐ์ ํ์ด์ง๋ฅผ ์์ฐจ์ ์ผ๋ก ์คํํ๋ฉด์ ์ด๋ํ๊ณ ์ถ๋ค๊ณ ๊ฐ์ ํด ๋ณด์.
๋ค์ค ๋ผ์ฐํ ์ ์ง์ํ์ง ์๋ ๊ฒฝ์ฐ๋ผ๋ฉด ์๋ ์ฒ๋ผ ์ฐ์์ผ๋ก ๋ผ์ฐํ ์ ์งํํ ๊ฒ์ด๋ค.
context.push("/first");
context.push("/second");
go_router๋ ๋ค์ค ๋ผ์ฐํ ์ ์ง์ํ๊ธฐ ๋๋ฌธ์, ์ฝ๋๋ฅผ ์ฐ์์ ์ผ๋ก ์์ฑํ ํ์ ์์ด path์ ๊ฒฝ๋ก๋ฅผ ์ถ๊ฐํ์ฌ ํ์ด์ง๋ค์ ๋ผ์ฐํ ํ ์ ์๊ฒ ๋๋ค.
๋จผ์ FirstPage()์ ๋ํ ๋ผ์ฐํธ๋ฅผ ๋ฑ๋กํด์ฃผ์.
GoRoute(
path: "/first",
builder: (BuildContext context, GoRouterState state) =>
const FirstPage(),
),
SecondPage()์ ๋ํ ๋ผ์ฐํธ๋ฅผ ์์ฑํ ๊ฒ์ธ๋ฐ, ์ด ๋์ SecondPage() ํธ์ถ์ FirstPage()๋ฅผ ์คํํ๊ณ SecondPage()๋ฅผ ์ด์ด์ค ์ ์๋๋ก ํ ๊ฒ์ด๋ค.
GoRoute์๋ routes๋ฅผ ๋ฐฐ์ด๋ก subRoutes๋ฅผ ๋ฑ๋กํ ์ ์๋ค.
๋ค์ค ํ์ด์ง๋ฅผ ๋ผ์ฐํ ํ๋ ๊ฒ์ push๋ก๋ ์งํํ ์ ์์ผ๋ฉฐ, go๋ฅผ ์ฌ์ฉํ์ฌ์ผ ํ๋ค.
์์์ go์ ๋ํด์ ์์๋ดค์ ๋์, go๋ ํ์ด์ง๋ฅผ ๋์ฒดํ๊ณ ์ด๋ํ๋ค๊ณ ํ์๋ค.
๋ง์ผ FirstPage()๋ฅผ GoRoute๋ก ๋ฑ๋กํ๊ณ subRoute๋ก SecondPage()๋ฅผ ๋ฑ๋กํ๊ฒ ๋๋ฉด, ์ฑ์ ์ต์์ ๋ผ์ฐํธ๊ฐ FirstPage()๋ก ๋์ฒด๋๊ธฐ ๋๋ฌธ์, ๋ค์ ํ์ผ๋ก ๋์์ค๊ธธ ์ํ๋ค๋ฉด, initialRoute์ subRoute๋ก ๋ฑ๋กํด์ผ ํ๋ค.
GoRoute(
path: "/",
builder: (BuildContext context, GoRouterState state) => const HomePage(),
routes: [
GoRoute(
path: "first",
builder: (BuildContext context, GoRouterState state) =>
const FirstPage(),
routes: [
GoRoute(
path: "second",
builder: (BuildContext context, GoRouterState state) =>
const SecondPage()),
],
),
],
),
subRoute๋ฅผ ๋ฑ๋ก ํ์์ผ๋, ์ด์ ์ด๋ฒคํธ๋ฅผ ๋ฐ์์์ผ ๋ผ์ฐํ ์ ์ฒ๋ฆฌํด ์ฃผ๋๋ก ํ์.
๋จผ์ , subRoute๋ก ๋ฑ๋กํ FirstPage(), SecondPage()๋ฅผ ์คํํ๊ณ ๊ฐ๊ณ ์ถ๋ค๋ฉด go๋ฅผ ์ฌ์ฉํด path๋ฅผ ๋ฃ์ด์ฃผ๋ฉด ๋๋ค.
๋ผ์ฐํ ๋ ํ์ด์ง๋ฅผ ๋ณด๋ฉด SecondPage()๊ฐ ๋ณด์ด๊ณ , pop()์ ํ๊ฒ ๋๋ฉด, FirstPage()๊ฐ ๋ณด์ด๊ฒ ๋๋ค.
์ฌ๊ธฐ์ ํ๋ฒ๋ pop()์ ํ๊ฒ ๋๋ฉด, subRoute์ ์์ Route์ธ "/" ํด๋น ๊ฒฝ๋ก๋ก ๋์ค๊ฒ ๋๋ค.
context.go("/first/second");
push๋ฅผ ํด์ฃผ๊ฒ ๋๋ฉด, Second() ํ์ด์ง๋ง ์คํ๋๋ค.
FirstPage()๋ง ์คํํ๊ณ ์ถ๋ค๋ฉด ๊ธฐ์กด๊ณผ ๋์ผํ๊ฒ ์ฌ์ฉํ๋ฉด ๋๋ค.
context.push("/first");
SecondPage()๋ง ์คํํ๊ณ ์ถ์ ๋์๋ ๋ ๊ฐ์ง ๋ฐฉ๋ฒ ์ค ํ๋๋ฅผ ์ฌ์ฉํ๋ฉด ๋๋ค. ๋จผ์ , push๋ฅผ ์ฌ์ฉํ ๋ฐฉ๋ฒ์ด๋ค.
context.push("/first/second");
๋ค์์ "/second" ๊ฒฝ๋ก๋ฅผ ์ฌ์ฉํ๊ณ ์ถ์ ๋, ์๋ก์ด Route๋ฅผ ๋ฑ๋กํด์ฃผ๋ฉด ๋๋ค.
GoRoute(
path: "/second",
builder: (BuildContext context, GoRouterState state) =>
const SecondPage(),
),
context.push("/second");
๋ฐ์ดํฐ ์ ๋ฌ๋ ๊ธฐ์กด ์ฌ์ฉ ๋ฐฉ๋ฒ๊ณผ ๋์ผํ๋ค.
FirstPage()์์ ๋ฐ์ดํฐ๋ฅผ ๋ฐ์์ฌ ์ ์๋๋ก ํด์ฃผ์.
GoRoute(
path: "first/:path",
builder: (BuildContext context, GoRouterState state) => FirstPage(
path: state.pathParameters["path"]!,
),
routes: [
GoRoute(
path: "second",
builder: (BuildContext context, GoRouterState state) =>
const SecondPage()),
],
),
FirstPage -> SecondPage
context.go("/first/go/second");
FirstPage
context.push("first/push");
์ด์ด์ Error์ ๊ดํ ๋ถ๋ถ์ ์ดํด๋ณด์.
Error๋ฅผ ๋ฐ์ํ๋ ๊ฐ์ฅ ์ฌ์ด ๋ฐฉ๋ฒ์ ๋ฑ๋ก๋์ง ์์ path๋ก ๋ผ์ฐํ ์ ํด๋ณด๋ฉด ๋๋ค.
context.push("/error");
๋ผ์ฐํฐ๊ฐ ๋ฑ๋ก๋์ง ์์๊ธฐ ๋๋ฌธ์ ์๋ฌ๊ฐ ๋ฐ์ํ๋ค.
go_router ์์๋ ๊ธฐ๋ณธ์ ์ผ๋ก ์๋ฌ์ ๋ํ ๋ณ๋์ ํ์ด์ง๊ฐ ์กด์ฌํ๋ค.
์๋ฌ๋ ์์์ ์ดํด๋ณธ Redirect ์ฒ๋ผ ์๋ฌ๊ฐ ๋ฐ์ํ ๊ฒฝ์ฐ ์๋ฌ ํ์ด์ง๋ก ๋ฆฌ๋ค์ด๋ ํธ ๋๋ ๊ฒ์ด๋ค.
errorBuilder, errorPageBuilder ํ๋ผ๋ฏธํฐ๋ฅผ ์ฌ์ฉํด์ ์๋ฌ ํ์ด์ง๋ฅผ ๋ฑ๋กํด์ฃผ๋ฉด ๋๋ค.
errorBuilder๋ฅผ ์ฌ์ฉํด ์๋ฌ ํ์ด์ง๋ฅผ ๋ฑ๋กํด ์ฃผ๋๋ก ํ์.
์๋ฌ๋ GoRouter ํ๋ผ๋ฏธํฐ๋ก ๋ฑ๋ก์ด ๋๋ค.
errorBuilder
static GoRouter router = GoRouter(
initialLocation: "/",
errorBuilder: (BuildContext context, GoRouterState state) => ErrorPage(
path: state.matchedLocation,
),
...
);
errorPageBuilder
static GoRouter router = GoRouter(
initialLocation: "/",
errorPageBuilder: (BuildContext context, GoRouterState state) =>
NoTransitionPage(child: ErrorPage(path: state.matchedLocation)),
...
);
Error์ ๋ํ UI๋ฅผ ์์ ๋กญ๊ฒ ์์ฑํ ์ ์๋ค.
์ถ๊ฐ๋ก ๋ผ์ฐํฐ builder์๋ ๋ค๋ฅด๊ฒ, error๋ builder ๋๋ pageBuilder ํ๋์ ํ๋ผ๋ฏธํฐ๋ง ์ฌ์ฉํด์ผ ํ๊ณ , ๋ ๋ค ์ฌ์ฉํ๋ ๊ฒฝ์ฐ ์๋ฌ๊ฐ ๋ฐ์ํ๋ค.
๋ฑ๋กํ์ง ์์ ๊ฒฝ๋ก๋ฅผ ์ฌ์ฉํ๋ ๊ฒ ์ธ์๋ path๊ฐ ์ ๋ชป๋ ๊ฒฝ์ฐ์๋ ์๋ฌ ํ์ด์ง๋ก ๋ผ์ฐํ ์ด ๋๋ค.
GoRoute(
path: "/test/:id",
builder: (BuildContext context, GoRouterState state) => const TestPage(),
),
id ํ๋ผ๋ฏธํฐ๊ฐ ์์ผ๋ฏ๋ก ์๋ฌ๊ฐ ๋ฐ์ํ๋ค.
context.push("/test");
go_router๋ฅผ ์ฌ์ฉํด์ BottomNavigationBar๋ฅผ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ์ ๋ํด์ ์ดํด๋ณด๋๋ก ํ์.
BottomNavigationBar ๊ธฐ๋ฅ์ ๋ง๋๋ ๋ฐฉ๋ฒ์ ์ ๋ง ๋ค์ํ ๋ฐฉ๋ฒ๋ค์ด ์กด์ฌํ๋ค. go_router์์ ์ ๊ณตํ๋ ๊ธฐ๋ฅ๋ ์ด๋ค ์ค ํ๊ฐ์ง ๊ธฐ๋ฅ์ด๊ธฐ ๋๋ฌธ์ ์ต์ ํ์ ๋ง๋ ๋ฐฉ๋ฒ์ผ๋ก ์ ์ฉํด ๋ณด์๋ฉด ๋ ๊ฒ ๊ฐ๋ค.
BottomNavigationBar ์ฌ์ฉ์ ์ํด์๋ shellRoute๋ฅผ ์ฌ์ฉํด์ผ ํ๋ค.
StatefulShellRoute.indexedStack ์ด ๋ฐ๋ก IndexedStack์ ์ฌ์ฉํด์ ๊ฐํธํ๊ฒ BottomNavigationBar๋ฅผ ๋ง๋ค ์ ์๋๋ก ์ ๊ณตํ๋ ๋ฉ์๋ ์ด๋ค.
branches ํ๋ผ๋ฏธํฐ๋ฅผ ํ์๋ก ๋ฑ๋กํด์ผ ํ๋ค.
builder๋ฅผ ์ฌ์ฉํด BottomNavigationBar๋ฅผ ๋ง๋ค์ด ์ฃผ๋ฉด ๋๋ค.
StatefulShellRoute.indexedStack(
branches: [],
builder: (BuildContext context, GoRouterState state,
StatefulNavigationShell navigationShell) => Scaffold(),
),
BottomNavigationBar๋ฅผ 3๊ฐ์ ํญ์ผ๋ก ๊ตฌ์ฑํ์ฌ ์์ฑํ์๋ค.
body ๋ถ๋ถ์ StatefulNavigationShell ๊ฐ์ฒด๋ฅผ ๋ฃ์ด์ฃผ๋ฉด ๋๊ณ , currentIndex๋ StatefulNavigationShell ๊ฐ์ฒด์ ํ์ฌ์ currentIndex ์ ๋ณด๊ฐ ์๋ค.
StatefulNavigationShell ๊ฐ์ฒด์ BottomNavigationBar๋ฅผ ์์ฑํ ๋์ ํ์ํ ์ ๋ณด๋ฅผ ๊ฐ์ง๊ณ ์๋ค๊ณ ๋ณด๋ฉด ๋๋ค.
StatefulShellRoute.indexedStack(
branches: [],
builder: (BuildContext context, GoRouterState state,
StatefulNavigationShell navigationShell) => Scaffold(
body: navigationShell,
bottomNavigationBar: BottomNavigationBar(
items: const <BottomNavigationBarItem>[
BottomNavigationBarItem(icon: Icon(Icons.home), label: "A"),
BottomNavigationBarItem(icon: Icon(Icons.settings), label: "B"),
BottomNavigationBarItem(icon: Icon(Icons.account_circle), label: "C"),
],
currentIndex: navigationShell.currentIndex,
onTap: (int index) => null,
),
),,
),
StatefulNavigationShell ๊ฐ์ฒด์ goBranch()๋ฅผ ์ฌ์ฉํด์ ํญ์ ๋ณ๊ฒฝํด ์ค ์ ์๋ค.
onTap: (int index) => navigationShell.goBranch(index),
branches์ BottomNavigationBar ๋ฐ๋์ ํด๋นํ๋ ์คํฌ๋ฆฐ๋ค์ ๋ฃ์ด์ฃผ๋ฉด ๋๋ค.
์ด ๋์ StatefulShellBranch ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํด์ ๋ฑ๋กํด์ฃผ๋ฉด ๋๊ณ , routes์๋ ์ง๊ธ๊น์ง ์ดํด๋ณธ GoRoute๋ฅผ ์ฌ์ฉํ๋ฉด ๋๋ค.
subRoutes ๋ฑ๋ก ์ญ์๋ ๊ธฐ์กด์ ์ฌ์ฉํ๋ ๋ฐฉ๋ฒ๊ณผ ๋์ผํ๋ค.
branches: [
StatefulShellBranch(
routes: [
GoRoute(
path: "/screenA",
builder: (context, state) => const AScreen(),
),
],
),
StatefulShellBranch(
routes: [
GoRoute(
path: "/screenB",
builder: (context, state) => const BScreen(),
),
],
),
StatefulShellBranch(
routes: [
GoRoute(
path: "/screenC",
builder: (context, state) => const CScreen(),
),
],
),
],
์ฑ์ด ์์๋๊ณ initialRoutes๊ฐ BottomNavigationBar๊ฐ ์๋ ํ์ด์ง๋ก ํ๊ณ ์ถ๋ค๋ฉด ํญ์ ๋ฐ๋ ๋ถ๋ถ์ path๋ก ์ง์ ํด ์ฃผ๋ฉด ๋๋ค.
initialLocation: "/screenA",
subRoutes๋ฅผ ์ฌ์ฉํ๊ฒ ๋๋ฉด, BottomNavigationBar ์์์ ๋ผ์ฐํ ์ด ๋๋ ๊ฒ์ด๊ธฐ ๋๋ฌธ์ ํ์ด์ง๊ฐ ์ ํ ๋๋๋ผ๋ BottomNavigationBar๊ฐ ๋จ์ ์์ผ๋, ์ด ๋ถ๋ถ์ ๊ณ ๋ คํด์ ์ฌ์ฉํ์๋ฉด ๋๋ค.
GoRouter
routes: [
GoRoute(
path: "/subScreenC",
builder: (context, state) => const CSubScreen(
isSub: false,
),
),
],
StatefulShellRouter
StatefulShellBranch(
routes: [
GoRoute(
path: "/screenC",
builder: (context, state) => const CScreen(),
routes: [
GoRoute(
path: "subScreenC",
builder: (context, state) => const CSubScreen(),
)
])
],
),
์ง๊ธ๊น์ง go_router๋ฅผ ์ฌ์ฉํ๊ธฐ ์ํ ๋ผ์ฐํฐ ๋ฑ๋ก ๋ถํฐ ์ฌ์ฉ ๋ฐฉ๋ฒ ๋ฐ ๊ธฐ๋ฅ์ ๋ํด์ ์ดํด๋ณด์๋ค.
๋ผ์ฐํฐ๋ Flutter์ ๊ธฐ๋ณธ Navigator๋ฅผ ์ฌ์ฉํด์๋ ์ผ๋ง๋ ์ง ์ํ๋ ๊ธฐ๋ฅ์ ๊ฐ๋ฐํ ์ ์๊ธฐ ๋๋ฌธ์ go_router ์ฌ์ฉ์ด ํ์์ ์ธ ๊ฒ์ ์๋๋ค.
ํ๋ก์ ํธ์ ๋ง๋ ๋ผ์ฐํฐ๋ฅผ ์ ํํด์ ์ฌ์ฉํ๋ ๊ฒ์ด ์ค์ํ๋ค !
๊ถ๊ธํ์ ๋ถ๋ถ์ด ์๊ฑฐ๋ ์ถ๊ฐ์ ์ผ๋ก go_router์ ๋ํด์ ์๊ณ ์ถ์ ๊ธฐ๋ฅ์ด ์๋ค๋ฉด ๋๊ธ ๋จ๊ฒจ์ฃผ์ธ์ ๐ฌ
์ ์ฑ๊ธ ๊ฐ์ฌํฉ๋๋ค~