Making a basic weekly planner app using Flutter

Tanmay Choudhary
Geek Culture
Published in
7 min readNov 12, 2021

--

Photo by JESHOOTS.COM on Unsplash

Hey everyone! It’s been a long time since I wrote a blog on Flutter. So this time, I’ll show how I made a simple weekly planner app. I’ll show how to make a very basic version with the basic functionality. You can improve your app the way you want!

How will it work?

The user will be able to select a day of the week and a todo with a title and a description.

Let’s start

I will be using Android Studio as my editor and I’ll use an iOS simulator. I’ll make a new Flutter project and delete the default starter project. I’ll also delete the test folder. In my lib folder, I’ll make two folder: custom_widgets and pages . Inside pages let’s make a folder which will hold our home widget, home.dart. Let’s start by writing this code in main.dart:

In our home.dart let’s add this code that makes a basic scaffold and run our app:

Result:

Let’s add a day list which has items for every day of the week. We will use ListView.builder for this and a simple List<String> for storing the abreviations of the days of the week. In the custom_widgets folder let’s add a dart file called, horizontal_day_list.dart. In the file, let’s make a stateful widget called HorizontalDateList:

I want to change the card colour when clicked, which is why I made a List<List<Color>>. The first Color is the colour of the Container and the second colour is the colour of the text. We’ll add the functionality to change the card and text colour on click later.

Let’s import the file in home.dart and change the Container in the body to a Column. We’ll add two widgets:

Result:

Let’s add a Container below the list where all our todos will be displayed. Hence the entire home.dart page should look like this:

Take care to add the const modifiers in the correct place(I’ll change their positions as I update the code). This will give us something like this:

Let’s add a floating action button to add todos. We can modify the button to have the shape of a rounded rectangle with the same colour as the background and a large add icon:

Now let’s define a widget that will show all the todos we create in a grid view. In the custom_widget folder let’s create a file called todo_tile.dart that will have the title and the description of our todos. I will do this using a simple container with some decoration added and make the tile so that it requires a title and a description:

In home.dart let’s make a List<List<String>> that will hold the title and description of every todo_tile. We will pass this list to the TodoGridView widget to display all the todos:

List<List<String>> todoInformation = [];

In the custom_widget folder lets make a file named todo_grid_view.dart. This will hold the Tiles in a grid:

In home.dart lets define the child property for the container:

child: TodoGridView(todoList: todoInformation),

To test if this works, add a dummy todo in the list todoInformation:

List<List<String>> todoInformation = [
["Hello", "Hello"]
];

After pressing hot restart, this should be visible:

Now let’s implement the functionality to change the day of the week when pressing the weekdays on the top. To signify what day is active, we will change the color scheme of the list view object and then print the day that was clicked. We will also change a varible weekday that we will define in home.dart:

String weekday = "MON";

void changeWeekday(String newDay) {
setState(() {
weekday = newDay;
});
print("changed, $weekday");
}

We will add a function as we will detect the click using the HorizontalDayList but we want to update the variable globaly. There are other ways to do this, but I simply chose this method. In the horizontal_day_list.dart let’s add the code to change the color of the dates. We can do this by wrapping the Container widget inside the list view in a GestureDetector widget and then specifying onTap:

This will first set all the card colors to unselected and then make the tapped card selected. Again, there might be more efficient ways to do this, but this is how I did it. The widget should take in the changeWeekday function we defined before and run it. Let’s do that. First we’ll add the function in the constructor:

final Function dayUpdateFunction;

const HorizontalDayList({Key? key, required this.dayUpdateFunction}) : super(key: key);

Now let’s run the function after the setState in onTap:

widget.dayUpdateFunction(weekdays[index]);

After you perform hot restart and click on the days a few times, this is what should be visible in the console:

Let’s make some dummy todos first. Here are a few. Update the todoInformation using these:

