Creating a Habit Tracker app using Flutter
Tags: beginners, productivity, programming, flutter
Published: 2024-01-27 17:43:45

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:

```yaml
dependencies:
  flutter:
    sdk: flutter
  provider: ^5.0.2
  shared_preferences: ^2.0.10
```

Run `flutter pub get` to fetch the dependencies.

2. Create a `Habit` class to represent a habit:

```dart
class Habit {
  final String name;
  bool isCompleted;

  Habit(this.name, this.isCompleted);
}
```

3. Create a `HabitProvider` using the `provider` package for state management:

```dart
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();
  }
}
```

4. Create the main app:

```dart
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(),
      ),
    );
  }
}
```

5. Implement the `HabitTrackerScreen`:

```dart
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'),
            ),
          ],
        );
      },
    );
  }
}
```

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.