רשימת משימות: משימות שנותרו
חלק מהיחידה פרויקטים במסלול ה-Flutter של Coddy. שיעור 4 מתוך 36.
מבט במסך אמור להבהיר לך כמה עוד נשאר לעשות. התשובה היא מספר המשימות שטרם הושלמו, ואפשר לחשב אותו מהרשימה בכל פעם שהמסך נבנה.
זה המקום למגדיר מאפיין. הוא נקרא כמו שדה, אבל מריץ את הקוד שלו בכל פעם שמשתמשים בו, כך שהוא תמיד מעודכן:
int get _left => _tasks.where((task) => !task.done).length;אין משתנה נוסף שצריך לשמור מסונכרן, ואין setState משלו: סימון משימה כבר קורא ל-setState, המסך נבנה מחדש, והמגדיר סופר שוב.
פרט אחד גורם לניסוח להישמע טבעי: "1 task left" ולא "1 tasks left". תנאי בוחר את המילים המתאימות.
אתגר
בינוניהצג כמה משימות נותרו:
- הוסף getter בשם
_leftשסופר את המשימות שלא הושלמו - הצג אותו בין השדה לרשימה, בתוך
Textכגון3 tasks left, בתוךRowעם ריפוד של 16 פיקסלים בצדדים ו־8 למעלה ולמטה - כשנותרה בדיוק משימה אחת, הצג
1 task left
נסו בעצמכם
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();
void _addTask() {
setState(() {
_tasks.add(Task(_controller.text));
});
_controller.clear();
}
@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),
),
],
),
),
Expanded(
child: ListView.builder(
itemCount: _tasks.length,
itemBuilder: (context, index) {
final task = _tasks[index];
return 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,
),
);
},
),
),
],
),
);
}
}
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה פרויקטים
תרגלו בעצמכם: קומפיילר Flutter אונליין