DEV Community

Nikhil Soman Sahu
Nikhil Soman Sahu

Posted on

1

Creating a Habit Tracker app using Flutter

Creating a Habit Tracker app using Flutter involves designing the user interface, managing state, and implementing functionality to track and visualize habits. Below is a simple example to get you started. This example uses the provider package for state management.

  1. First, add the necessary dependencies to your pubspec.yaml file:
dependencies:
  flutter:
    sdk: flutter
  provider: ^5.0.2
  shared_preferences: ^2.0.10
Enter fullscreen mode Exit fullscreen mode

Run flutter pub get to fetch the dependencies.

  1. Create a Habit class to represent a habit:
class Habit {
  final String name;
  bool isCompleted;

  Habit(this.name, this.isCompleted);
}
Enter fullscreen mode Exit fullscreen mode
  1. Create a HabitProvider using the provider package for state management:
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences/shared_preferences.dart';

class HabitProvider extends ChangeNotifier {
  List<Habit> habits = [];

  HabitProvider() {
    _loadHabits();
  }

  void _loadHabits() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    List<String>? habitNames = prefs.getStringList('habits');

    if (habitNames != null) {
      habits = habitNames.map((name) {
        bool isCompleted = prefs.getBool(name) ?? false;
        return Habit(name, isCompleted);
      }).toList();

      notifyListeners();
    }
  }

  void addHabit(String habitName) async {
    habits.add(Habit(habitName, false));
    _saveHabits();
  }

  void toggleHabit(int index) {
    habits[index].isCompleted = !habits[index].isCompleted;
    _saveHabits();
  }

  void _saveHabits() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    prefs.setStringList('habits', habits.map((habit) => habit.name).toList());

    habits.forEach((habit) {
      prefs.setBool(habit.name, habit.isCompleted);
    });

    notifyListeners();
  }
}
Enter fullscreen mode Exit fullscreen mode
  1. Create the main app:
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider(
      create: (context) => HabitProvider(),
      child: MaterialApp(
        title: 'Habit Tracker',
        theme: ThemeData(
          primarySwatch: Colors.blue,
        ),
        home: HabitTrackerScreen(),
      ),
    );
  }
}
Enter fullscreen mode Exit fullscreen mode
  1. Implement the HabitTrackerScreen:
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

class HabitTrackerScreen extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Habit Tracker'),
      ),
      body: Consumer<HabitProvider>(
        builder: (context, habitProvider, child) {
          return ListView.builder(
            itemCount: habitProvider.habits.length,
            itemBuilder: (context, index) {
              final habit = habitProvider.habits[index];
              return ListTile(
                title: Text(habit.name),
                trailing: Checkbox(
                  value: habit.isCompleted,
                  onChanged: (value) {
                    habitProvider.toggleHabit(index);
                  },
                ),
              );
            },
          );
        },
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          _addHabitDialog(context);
        },
        child: Icon(Icons.add),
      ),
    );
  }

  void _addHabitDialog(BuildContext context) {
    TextEditingController habitController = TextEditingController();

    showDialog(
      context: context,
      builder: (BuildContext context) {
        return AlertDialog(
          title: Text('Add a Habit'),
          content: TextField(
            controller: habitController,
            decoration: InputDecoration(labelText: 'Habit name'),
          ),
          actions: <Widget>[
            TextButton(
              onPressed: () {
                Navigator.of(context).pop();
              },
              child: Text('Cancel'),
            ),
            TextButton(
              onPressed: () {
                Navigator.of(context).pop();
                Provider.of<HabitProvider>(context, listen: false)
                    .addHabit(habitController.text);
              },
              child: Text('Add'),
            ),
          ],
        );
      },
    );
  }
}
Enter fullscreen mode Exit fullscreen mode

In this example, the HabitProvider class is responsible for managing the state of the habits, loading habits from and saving habits to SharedPreferences. The HabitTrackerScreen widget displays a list of habits and allows users to add new habits. The state management is handled using the provider package.

Feel free to customize and expand upon this example to fit the specific requirements of your Habit Tracker app.

Sentry blog image

The countdown to March 31 is on.

Make the switch from app center suck less with Sentry.

Read more

Top comments (1)

Collapse
 
paulkbryant profile image
PaulKBryant
Comment hidden by post author

Some comments have been hidden by the post's author - find out more

The Most Contextual AI Development Assistant

Pieces.app image

Our centralized storage agent works on-device, unifying various developer tools to proactively capture and enrich useful materials, streamline collaboration, and solve complex problems through a contextual understanding of your unique workflow.

👥 Ideal for solo developers, teams, and cross-company projects

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay