Flutter: ウィジェットをキャッシュしておく
June 5, 2024
なんとなく思いついたのでコードをメモ。
一度作成したウィジェットをキャッシュに保存しておいて、必要になったときだけウィジェットを再構築する。
次の例で行くと、3の倍数かそうでないかで表示を切り替えている。何も考えないと数字がカウントアップされるごとに SanNoBaisuWidget
ウィジェットが build()
メソッドで読んでいる中身のウィジェットを構築されることになるが、本当にウィジェットを再構築する必要があるのは「奇数から偶数」「偶数から奇数」に切り替わるタイミングのみである。
次のコードのようにすることで、再構築が必要なとき以外の時はキャッシュしておいたウィジェットを返すことができる。
今回の例だと SanNoBaisuWidget
が返しているのは Text()
だけであり軽量だが、これが複雑なウィジェットになってくればくるほどキャッシュから返すことにより効率化できることになる。
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatefulWidget {
const MyApp({super.key});
@override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
int _count = 0;
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Column(
children: <Widget>[
Text(_count.toString()),
IconButton(
icon: const Icon(Icons.add),
onPressed: () {
setState(() {
_count++;
});
},
),
SanNoBaisuWidget(count: _count),
],
),
),
);
}
}
class SanNoBaisuWidget extends StatefulWidget {
const SanNoBaisuWidget({
super.key,
required this.count,
});
final int count;
@override
State<SanNoBaisuWidget> createState() => _SanNoBaisuWidgetState();
}
class _SanNoBaisuWidgetState extends State<SanNoBaisuWidget> {
Widget? _cache;
bool _isSanNoBaisu(int count) {
return count % 3 == 0;
}
@override
void didUpdateWidget(SanNoBaisuWidget oldWidget) {
if (_isSanNoBaisu(oldWidget.count) != _isSanNoBaisu(widget.count)) {
_cache = null;
}
super.didUpdateWidget(oldWidget);
}
@override
Widget build(BuildContext context) {
return _cache ??= _isSanNoBaisu(widget.count)
? const Text('3の倍数')
: const Text('3の倍数ではない');
}
}