Uma lista de objetos em um modelo
Parte da seção Gerenciamento de estado do Journey de Flutter da Coddy. Lição 14 de 27.
Um modelo geralmente mantém uma lista de objetos, e os próprios objetos mudam: uma tarefa é marcada. A regra continua a mesma: a alteração passa por um método do modelo, e o método chama 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();
}
}Alterar task.done a partir do widget também mudaria o objeto, mas nenhum ouvinte ficaria sabendo, então a caixa não se moveria. O modelo é o único lugar que altera seus dados e o único lugar que avisa.
Observe o with. extends indica o que uma classe é, e uma classe estende apenas uma outra classe. with mistura habilidades extras em uma classe, e você pode adicionar várias. ChangeNotifier funciona das duas formas, então class TaskList with ChangeNotifier é o mesmo que extends ChangeNotifier e deixa extends livre para outra coisa.
Desafio
MédioAo tocar em uma tarefa, task.done é alternado diretamente no widget, então nada na tela se move. Mova a alteração para o modelo:
- Adicione um método
toggle(Task task)aTaskListque alterna odoneda tarefa e notifica os listeners. - Faça o
onChangeddo item chamá-lo.
Experimente você mesmo
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;
},
),
],
),
);
}
}
Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Todas as lições de Gerenciamento de estado
3Provider
Provider: Compartilhar um modeloChamando notifyListenersProvider: Observar ou lerProvider: ConsumerDuas telas, um modeloUma lista de objetos em um modeloVários modelos: MultiProviderPratique por conta própria: Compilador de Flutter online