Eu recorri a esse meio pois seguindo os passos do vídeo não obtive sucesso; a nova tarefa não aparecia, apesar de adicionada à lista de tarefas. Baseando-me num artigo de InheritedWidget indicado pelo curso anterior, adotei as seguintes medidas e funcionou:
Primeiro, o atributo tasks virou um parâmetro obrigatório, a fim de que ele seja repassado na criação das respectivas árvores de Widget.
class TaskInherited extends InheritedWidget {
static final List<TaskCard> defaultTasks = [...];
final List<TaskCard> tasks;
const TaskInherited({super.key, required this.tasks, required super.child});
static TaskInherited of(BuildContext context) {...}
@override
bool updateShouldNotify(TaskInherited old) {...}
addTask(String name, String photo, int difficulty) {...}
}
Segundo, o MaterialApp cria a tela inicial, carregando as tarefas-padrão criadas anteriormente no TaskInherited.
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'MyApp',
theme: customTheme,
home: TaskInherited(
tasks: TaskInherited.defaultTasks,
child: const TaskScreen(),
),
);
}
}
Terceiro, na navegação para tela de formulário utilizo o pushReplacement
a fim de repor uma nova tela, e repassando a lista de tarefas do contexto atual a um novo TaskInherited e uma nova árvore de Widgets.
...
class _TaskScreenState extends State<TaskScreen> {
...
onFloatingActionButtonPressed() =>
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder:
(context) =>
TaskInherited(tasks: TaskInherited
.of(this.context)
.tasks, child: const TaskFormScreen()),
),
);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: ...,
body: ...,
floatingActionButton: FloatingActionButton(
heroTag: "addTaskButton",
onPressed: onFloatingActionButtonPressed,
child: Icon(Icons.add),
),
);
}
}
Por fim, estabeleço todas as ligações à tela anterior utilizando também o pushReplacement
, pois preciso recriar a árvore de Widgets instanciando um novo TaskInherited, e também repassando a mesma lista de tarefas do contexto. Adiciona-se uma tarefa através do mesmo contexto.
class _TaskFormScreenState extends State<TaskFormScreen> {
...
onFormButtonPressed() {
...
TaskInherited.of(context).addTask(
_nameController.text,
_imageController.text,
int.parse(_difficultyController.text),
);
...
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder:
(context) => TaskInherited(
tasks: TaskInherited.of(this.context).tasks,
child: const TaskScreen(),
),
),
);
}
onAppBarButtonPressed() => Navigator.pushReplacement(
context,
MaterialPageRoute(
builder:
(context) => TaskInherited(
tasks: TaskInherited.of(this.context).tasks,
child: TaskScreen(),
),
),
);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
leading: IconButton(
onPressed: onAppBarButtonPressed,
...
),
...
),
body: Form(
key: _taskFormKey,
child: Center(
child: SingleChildScrollView(
child: Container(
...
child: Column(
...
children: [
...
Padding(
...
child: FilledButton(
onPressed: onFormButtonPressed,
...
),
...
),
),
],
),
),
),
),
),
);
}
}