Menu
CoddyTech

Danh sách việc cần làm: Đánh dấu hoàn thành

Thuộc phần Dự án trong hành trình Flutter của Coddy. Bài học 3 trên 36.

Một công việc cần ghi nhớ xem nó đã hoàn thành chưa. Thêm cho lớp một trường thứ hai, ban đầu có giá trị false và có thể thay đổi, nên trường này không phải final:

class Task {
  Task(this.title);

  final String title;
  bool done = false;
}

Mỗi hàng có một Checkbox làm tiện ích leading:. value của nó là done của công việc, còn onChanged đặt done bên trong setState.

Công việc đã hoàn thành nên trông như đã hoàn thành. TextDecoration.lineThrough kẻ một đường xuyên qua văn bản, còn màu xám giúp văn bản trông mờ hơn. Khi công việc chưa hoàn thành, kiểu hiển thị là null và văn bản giữ nguyên giao diện theo chủ đề:

style: task.done
    ? const TextStyle(decoration: TextDecoration.lineThrough, color: Colors.grey)
    : null,
challenge icon

Thử thách

Trung bình

Đánh dấu các nhiệm vụ đã hoàn thành:

  • thêm bool done = false; vào Task
  • thêm một Checkbox ở leading: cho mỗi ListTile để hiển thị và thay đổi trạng thái done của nhiệm vụ
  • khi nhiệm vụ hoàn thành, gạch ngang tiêu đề và đổi màu thành Colors.grey

Tự làm thử

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;
}

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(
                  title: Text(task.title),
                );
              },
            ),
          ),
        ],
      ),
    );
  }
}
quiz iconTự kiểm tra

Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.

Tất cả bài học trong Dự án

Tự luyện tập: Trình biên dịch Flutter online