티스토리 뷰
0. 소개
이전에 StatefulWidget으로 만들었던 BottomNavigationBar를 GetX controller를 이용해 만들어보겠습니다.
GetX 라이브러리에서는 StatefulWidget 사용을 지양하니 섞어 사용중이시라면 GetX 방식으로 바꾸시는걸 권장드립니다.
이전글
1. GetX Controller 만들기
// BottomNavigationBar 상태 관리를 위한 GetX controller
class MyBottomNavgationBarController extends GetxController {
// Get.fine 대신 클래스명 사용 가능
static MyBottomNavgationBarController get to => Get.find();
// 현재 선택된 탭 아이템 번호 저장
final RxInt selectedIndex = 0.obs;
// 탭 이벤트가 발생할 시 selectedIndex값을 변경해줄 함수
void changeIndex(int index) {
selectedIndex(index);
}
}
BottomNavigationBar 필수 속성인 currentIndex와 onTap에 지정해주기 위한 변수와 함수를 만듭니다.
2. BottomNavigationBar class 정의
class MyBottomNavgationBar extends GetView<MyBottomNavgationBarController> {
const MyBottomNavgationBar({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Obx(() => BottomNavigationBar(
// 현재 인덱스를 selectedIndex에 저장
currentIndex: controller.selectedIndex.value,
// 요소(item)을 탭 할 시 실행)
onTap: controller.changeIndex,
// 선택에 따라 icon·label 색상 변경
selectedItemColor: context.theme.colorScheme.onBackground,
unselectedItemColor: context.theme.colorScheme.onSurfaceVariant,
// 선택에 따라 label text style 변경
unselectedLabelStyle: TextStyle(fontSize: 10),
selectedLabelStyle: TextStyle(fontSize: 10),
// 탭 애니메이션 변경 (fixed: 없음)
type: BottomNavigationBarType.fixed,
backgroundColor: context.theme.colorScheme.background,
// Bar에 보여질 요소. icon과 label로 구성.
items: <BottomNavigationBarItem>[
BottomNavigationBarItem(
icon: controller.selectedIndex.value ==
0 // 선택된 탭은 채워진 아이콘, 나머지는 line 아이콘
? SvgPicture.asset(
'assets/icons/menu1_solid.svg',
)
: SvgPicture.asset(
'assets/icons/menu1_line.svg',
),
label: "tap1"),
BottomNavigationBarItem(
icon: controller.selectedIndex.value == 1
? SvgPicture.asset(
'assets/icons/menu2_solid.svg',
)
: SvgPicture.asset(
'assets/icons/menu2_line.svg',
),
label: "tap2"),
BottomNavigationBarItem(
icon: controller.selectedIndex.value == 2
? SvgPicture.asset(
'assets/icons/menu3_solid.svg',
)
: SvgPicture.asset(
'assets/icons/menu3_line.svg',
),
label: "tap3"),
],
));
}
}
GetView를 통해 controller라는 키워드로 MyBottomNavgationBarController에 접근할 수 있습니다.
또, BottomNavigationBar를 Obx로 감싸 선택된 탭이 채워진 아이콘으로 변경될 수 있게 하였습니다. (Obx 내부에 변경 값이 있는지 감시)
3. Scaffold 정의
class RootScaffold extends StatelessWidget{
// 탭별 화면
static List<Widget> tabPages = <Widget>[
Page1(), // 외부 클래스로 정의
Page2(),
Page3(),
];
@override
Widget build(BuildContext context) {
// 페이지 전환을 위한 MyBottomNavgationBarController 인스턴스화 (의존성 주입)
// Get.put : 수명이 페이지와 같음
Get.put(MyBottomNavgationBarController());
return Scaffold(
backgroundColor: context.theme.colorScheme.background,
// 빈 AppBar 따로 정의
appBar: EmptyAppBar(),
// MyBottomNavgationBarController의 변수가 변하면 화면(페이지) 변경
body: Obx(() => SafeArea(
child:
// static 변수를 이용해 컨트롤러 접근
tabPages[MyBottomNavgationBarController.to.selectedIndex.value])),
// 2번에서 만든 BottomNavgationBar 컴포넌트
bottomNavigationBar: MyBottomNavgationBar(),
);
}
}
각 탭별 페이지 컴포넌트를 정의하고 컨트롤러에 저장한 인덱스를 통해 탭별로 맞는 화면을 body 부분에 보여줍니다.
감사합니다.
Ref.
'Flutter' 카테고리의 다른 글
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- TestCode
- 아키텍쳐 패턴
- Flutter
- 리액티브 프로그래밍
- notion
- design pattern
- swift
- RX
- Flux
- Swift Concurrency
- 코디네이터 패턴
- reactive programming
- 노션
- SWM
- Architecture Pattern
- 소프트웨어마에스트로
- 비동기/동기
- coordinator pattern
- ios
- SwiftUI
- healthkit
- 프로그래머스
- DocC
- MVVM
- MVI
- combine
- Bloking/Non-bloking
- MVC
- GetX
- programmers
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
글 보관함