Getx로는 제대로 된 Bottom tab navigator를 구현하기 힘들다는 블로그를 봤는데... 개뿔.. 잘만하더라....
일단 기본 네비게이터로 구현했던 nested navigation 시스템에서는 좀 있어 보일라고 NavigationTree.dart라는 파일에서 모든 네비게이션 시스템이 관리되도록 하려고 했는데.... 👇👇 참... 등신짓이었어.
2022.10.21 - [Flutter/Flutter Project] - [소셜차트] 앱 제작기 #3. Navigation 시스템 구성
nested navigator에서는 같은 여러 스크린이 각각 다른 네비게이터에 배치될 수 있는데 이 때도 문제가 심각해지더라고.. 뿐만 아니라 각 스크린 argument 전달에도 문제가 있었고, 페이지를 변경하거나 확장하는 것도 개판이었고... 그야 말로 대 환장 파티... 에휴.....
그래도 이번 기회에 view와 controller를 분리시키는 getx의 의도를 조금 깨달은 거 같아서 다행이긴 해. 역시 고생을 해야 늘어 ㅋㅋ
우선 파일 하나로 구현했던 bottom tab navigator를 tab별로 파일을 분리해서 심플하게 변경했어👇
class NavigatorMain extends GetView<MainNavigatorController> {
const NavigatorMain({super.key});
@override
Widget build(BuildContext context) {
return Scaffold(
resizeToAvoidBottomInset: false,
body: Obx(
() => IndexedStack(
index: controller.currentIndex.index,
children: const [
TabNavigatorHome(),
TabNavigatorExplore(),
TabNavigatorNotice(),
TabNavigatorProfile(),
],
),
),
bottomNavigationBar: Obx(() => controller.isBottomTabVisible
? BottomNavigationBar(
type: BottomNavigationBarType.fixed,
items: const [
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.home),
label: "홈",
),
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.search),
label: "탐색",
),
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.bell),
label: "알림",
),
BottomNavigationBarItem(
icon: Icon(CupertinoIcons.person),
label: "내정보",
),
],
currentIndex: controller.currentIndex.index,
onTap: (index) => controller.currentIndex = NavKeys.values[index],
)
: Container(height: 0)),
);
}
}
기존에 사용하던 Stack + OffStage 조합으로 구현했던 tab별 navigator는 IndexedStack하나로 간단하게 변경했고 bottom tab navigator를 감추고 싶을 경우도 있을거 같아서 get controller에 isBottomTabVisible를 하나 추가했어.
그리고 각 navigator의 MaterialPageRoute는 GetPageRoute로 변경하고 각 스크린에 binding을 통해서 controller를 붙여줬어. 이렇게 하는 사람들이 많아서 따라해봤는데 확실히 편하고 구조적으로도 안정되어 있는 거 같아.👇👇
class HomeNavigator extends StatelessWidget {
const HomeNavigator({super.key});
@override
Widget build(BuildContext context) {
return Navigator(
key: Get.nestedKey(NavKeys.home.index),
initialRoute: ScreenHome.routeName,
onGenerateRoute: ((settings) {
switch (settings.name) {
case ScreenHome.routeName:
return GetPageRoute(
page: () => ScreenHome(navKey: NavKeys.home),
);
case ScreenInsightCard.routeName:
return GetPageRoute(
page: () => ScreenInsightCard(navKey: NavKeys.home));
case ScreenProfile.routeName:
var args = settings.arguments;
return GetPageRoute(
page: () =>
ScreenProfile(userId: args.toString(), navKey: NavKeys.home),
binding: ScreenProfileBinding(navKey: NavKeys.home),
);
case ScreenChart.routeName:
return GetPageRoute(
page: () => ScreenChart(navKey: NavKeys.home),
binding: ScreenChartBinding(navKey: NavKeys.home),
);
case ScreenWrite.routeName:
return GetPageRoute(
page: () => ScreenWrite(navKey: NavKeys.home),
binding: ScreenWriteBinding(navKey: NavKeys.home),
);
default:
return null;
}
// });
}),
);
}
}
get으로 router 시스템을 변경하면서 스크린이나 그 컨트롤러를 여러 navigator에서 재활용하는 게 매우 간편해졌고 스크린에 argument를 전달하는 것도 마찬가지로 쉬워졌어. 이렇게 변경하는 과정에서 각 screen이나 navigator는 binding 파일과 controller 파일을 가지도록 만들고 있어. controller나 binding이 당장 필요하지 않은 건 만들지 않았지만 나중에는 다 만들어 둘라고 ㅋㅋ 왜? 걍 버릇을 들이려고 하는 것도 있고 언제 또 controller가 필요할 지 모르는데 그 때마다 허둥지둥하고 싶지 않아서..
그리고 파일이랑 폴더 이름도 많이 변경했어. 몰랐는데 dart에서 파일, 폴더 작명은 소문자에 "_" (under score)를 사용하는 걸 추천하더라고 👇👇 뭐 이유가 있겠지...하고 나도 따르고 있어.
https://dart.dev/guides/language/effective-dart/style
기본적으로 UpperCamelCase, lowerCamelCase 그리고 lowercase_with_underscores 이렇게 3가지가 있는데 위에서 언급한 것처럼 파일, 폴더, 라이브러리는 lowercase_with_underscores를 사용하고 Class 같은 type을 나타내는 애들은 UpperCamelCase, 그리고 그 type의 instance나 constant는 lowerCamelCase 사용을 추천한다고 되어 있어.
아무리 혼자 작업하더라고 지킬 건 지켜야겠지 ㅎㅎ 암튼 더 자세한 건 위 링크에 있는 문서를 보라구.
암튼 그래서 결국 navigation 시스템 다 갈아엎고 스크린들도 좀 더 추가하고 firebase model 만들고 하는 과정에 있어. 여기까지 하는데 약 2주 좀 넘게 걸렸네.. 아이고 언제 다 만드냐 ㅋㅋㅋㅋ
아이고 우리 아들 운다~ 안녕~!
'Flutter > Flutter Study' 카테고리의 다른 글
[Flutter] Bad state: Future already completed (0) | 2022.11.10 |
---|---|
[Flutter] getx page&controller 재사용 (0) | 2022.11.02 |
[Flutter] loading 화면 (0) | 2022.10.25 |
[Flutter] Firebase auth email link login (0) | 2022.10.21 |
[Flutter] GetX (0) | 2022.10.17 |