실제 앱에서 사용할만한 상태관리 예제로 Scaffold 의 bottonNavigationBar 의 인덱스를 전역에서 사용하는 예제를 만들어 보려고 합니다.
요즘 앱에서 많이 사용하는 bottonNavigationBar 의 형태를 Flutter 에서는 Scaffold를 통해서 간단히 만들 수 있습니다.
이제 bottom navigation bar 가 있는 앱을 만들어 보겠습니다.
역시나 저는 MaterialApp 대신에 Getx의 기능을 사용하기 위해 GetMaterialApp으로 시작해 보겠습니다.
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return GetMaterialApp(
title: 'Flutter Demo',
initialBinding: InitBinding(),
initialRoute: '/',
getPages: [
GetPage(name: '/', page: () => const Home()),
GetPage(name: '/search', page: () => Search()),
GetPage(name: '/my', page: () => My()),
]
);
}
}
Name Route 를 사용하기 위해 GetPage를 통해 3개의 페이지를 만들었습니다.
home, search, my 3개의 페이지를 만들고 Route 에 이름을 부여하였습니다.
GetMaterialApp에서는 initialBinding 이라고 하는 binding을 지원합니다.
앱이 실행될때 최초로 실행이 되는 코드입니다.
실제 initialRoute를 통해 최초 화면인 Home 보다 먼저 실행입니다.
앱이 최초 실행되는 순간부터 주입하고 싶은 여러 controller를 추가할 수 있습니다.
예를 들어, 로그인이 되어 있는지 확인할 수도 있고 네트워크의 상태를 최초 앱구동부터 앱이 실행동안 감시하는 controller 를 주입할 수도 있습니다.
binding 의 코드는 다음과 같습니다.
import 'package:blog_demo/controller/bottom_index_controller.dart';
import 'package:get/get.dart';
class InitBinding extends Bindings {
@override
void dependencies() {
Get.put(BottomIndexController());
}
}
Bindings를 상속하는 간단한 코드입니다.
여기서 사용하는 BottomIndexController 은 아래 처럼 간단히 구현이 가능합니다.
import 'package:get/get.dart';
class BottomIndexController extends GetxController {
static BottomIndexController get to => Get.find();
RxInt currentIndex = 0.obs;
void changePageIndex(int index) {
currentIndex(index);
}
}
이제 앱구동부터 앱이 종료되는 시점까지 BottomNavigationBar의 인덱스를 관리할 수 있습니다.
이제 앱의 initialRoute인 home 을 간단히 구현해 보겠습니다.
import 'package:blog_demo/component/bottom_navigation_widget.dart';
import 'package:flutter/material.dart';
class Home extends StatelessWidget {
const Home({Key? key}): super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Home'),
),
body: const Center(
child: Text('Home', style: TextStyle(fontSize: 40),)
),
bottomNavigationBar: BottomNavigationWidget(),
);
}
}
코드의 내용은 간단하지만 유심히 보셔야 할 부분은 BottomNavigationWidget() 입니다.
BottomNavigationBar를 사용하는 모든 페이지에서 공용으로 사용할 Widget이으로 하나의 클래스로 만듭니다.
import 'package:blog_demo/controller/bottom_index_controller.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
class BottomNavigationWidget extends StatelessWidget {
BottomNavigationWidget({Key? key}) : super(key: key);
final BottomIndexController indexCtrl = Get.find();
@override
Widget build(BuildContext context) {
return BottomNavigationBar(
type: BottomNavigationBarType.fixed,
currentIndex: indexCtrl.currentIndex.value,
selectedItemColor: Colors.black,
unselectedItemColor: Colors.grey,
onTap: (index) {
indexCtrl.changePageIndex(index);
switch (index) {
case 0:
Get.toNamed('/');
break;
case 1:
Get.toNamed('/search');
break;
case 2:
Get.toNamed('/my');
break;
}
},
items: const [
BottomNavigationBarItem(
icon: Icon(Icons.home_outlined),
activeIcon: Icon(Icons.home),
label: '홈'),
BottomNavigationBarItem(
icon: Icon(Icons.search_outlined),
activeIcon: Icon(Icons.search),
label: '검색'),
BottomNavigationBarItem(
icon: Icon(Icons.account_circle_outlined),
activeIcon: Icon(Icons.account_circle),
label: 'My'),
],
);
}
}
BottomNavigationBar의 currentIndex 값을 controller의 값으로 하였습니다.
그리고 index의 값이 선택될 때마다 index의 값을 저장하도록 하였습니다.
indexCtrl.changePageIndex(index);
이제 BottomNavigationBar를 탭하여 다른 메뉴로 이동해 보겠습니다.
BottomNavigationBar도 이동을 했고, index의 값도 정상적으로 읽어오고 있습니다.
실제 출시한 앱에서도 유용하게 사용한 코드입니다.
Search 페이지의 내용입니다. Get.find()를 통해 controller 의 값을 간단히 가져올 수 있습니다.
class Search extends StatelessWidget {
Search({Key? key}): super(key: key);
final BottomIndexController bottomIndexController = Get.find();
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Search'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text('Search', style: TextStyle(fontSize: 40),),
const SizedBox(height: 20,),
Obx(() =>
Text(bottomIndexController.currentIndex.value.toString(),
style: const TextStyle(fontSize: 30),)),
],
)
),
bottomNavigationBar: BottomNavigationWidget(),
);
}
}
'Flutter' 카테고리의 다른 글
[Flutter] Debug Mode Banner 없애기 (0) | 2022.08.23 |
---|---|
[Flutter] Getx Route Management (0) | 2022.08.23 |
[Flutter] Getx 상태관리(2) Get.find() (0) | 2022.08.22 |
[Flutter] Container - decoration (0) | 2022.08.09 |
[Flutter] Container - padding & margin (0) | 2022.08.08 |