Thuta Learning
ProjectsMobile Developmentbeginner

Mini Project: Habit Tracker

Relax. We'll talk through this in plain words — no textbook voice.

In this mini project, we'll build a simple Habit Tracker UI. Users can enter a habit name and tap Add, see habits listed, and tap one to increase its completed count. This project lets you practice TextField, Button, List, setState, and basic layout all in one place.

dart
class HabitTracker extends StatefulWidget {
  const HabitTracker({super.key});

  @override
  State<HabitTracker> createState() => _HabitTrackerState();
}

class _HabitTrackerState extends State<HabitTracker> {
  final controller = TextEditingController();
  final List<Map<String, dynamic>> habits = [];

  void addHabit() {
    final name = controller.text.trim();

    if (name.isEmpty) return;

    setState(() {
      habits.add({'name': name, 'done': 0});
      controller.clear();
    });
  }

  void completeHabit(int index) {
    setState(() {
      habits[index]['done']++;
    });
  }

  @override
  void dispose() {
    controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Habit Tracker')),
      body: Padding(
        padding: const EdgeInsets.all(16),
        child: Column(
          children: [
            TextField(
              controller: controller,
              decoration: const InputDecoration(
                labelText: 'New habit',
                border: OutlineInputBorder(),
              ),
            ),
            const SizedBox(height: 12),
            ElevatedButton(
              onPressed: addHabit,
              child: const Text('Add Habit'),
            ),
            const SizedBox(height: 20),
            Expanded(
              child: ListView.builder(
                itemCount: habits.length,
                itemBuilder: (context, index) {
                  final habit = habits[index];

                  return Card(
                    child: ListTile(
                      title: Text(habit['name']),
                      subtitle: Text("Completed: ${habit['done']} times"),
                      trailing: const Icon(Icons.check_circle_outline),
                      onTap: () => completeHabit(index),
                    ),
                  );
                },
              ),
            ),
          ],
        ),
      ),
    );
  }
}
You should see
The Habit Tracker screen appears, letting you add new habits. Every tap on a habit card increases its Completed count.

Next Steps

You can keep expanding this project by adding a delete button, a completed filter, a local database, notification reminders, or a dark mode toggle.

Easy traps

  • Putting a ListView inside a Column without Expanded can cause a height constraint error. Consider using Expanded/Flexible for scrollable widgets inside a Column.