はじめに
こんにちは、エンジニアのkeitaMaxです。
前回の記事
前回カウンターアプリを作成しました。そこで処理とUIを同じファイルに書いたのですが、今回はそれをcontroller.dartファイルを作成して分けようと思います。
前回までのコード
import 'package:flutter/material.dart';
class CounterScreen extends StatefulWidget {
const CounterScreen({super.key});
@override
State<CounterScreen> createState() => _CounterScreenState();
}
class _CounterScreenState extends State<CounterScreen> {
int count = 0;
void incrementCounter() {
setState(() => count++);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('CounterScreen')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Text('$count'),
TextButton(
onPressed: incrementCounter,
child: const Text('カウントアップ'),
),
],
),
),
);
}
}
この処理部分を別のファイルに分けようと思います。
Controllerファイルの作成
同じ階層にcontroller.dartファイルを作成し、CounterControllerを作成します。
import 'package:flutter/material.dart';
class CounterController extends ChangeNotifier {
}
ChangeNotifierを継承しているとnotifyListeners()を実行した時に、UI側に変更したというのを知らせて再描画をしてくれるので、ChangeNotifierを継承します。
Controllerの実装
ほぼ↑のリファレンスに書いてあるように実装をします。
import 'package:flutter/material.dart';
class CounterController extends ChangeNotifier {
int _count = 0;
int get count => _count;
void increment() {
_count++;
notifyListeners();
}
}
increment関数を実行することで、_countの値が増えるようになります。
増えた時にnotifyListeners()を実行してUIに再描画を促しています。
_countは外部から直接変更させないためにプライベート変数にしています。
_countの値を参照したい時は、getterを使用してcountから参照できるようにしています。
Screenの修正
Screenの方からContollerを読み込んで使用する形に修正します。
final controller = CounterController();
int get count => controller.count;
void increment() {
controller.increment();
setState(() {});
}
このようにCounterControllerをimportしてcontroller.countとcontroller.increment()を取り出しています。
import 'package:flutter/material.dart';
import 'controller.dart';
class CounterScreen extends StatefulWidget {
const CounterScreen({super.key});
@override
State<CounterScreen> createState() => _CounterScreenState();
}
class _CounterScreenState extends State<CounterScreen> {
final controller = CounterController();
int get count => controller.count;
void increment() {
controller.increment();
setState(() {});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('CounterScreen')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Text('$count'),
TextButton(onPressed: increment, child: const Text('カウントアップ')),
],
),
),
);
}
}
これでflutter runで実行してみてください。
しっかり動いているはずです!
おわりに
この記事での質問や、間違っている、もっといい方法があるといったご意見などありましたらご指摘していただけると幸いです。
最後まで読んでいただきありがとうございました!
参考