Habit Tracker App Using Flutter



In this tutorial, we'll be creating a Habit Tracker App application in Flutter,

Habit app are essential app for keeping Habits and staying organized. Our app creates a scrollable Habit list , allowing users to save Habit via a text field. Habits are dynamically displayed within containers and checkboxes. Users can scroll through the list as needed. Users can edit , delete their Habit details on ticking the checkboxes. By the end of this tutorial, you'll have a functional Habit List app that you can run on both Android and iOS devices.


Source Code for the main.dart file




Add the following Code inside your main.dart file :


             
import 'package:flutter/material.dart';
import 'home_page.dart';

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

class MyApp extends StatelessWidget {
    const MyApp({super.key});

    // This widget is the root of your application.
    @override
    Widget build(BuildContext context) {
    return MaterialApp(
        debugShowCheckedModeBanner: false,
        home: HomePage(),
        theme: ThemeData(primarySwatch: Colors.green)
    );
    }
}
             
             
            


Source Code for the home_page.dart file




Add the following Code inside your home_page.dart file :


             
import 'package:flutter/material.dart';
import 'habit_tile.dart';
class HomePage extends StatefulWidget {
    const HomePage({super.key});

    @override
    State< HomePage> createState() => _HomePageState();
}

class _HomePageState extends State< HomePage> {
    final _newHabitNameController = TextEditingController();
    List todayHabitList = [
    ["Morning Run", false],
    ["Gym", false]
    ];


    // open habit settings to edit
    void openHabitSettings(int index) {
    showDialog(
        context: context,
        builder: (context) {
        return AlertDialog(
            content: TextField(
            controller: _newHabitNameController,
            style: const TextStyle(color: Colors.black),
            decoration: InputDecoration(
                hintText: 'Enter new Habit....',
                hintStyle: TextStyle(color: Colors.grey[600]),
                enabledBorder: const OutlineInputBorder(
                    borderSide: BorderSide(color: Colors.black)),
                focusedBorder: const OutlineInputBorder(
                    borderSide: BorderSide(color: Colors.black)),
            ),
            ),
            actions: [
            MaterialButton(
                onPressed: (){
                saveExistingHabit(index);
                },
                child: Text(
                "Update",
                style: TextStyle(color: Colors.white),
                ),
                color: Colors.green[600],
            ),
            MaterialButton(
                onPressed: (){
                cancelDialogBox();
                },
                child: Text(
                "Cancel",
                style: TextStyle(color: Colors.white),
                ),
                color: Colors.green[600],
            ),
            ],
        );

        },
    );
    }

    // save existing habit with a new name
    void saveExistingHabit(int index) {
    setState(() {
        todayHabitList[index][0] = _newHabitNameController.text;
    });
    _newHabitNameController.clear();
    Navigator.pop(context);

    }

    // delete habit
    void deleteHabit(int index) {
    setState(() {
        todayHabitList.removeAt(index);
    });

    }

    void saveNewHabit() {
    // add new habit to todays habit list
    setState(() {
        todayHabitList.add([_newHabitNameController.text, false]);
    });

    // clear textfield
    _newHabitNameController.clear();
    // pop dialog box
    Navigator.of(context).pop();

    }

    // cancel new habit
    void cancelDialogBox() {
    // clear textfield
    _newHabitNameController.clear();
    // pop dialog box
    Navigator.of(context).pop();
    }

void createnewhabit(){
    showDialog(context: context, builder: (context){
    return
        AlertDialog(
        content: TextField(
            controller: _newHabitNameController,
            style: const TextStyle(color: Colors.black),
            decoration: InputDecoration(
            hintText: 'Enter new Habit....',
            hintStyle: TextStyle(color: Colors.grey[600]),
            enabledBorder: const OutlineInputBorder(
                borderSide: BorderSide(color: Colors.black)),
            focusedBorder: const OutlineInputBorder(
                borderSide: BorderSide(color: Colors.black)),
            ),
        ),
        actions: [
            MaterialButton(
            onPressed: (){
                saveNewHabit();
            },
            child: Text(
                "Save",
                style: TextStyle(color: Colors.white),
            ),
            color: Colors.green[600],
            ),
            MaterialButton(
            onPressed: (){
                cancelDialogBox();
            },
            child: Text(
                "Cancel",
                style: TextStyle(color: Colors.white),
            ),
            color: Colors.green[600],
            ),
        ],
        );

    },
    );
}

    void checkBoxtapped(bool? value, int index){
    setState(() {

        todayHabitList[index][1]=value;

    });
    }


    @override
    Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
        backgroundColor: Colors.green,
        title: Text('My Habits'),
        centerTitle: true,
        ),

        backgroundColor: Colors.grey[300],
        floatingActionButton: FloatingActionButton(
            onPressed: (){
                createnewhabit();
            },
            child: Icon(Icons.add)
        ),
        body: ListView.builder(
        itemCount: todayHabitList.length,
            itemBuilder: (context,index){

        return HabitTile(
            habitName: todayHabitList[index][0],
            habitCompleted: todayHabitList[index][1],
            onChanged: (value){
            checkBoxtapped(value, index);
            },
            settingsTapped: (context){
            openHabitSettings(index);
            },
            deleteTapped: (context){
                deleteHabit(index);
            },
            );
        })
    );
    }
}
                
             
             
            


Source Code for the habit_tile.dart file




Add the following Code inside your habit_tile.dart file :


             
import 'package:flutter/material.dart';
import 'package:flutter_slidable/flutter_slidable.dart';

class HabitTile extends StatefulWidget {

    final String habitName;
    final bool habitCompleted;
    final Function(bool?)? onChanged;
    final Function(BuildContext)? settingsTapped;
    final Function(BuildContext)? deleteTapped;

    const HabitTile({super.key, required this.habitName, required this.habitCompleted, required this.onChanged,
    required this.settingsTapped,
    required this.deleteTapped,});

    @override
    State< HabitTile> createState() => _HabitTileState();
}

class _HabitTileState extends State< HabitTile> {
    @override
    Widget build(BuildContext context) {
    return Padding(
        padding: const EdgeInsets.all(16.0),
        child: Slidable(
        endActionPane: ActionPane(
            motion: StretchMotion(),
            children: [
            SlidableAction(
                onPressed: widget.settingsTapped,
                backgroundColor: Colors.grey.shade800,
                icon: Icons.settings,
                borderRadius: BorderRadius.circular(12),
            ),

            // delete option
            SlidableAction(
                onPressed: widget.deleteTapped,
                backgroundColor: Colors.red.shade400,
                icon: Icons.delete,
                borderRadius: BorderRadius.circular(12),
            ),
            ],
        ),
        child: Container(
            padding: EdgeInsets.all(24),
            decoration: BoxDecoration(
            color: Colors.grey[100],
            borderRadius: BorderRadius.circular(16)
            ),
            child: Row(
            children: [
Checkbox(value:widget.habitCompleted,
    onChanged: widget.onChanged
),
                Text(widget.habitName,style: TextStyle(
                fontSize: 17
                ),),
            ],
            ),
        ),
        ),
    );
    }
}
                
                
             
             
            


The Output is shown below :








Contact Us

REACH US

SERVICES

  • CODING
  • ON-LINE PREPARATION
  • JAVA & PYTHON

ADDRESS

B-54, Krishna Bhawan, Parag Narain Road, Near Butler Palace Colony Lucknow
Contact:+ 919839520987
Email:info@alexsir.com