Liste de tâches : Annuler une suppression
Fait partie de la section Projets du Journey Flutter de Coddy. Leçon 7 sur 36.
Un balayage est rapide, et un balayage accidentel aussi. Les bonnes applications vous permettent de revenir en arrière : un message en bas indique ce qui a été supprimé, avec un bouton Annuler à côté.
Un SnackBar prend un action:, un SnackBarAction avec un label et un onPressed. Pour remettre la tâche à sa place, mémorisez sa position avant de la supprimer :
final index = _tasks.indexOf(task);
// supprime-le, puis affiche la SnackBar
SnackBarAction(
label: 'Undo',
onPressed: () {
setState(() {
_tasks.insert(index, task);
});
},
)Si vous balayez rapidement deux tâches, le deuxième message attend que le premier disparaisse. Appelez ScaffoldMessenger.of(context).hideCurrentSnackBar(); avant showSnackBar, afin que le message le plus récent s’affiche immédiatement.
insert(index, task) remet la tâche à cette position et décale vers le bas celles qui la suivent. add la placerait à la fin.
La fonction que vous transmettez à onPressed mémorise index et task tels qu’ils étaient au moment où vous l’avez créée, même si elle s’exécute plus tard. C’est une fermeture, sur laquelle les fonctions de rappel s’appuient constamment.
Défi
MoyenPermettez d’annuler une suppression. Dans _deleteTask :
- avant de supprimer la tâche, conservez sa position avec
indexOf - après l’avoir supprimée, affichez une
SnackBaravec le texteDeletedet le titre de la tâche, commeDeleted Walk the dog - ajoutez une action
Undoqui remet la tâche à son ancienne position - masquez d’abord le message affiché, afin qu’une nouvelle suppression le remplace
Essayez vous-même
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.teal),
),
home: const TodoScreen(),
);
}
}
class Task {
Task(this.title);
final String title;
bool done = false;
}
class TodoScreen extends StatefulWidget {
const TodoScreen({super.key});
@override
State<TodoScreen> createState() => _TodoScreenState();
}
class _TodoScreenState extends State<TodoScreen> {
final List<Task> _tasks = [Task('Buy milk'), Task('Walk the dog'), Task('Read a book')];
final _controller = TextEditingController();
int get _left => _tasks.where((task) => !task.done).length;
void _addTask() {
final title = _controller.text.trim();
if (title.isEmpty) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(content: Text('Type a task first')),
);
return;
}
setState(() {
_tasks.add(Task(title));
});
_controller.clear();
}
void _deleteTask(Task task) {
setState(() {
_tasks.remove(task);
});
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('My Tasks')),
body: Column(
children: [
Padding(
padding: const EdgeInsets.fromLTRB(16, 16, 16, 8),
child: Row(
children: [
Expanded(
child: TextField(
controller: _controller,
decoration: const InputDecoration(
labelText: 'New task',
border: OutlineInputBorder(),
),
),
),
const SizedBox(width: 8),
IconButton.filled(
onPressed: _addTask,
icon: const Icon(Icons.add),
),
],
),
),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8),
child: Row(
children: [
Text(
_left == 1 ? '1 task left' : '$_left tasks left',
style: Theme.of(context).textTheme.titleSmall,
),
],
),
),
Expanded(
child: ListView.builder(
itemCount: _tasks.length,
itemBuilder: (context, index) {
final task = _tasks[index];
return Dismissible(
key: ObjectKey(task),
direction: DismissDirection.endToStart,
background: Container(
color: Colors.red,
alignment: Alignment.centerRight,
padding: const EdgeInsets.symmetric(horizontal: 24),
child: const Icon(Icons.delete, color: Colors.white),
),
onDismissed: (direction) => _deleteTask(task),
child: ListTile(
leading: Checkbox(
value: task.done,
onChanged: (value) {
setState(() {
task.done = value!;
});
},
),
title: Text(
task.title,
style: task.done
? const TextStyle(
decoration: TextDecoration.lineThrough,
color: Colors.grey,
)
: null,
),
),
);
},
),
),
],
),
);
}
}
Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.
Toutes les leçons de Projets
1Projet : Liste de tâches
Liste de tâches : La liste des tâchesListe de tâches : Ajouter une tâche4Projet : Suivi des habitudes
Suivi des habitudes : Vos habitudesSuivi des habitudes : La semaineEntraînez-vous par vous-même : Compilateur Flutter en ligne