Model内のオブジェクトのリスト
CoddyのFlutterジャーニー「状態管理」セクションの一部。レッスン 14/27。
モデルはオブジェクトのリストを保持することが多く、オブジェクト自体も変化します。タスクにチェックが付く、といった具合です。ルールは変わりません。変更はモデルのメソッドを通じて行い、そのメソッドが notifyListeners() を呼び出します。
class TaskList with ChangeNotifier {
final List<Task> _tasks = [Task('Buy milk'), Task('Call Sam')];
List<Task> get tasks => _tasks;
void toggle(Task task) {
task.done = !task.done;
notifyListeners();
}
}ウィジェットから task.done を変更してもオブジェクト自体は変わりますが、リスナーには通知されないため、ボックスは動きません。データを変更する場所はモデルに集約し、通知する場所もモデルに集約します。
with に注目してください。extends はクラスが何であるかを示し、クラスが継承できるクラスは1つだけです。with はクラスに追加の機能を組み込み、複数追加することもできます。ChangeNotifier はどちらの方法でも使えるため、class TaskList with ChangeNotifier は extends ChangeNotifier と同じであり、別のものに使うために extends を空けておけます。
チャレンジ
中級タスクをタップすると、ウィジェット内でtask.doneが切り替わるため、画面上の何も動きません。変更処理をモデルに移しましょう。
TaskListに、タスクのdoneを切り替えてリスナーに通知するメソッドtoggle(Task task)を追加します。- タイルの
onChangedからこのメソッドを呼び出すようにします。
自分で試してみよう
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
class Task {
Task(this.title);
final String title;
bool done = false;
}
class TaskList with ChangeNotifier {
final List<Task> _tasks = [Task('Buy milk'), Task('Walk the dog'), Task('Call Sam')];
List<Task> get tasks => _tasks;
int get doneCount => _tasks.where((t) => t.done).length;
}
void main() {
runApp(
ChangeNotifierProvider(
create: (context) => TaskList(),
child: const MyApp(),
),
);
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return const MaterialApp(
debugShowCheckedModeBanner: false,
home: HomePage(),
);
}
}
class HomePage extends StatelessWidget {
const HomePage({super.key});
@override
Widget build(BuildContext context) {
final list = context.watch<TaskList>();
return Scaffold(
appBar: AppBar(title: Text('${list.doneCount} of ${list.tasks.length} done')),
body: ListView(
children: [
for (final task in list.tasks)
CheckboxListTile(
title: Text(task.title),
value: task.done,
onChanged: (value) {
task.done = !task.done;
},
),
],
),
);
}
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
状態管理のすべてのレッスン
自分で練習してみよう: Flutterオンラインコンパイラ