Menu
CoddyTech

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.

challenge icon

Desafio

Médio

Ao 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) a TaskList que alterna o done da tarefa e notifica os listeners.
  • Faça o onChanged do 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;
              },
            ),
        ],
      ),
    );
  }
}
quiz iconTeste seus conhecimentos

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

Pratique por conta própria: Compilador de Flutter online