단순 상태 관리 앱 화면
main(controller 등록)
class SimpleStatePage extends StatelessWidget {
const SimpleStatePage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
// getx controller 등록
Get.put(CountControllerWithGetX());
return Scaffold(
appBar: AppBar(
title: Text('단순 상태 관리'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Expanded(child: WithGetX()),
Expanded(
// provider controller 등록
child: ChangeNotifierProvider<CountControllerWithProvider>(
create: (_) => CountControllerWithProvider(),
child: WithProvider(),
)),
],
),
));
}
}
Provider
controller
class CountControllerWithProvider extends ChangeNotifier {
int count = 0;
void increase() {
count++;
notifyListeners();
}
}
ui
class WithProvider extends StatelessWidget {
const WithProvider({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Center(
child: Column(
children: [
Text(
"Provider",
style: TextStyle(fontSize: 50),
),
Consumer<CountControllerWithProvider>(
builder: (_, snapshot, child) {
return Text("${snapshot.count}", style: TextStyle(fontSize: 50));
},
),
RaisedButton(
onPressed: () {
// listen: false를 줘서 consumer 부분만 rebuild
Provider.of<CountControllerWithProvider>(context, listen: false)
.increase();
},
child: Text(
"+",
style: TextStyle(fontSize: 50),
),
),
],
),
);
}
}
GetX
controller
class CountControllerWithGetX extends GetxController {
int count = 0;
void increase() {
count++;
update();
}
}
ui
class WithGetX extends StatelessWidget {
const WithGetX({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
"GetX",
style: TextStyle(fontSize: 50),
),
GetBuilder<CountControllerWithGetX>(builder: (controller) {
return Text(
"${controller.count}",
style: TextStyle(fontSize: 50),
);
}),
RaisedButton(
onPressed: () {
Get.find<CountControllerWithGetX>().increase();
},
child: Text(
"+",
style: TextStyle(fontSize: 50),
),
),
],
),
);
}
}
비교
Provider는 consumer를 이용해 상태값을 가져오고 provider와 context를 이용해 controller의 비즈니스 로직을 불러옵니다.
GetX는 GetBuilder를 통해 상태값을 가져오고 Get.find를 통해 controller의 비즈니스 로직을 가져옵니다.
context를 사용하지 않는 GetX 방식은 위젯으로 분리하여 사용가능합니다.
...{
...
return (
...,
buildRaisedButton(),
);
Widget buildRaisedButton() {
return RaisedButton(
onPressed: () {
Get.find<CountControllerWithGetX>().increase();
},
child: Text(
"+",
style: TextStyle(fontSize: 50),
),
);
}
}
반면, provider의 경우에는 stateful 위젯으로 변경하거나 context를 넘져워야합니다.
buildRaisedButton(context),
],
),
);
}
Widget buildRaisedButton(BuildContext context) {
return RaisedButton(
onPressed: () {
// listen: false를 줘서 consumer 부분만 rebuild
Provider.of<CountControllerWithProvider>(context, listen: false)
.increase();
},
child: Text(
"+",
style: TextStyle(fontSize: 50),
),
);
}
}
GetX는 선언이 자유롭다.
부모에서 controller를 선언해줄 필요가 없습니다.
ui 부분에서 바로 사용 가능
class WithGetX extends StatelessWidget {
const WithGetX({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
// 바로 사용 가능
Get.put(CountControllerWithGetX());
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
"GetX",
style: TextStyle(fontSize: 50),
),
GetBuilder<CountControllerWithGetX>(builder: (controller) {
return Text(
"${controller.count}",
style: TextStyle(fontSize: 50),
);
}),
RaisedButton(
onPressed: () {
Get.find<CountControllerWithGetX>().increase();
},
child: Text(
"+",
style: TextStyle(fontSize: 50),
),
),
],
),
);
}
}
또한 클래스가 생성될때 바로 사용가능합니다.
class WithGetX extends StatelessWidget {
const WithGetX({Key? key}) : super(key: key);
// 클래스가 생성될때 바로 사용가능
CountControllerWithGetX _countControllerWithGetX =Get.put(CountControllerWithGetX());
@override
Widget build(BuildContext context) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
"GetX",
style: TextStyle(fontSize: 50),
),
GetBuilder<CountControllerWithGetX>(builder: (controller) {
return Text(
"${controller.count}",
style: TextStyle(fontSize: 50),
);
}),
RaisedButton(
onPressed: () {
//find를 할 필요가 없음
_countControllerWithGetX.increase();
},
child: Text(
"+",
style: TextStyle(fontSize: 50),
),
),
],
),
);
}
}
특정 컨트롤러에 아이디를 부여해서 관리 가능
cotroller
class CountControllerWithGetX extends GetxController {
int count = 0;
// id를 받아서 update에 배열로 넣어줌
void increase(String id) {
count++;
update([id]);
}
}
ui
class WithGetX extends StatelessWidget {
WithGetX({Key? key}) : super(key: key);
CountControllerWithGetX _countControllerWithGetX =
Get.put(CountControllerWithGetX());
@override
Widget build(BuildContext context) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(
"GetX",
style: TextStyle(fontSize: 50),
),
GetBuilder<CountControllerWithGetX>(
// id 추가
id: "first",
builder: (controller) {
return Text(
"${controller.count}",
style: TextStyle(fontSize: 50),
);
},
),
GetBuilder<CountControllerWithGetX>(
id: "second",
builder: (controller) {
return Text(
"${controller.count}",
style: TextStyle(fontSize: 50),
);
},
),
buildRaisedButton("first"),
buildRaisedButton("second"),
],
),
);
}
Widget buildRaisedButton(String id) {
return RaisedButton(
onPressed: () {
// id를 넘겨줌
_countControllerWithGetX.increase(id);
},
child: Text(
"+",
style: TextStyle(fontSize: 50),
),
);
}
}
참고
https://www.youtube.com/watch?v=k3hgQu6it4c
728x90
'Usage > Flutter' 카테고리의 다른 글
[Flutter] GetX 종속성 관리 - 의존성 주입 (0) | 2021.06.17 |
---|---|
[Flutter] GetX의 반응형 상태관리 (0) | 2021.06.17 |
[Flutter] GetX Routing 사용법 및 기존 routing 비교 (0) | 2021.06.17 |
[Flutter] Bloc Pattern (stateful -> bloc -> skip event bloc ) (0) | 2021.06.16 |
[Flutter] FutureBuilder를 통해 future 리턴 받기 (0) | 2021.06.15 |