List<String> todoInformation = [
"MON,TEST1,TEST1",
"WED,TEST2,TEST2",
"SUN,TEST3,TEST3",
"WED,TEST4,TEST4",
"FRI,TEST5,TEST5",
"THU,TEST6,TEST6",
"MON,TEST7,TEST7",
];

You might get an error here but that is because you have changed the list datatype and you haven’t made ammends in the grid view widget. Just change the datatype of the list in the constructor to List<String> and to access the title and description we can use the split function. Just return this in the itemBuilder:

TodoTile(title: widget.todoList[index].split(",")[1], description: widget.todoList[index].split(",")[2])

Now all those widgets should appear. But lets make them appear for a particular day only. Let’s make a list that stores the todo for the selected day and define a function that updates that list:

void updateList() {
dayDependentTodos.clear();
for (int i = 0; i < todoInformation.length; i++) {
if (todoInformation[i].split(",")[0] == weekday) {
dayDependentTodos.add(todoInformation[i]);
}
}
}

In the changeWeekday function lets add that function after the print statement:

void changeWeekday(String newDay) {
setState(() {
weekday = newDay;
});
print("changed, $weekday");

updateList();
}

In home.dart let’s change the list passed to the grid view from todoInformation to dayDependentTodos. And run hot restart.

First let’s make it so that after we open the app, the day of the week is automatically selected. To do that open the horizontal_day_list.dart file and let’s add a init function:

@override
void initState() {
super.initState();
SchedulerBinding.instance!.addPostFrameCallback((_) {
date = DateTime.now();
widget.dayUpdateFunction(weekdays[date.weekday - 1]);
updateDayColor(date.weekday - 1);
});
}

This will run the build function and then get the index number of the day of the week and then assign it. I have updated the code in the onTap in the GestureDetector to this:

onTap: () {
updateDayColor(index);
widget.dayUpdateFunction(weekdays[index]);
},

where the updateDayColor function is this:

void updateDayColor(int index) {
setState(() {
for (int i = 0; i < cardColorList.length; i++) {
cardColorList[i][0] = inactiveCardColor;
cardColorList[i][1] = inactiveTextColor;
}

cardColorList[index][0] = activeCardColor;
cardColorList[index][1] = activeTextColor;
});
}

I have also added late DateTime day; before defining the init function.

Now let’s add the mechanism to to add another todo by clicking the floating action button. In home.dart I have added 2 TextEdittingControllers like this:

TextEditingController titleController = TextEditingController();
TextEditingController descriptionController =
TextEditingController();

I also made a function to show a snackbar incase of an invalid input:

void showInSnackBar(String value) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text(
value,
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 20,
color: Colors.redAccent),
)
)
);
}

In the onPressed parameter of the FloatingActionButton let’s add the function to add a dialog box:

showDialog(
context: context,
builder: (context) {
return TodoInformationPopup(titleController: titleController,
descriptionController: descriptionController,);
}
)

We will define the TodoInformationPopup later. Since we are in home.dart let’s just add the code to define what will happen after exiting the dialog box:

The code should be self explanatory. We add the todo in the main list and then run updateList() to update the dayDependantTodo list. After that, we clear the two controllers. Now in custom_widgets make a dart file called todo_information_popup.dart. This will return a Dialog widget like this:

As you can see, it will have both the controllers as input. You can customise it the way you want it to. I’ll make mine like this:

I’ll post the code for this but, like I said in the beginning, feel free to play around with this:

Clicking anywhere other than the dialog box should exit from it and you will get a snackbar saying invalid input. Here is the final app:

Conclusion

So that’s it for this blog! You can continue the app and store the todos in a file in the phone’s documents folder so that you can access them whenever you want. I’ll link the github repo where I have included the code here so you might want to check that out.

If you liked this article press the clap button a couple of times. I write articles on programming and space, so if that interests you, check out my other articles.

Thanks for reading!

--

--

Tanmay Choudhary
Geek Culture

Space exploration, AI and Flutter enthusiast. Aspiring aerospace engineer.