Flutterでは数多くの状態管理方法があるのですが、今回は「GetX」というパッケージを触ってみようと思います!
追記:
こちらのパッケージ、現在では主流となっているRiverpodを同じくらいのLike数があるのですが、過去に色々あって古参Flutterエンジニアからは敬遠されている節があるようです
ただ多くのバージョンアップを繰り返してクオリティも上がっているようなので、状態管理の選定で一考の余地はあるのかなと思います
GetXとは
公式では以下のように説明されています。
GetX is an extra-light and powerful solution for Flutter. It combines high-performance state management, intelligent dependency injection, and route management quickly and practically.
DIや状態管理、ルートの管理を行うためのパッケージということみたいです。
やってみる
では実際にコードに組み込んでいきましょう
今回使用しているバージョンは以下です。
・Flutter: stable, 2.0.6
・GetX: 4.1.4
GetMaterialApp
GetXでRouteNavigationの管理を行うには、最初にGetMaterialApp(home: Widget())
で囲ってあげる必要があるようです。
void main() {
runApp(
GetMaterialApp(
home: MyApp(),
),
);
}
ただ上記で使用したGetMaterialApp
は、状態管理やDIを行うだけならば必要がないもののようです。
基本的には画面遷移などもGetXパッケージで管理した方がいいと思うのでとりあえずこちらで囲んでおけば問題ないかと思います。
GetxController
次に状態管理やロジックを書くためのコントローラークラスを作成します。
コントローラーを作るためにはGetxController
を継承します。
class Controller extends GetxController{
// state
var count = 0.obs;
// logic
increment() => count++;
}
0.obs
という見慣れないものが出てきました。
公式の文章を引用したものがこちら
You can make any variable observable using a simple ".obs".
どうやら値を簡単にObservableなものにしてくれるもののようです。
基本的にステートの情報はリアルタイムでUIに反映させたいと思うので、GetXで状態管理をするならば**.obs**を多用することになりそうです。
UI
では次にUI部分を作成していきます。
GetXではStatelessWidgetの中に組み込んでいけるようです(この辺はRiverpodなどと同じですね)
一通り出来上がったのがこちらです
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
final Controller c = Get.put(Controller());
return MaterialApp(
title: 'Flutter Demo',
home: Scaffold(
body: Center(
child: Obx(
() => Text(
'${c.count}',
),
),
),
floatingActionButton: FloatingActionButton(
onPressed: c.increment,
child: Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
),
);
}
}
では一つずつ説明します。
Get
まずこちら
final Controller c = Get.put(Controller());
作成したコントローラーを使用するにはGet.put(Controller());
とする必要があります。
GetXではGet.~~()
というものが複数存在します。例を挙げると
Get.to(NextScreen()); // 画面遷移を行う
Get.back(); // 前の画面に戻る
Get.off(NextScreen()); // 前の画面に戻ることのない遷移(Splashやログイン画面)
Get.offAll(NextScreen()); // 以前の画面を全てキャンセル
他にもRouteNameを利用した画面遷移などの方法もあるので、詳しくはこちらを確認してみてください。
Obx()
次にControllerで定義したStateを表示している部分の説明をします。
Obx(
() => Text(
'${c.count}',
),
),
.obsでObservable化した値をリアルタイムでUIに反映させるにはObx(() => Widget())
で囲んであげる必要があります。
そうすることで
onPressed: c.increment,
こちらで発火した関数でインクリメントされた値がリアルタイムで反映されます。
終わり
とまぁざっと触ってみたんですが、既存で広く利用されているRiverpodやProviderなどよりはずっとシンプルに書けるのかなーといった印象です。
ただ今回の記事は公式ページを軽く翻訳した程度のものなので、もっと詳細が気になる方は公式情報を見てみてください!