Last time I have written a comparison between different state management, and after some discussions with colleagues and friends (who are the native mobile app developers), I think it is good to have a start on GetX, one of the state management tools in Flutter, mainly because the architecture is like MVVM.
First of all, import GetX library on your project. In pubspec.yaml, import the latest version of GetX under dependencies.
get: ^4.6.1
Remember to run the flutter pub get command after you added a new library.
Next, you can install the GetX plugin if you are using Android Studio. Go to settings/preferences, select plugin and type “getx”, you will then get the plugin. Click install, apply and OK to apply the settings.
Now, you can create the new GetX sets with the plugin. In your current project, go to lib folder and right click->new, you will then see GetX. Click it and you will get a popup. Choose Default for default GetX module and type the module name whatever you want. Click OK.
You should now see there are 3 .dart files in it. For view.dart, it is responsible for the user interface, and you can build widgets there. For logic.dart, it acts like a viewmodel in MVVM, mainly for state changing and page routing functions. And lastly, state.dart is a model that you can put different data model in this class, it is an optional class if you can building a simple function, such as counter function.
Most likely the view links with both logic and state, because you need to display the values in the user interface. So now let’s start the first program in GetX.
Counter
As state is for the model, in the counter function we should have a counter variable, and so here we initialise a variable count.
state.dart
class PageZeroState {
late int count;
PageZeroState() {
///Initialize variables
count=0;
}
}
Then, we need to implement to add function in the logic layer which acts as viewmodel. Once the user presses a button, we will call this function to update count.
logic.dart
class PageZeroLogic extends GetxController {
final PageZeroState state = PageZeroState();
void increase(){
++state.count;
update();
}
}
And for the view, you can build the user interface that you like. This is an example of a simple counter. The text is reflected from the variable count, and IconButton is used to control and do the add process. Don’t forget to write GetBuilder with your logic class, which is responsible for changing the state.
view.dart
import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'logic.dart';
class PageZeroPage extends StatelessWidget {
final logic = Get.put(PageZeroLogic());
final state = Get.find<PageZeroLogic>().state;
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Center(
child: GetBuilder<PageZeroLogic>( builder: (logic){
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(state.count.toString()),
IconButton(onPressed: ()=>logic.increase(),
icon: const Icon(Icons.add)
)
],
);
})
),
),
);
}
}
Build the app and see if it works. You should have a question on your head, why we do need to include update() in the increase function. It is used to update the state, like notifyItemChanged() in recycler view of native Android. To reduce this troublesome process, reactive programming is a solution for you.
Initialise Observable Value
There are 3 ways to create an observable value.
- Rx{Type}
final name = RxString(‘’);
final isLogin = RxBool(false);
final count = RxInt(0);
final balance = RxDouble(0.0);
final items = RxList<String>([]);
final myMap = RxMap<String, int>({}); - Rx<Type>
final name = Rx<String>(‘’);
final isLogin = Rx<bool>(false);
final count = Rx<int>(0);
final balance = Rx<double>(0.0);
final items = Rx<List<String>>([]);
final myMap = Rx<Map<String, int>>({}); - .obs
final name = ''.obs;
final isLogin = false.obs;
final count = 0.obs;
final balance = 0.0.obs;
final items = [].obs;
final myMap = {}.obs;
The last method is the clearest way to initialise an observable, and I will use it in the following example.
Change the type of count to observable, you can change it to var (auto) or RxInt.
state.dart
class PageZeroState {
late var count;
PageZeroState() {
///Initialize variables
count = 0.obs;
}
}
Remove the line update() in logic layer, there is no need to call like this as we have the observable variable.
logic.dart
class PageZeroLogic extends GetxController {
final PageZeroState state = PageZeroState();
void increase() {
++state.count;
}
}
Last but not least, change the GetBuilder into Obx as the observer of the function.
view.dart
class PageZeroPage extends StatelessWidget {
final logic = Get.put(PageZeroLogic());
final state = Get.find<PageZeroLogic>().state;
@override
Widget build(BuildContext context) {
return Scaffold(
body: SafeArea(
child: Center(
child: Obx((){
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text(state.count.toString()),
IconButton(onPressed: ()=>logic.increase(),
icon: const Icon(Icons.add)
)
],
);
})
),
),
);
}
}
Run your apps again and see the result. It looks like the same as before, and the counter works when you clicking the add button. Reactive programming makes your coding process easier and your code will be clearer!
Next time, I will talk about the paging using GetX. Give me a clap for support me~ Happy hacking!