Part 1 - TODO app UI building using Flutter
Tags: flutter, tutorial, dart, ui
Published: 2020-12-25 12:36:20

## 👋 Everyone! 

Welcome to the 1st part of the Flutter TODO app-building series. In this article, we are going to build the main screen on which all the TODOs from a user are shown.

To know more about the project you can go to [Introduction article](https://dev.to/siruswrites/flutter-todo-app-series-introduction-kdp).

This article is complementary to the video series on YouTube, so if you are more of a video person then you can go and watch the video 👇👇
{% youtube 0_3jWthag98 %}

### Breaking The UI Into Parts. 

| How a user will look at it | How a DEV should look at it |
|--|--|
| ![Normal View](https://dev-to-uploads.s3.amazonaws.com/i/5lq7eml9xwzdujwws13r.jpg) | ![DEV View](https://dev-to-uploads.s3.amazonaws.com/i/vyjw0o4qief4prxijzun.jpg)| 

Each part is marked with a number and I have explained what they are and which widget I have used in Flutter.

So as you can see that we have  [`Scaffold`](https://api.flutter.dev/flutter/material/Scaffold-class.html)  as the parent and then we have `appBar`, `body`, and `floatingActionButton`.

1. We have an `AppBar` in which we have a `title` property which is a type of `Widget` so we use a `Text` widget.
2. On the trailing(actions) side of the `AppBar` we have an `IconButton` which on clicking will log the user out of the app.
3. Moving to `body` we can see that the date button and our TODO list are vertically aligned, so which widget we can use for this? Yes, you have guessed it right we are going to use a `Column` so the first child is a simple `TextButton` (Added in Flutter 1.22).
4. Next child in our `Column` will be `ListView` to be specific as we are going to add data dynamically so we need to use a `ListView.builder` (This works like a `RecyclerView` in Android).
5. Inside our `ListView.builder` each child is a `Dismissible` so that the user can dismiss them to delete. `Card` is the child of it which gives it an aesthetic look and child is a `ListTile`.
6. Getting to `ListTile` we have `title` which also takes the type of `Widget` so again we are using a `Text` widget.
7. Just below the title we have a description and date of creation. `ListTile` also has a property for this which is `subtitle` again you have guessed it we need a `Widget` but this time we are going to pass a `Column` not a `Text` widget because we need to have them vertically aligned. Next in `Column`, we have 2 `Text` widget that is for description and date of creation.
8. To the left end we have an Icon, to get this we add `leading` in `ListTile` that is an `IconButton`.
9. To the right end we have again an icon but this time it is a simple `Icon` which is in the `trailing` of `ListTile` position. 
10. Finally we have a `FloatingActionButton` with an `Icon` as a child.

Oof, this was so looonnng!!, now that you can read the UI we can start building it!! 🎉

### It's CODE TIME!!!

First of all, we are going to start by making a `StatefulWidget`.
```dart
class TODOScreen extends StatefulWidget {
  TODOScreen({Key key}) : super(key: key);

  @override
  _TODOScreenState createState() => _TODOScreenState();
}

class _TODOScreenState extends State<TODOScreen> {
  @override
  Widget build(BuildContext context) {
    // We are going to start building here
  }
}
```

Then we can work on `Scaffold`
```dart
return Scaffold(
      appBar:    // This is where we are going to add our `AppBar`, 
      body:    // This is where most of the code will go,
      floatingActionButton:   // This is where we will add `FloatingActionButton`,
);
```

For the `AppBar` we will have a title property and also in `action` we will have `IconButton` for logout
```dart
appBar: AppBar(
  title: Text("My TODO app"),
  actions: [
    IconButton(
      onPressed: () {},
      icon: Icon(Icons.exit_to_app),
    )
  ],
),
```

In the `body`, we have `Column` which contains `TextButton` and `ListView.builder`.
```dart
body: Column(
  children: <Widget>[
    // Here we will have `TextButton` and `ListView.builder`
  ],
),
```

For time being we can just make a simple button with a Placeholder text, then we can work on logic and show the actual date.
```dart
TextButton(
      onPressed: () {},   // Here we will call `DatePicker`
      child: Text("Date"),    // In place of "Date" we will add the date which is selected
),
```

Below the button, we have our `ListView.builder`
> We need to make `shrinkWrap` as `true` in `ListView.builder` since it is inside a `Column` otherwise this will shower you with errors (I hope you don't like them😉) and will make `itemCount` as 3.

```dart
ListView.builder(
      shrinkWrap: true,
      itemCount: 3,
      itemBuilder: (context, index) {
            // Here we have to return our list item
      },
)
```

To make our Tasks(items in `ListView.builder`) have swipe to delete we need to start by wrapping it with a `Dismissible` which will give us properties such as `direction` to select the direction of dismissing, `background` which is stacked behind the `child` of `Dismissible` and only show up when the child is swiped.
```dart
Dismissible(
  // This should be unique for each item hence we are using index
  key: ValueKey(index),  
  // As written above this will be stacked behind the `child`
  background: Container( 
    alignment: Alignment.centerLeft,
    color: Colors.red,
    child: Padding(
      padding: const EdgeInsets.all(8.0),
      child: Icon(Icons.delete),
    ),
  ),
  direction: DismissDirection.startToEnd,  // Only allow to swipe in reading direction
  child:   // Widget which is actually shown on screen
);
```

For the `child` we are going to have a `Card` -> `ListTile` then we can add:
- `title` which will show task title
- `subtitle` which will be a `Column` and have task description and created date
- `leading` which will be an `IconButton` to show which task is completed and mark a task as completed
- `trailing` which will be an `Icon`
```dart
Card(
  child: ListTile(
    leading: IconButton(
      onPressed: () {},
      icon: Icon(Icons.check_circle_outline_outlined),
    ),
    trailing: Icon(Icons.arrow_forward_ios),
    title: Text("Title"),
    subtitle: Column(
      crossAxisAlignment: CrossAxisAlignment.start,
      children: <Widget>[
        Text("Desc"),
        Text("Date"),
      ],
    ),
  ),
),
```

![The issue](https://dev-to-uploads.s3.amazonaws.com/i/sg861rh2u3j3jzeduzl3.png)
What you can see on your screen?... Yes, this looks kinda weird, Let's fix it.
To fix it first we need to remove the default margin from `Card`.
```dart
Card(
  margin: const EdgeInsets.all(0.0),
  .
  .
),
```

![Now card are sticking to each other](https://dev-to-uploads.s3.amazonaws.com/i/jlxti9nyegrsqnoaihrf.png)
Now cards are sticking to each other. This could be easily solved by wrapping `Padding` around `Dismissible`.
```dart
return Padding(
  padding: const EdgeInsets.all(8.0),
  child: Dismissible(
  .
  ),
),
```


![Completed](https://dev-to-uploads.s3.amazonaws.com/i/kzwmu7apop61kfk2d24m.png)
Yes, this looks much better😍

Finally, we can work on our `FloatingActionButton`!  It has a single child which is an `Icon`.
```dart
floatingActionButton: FloatingActionButton(
  onPressed: () {},
  child: Icon(Icons.add),
),
```

Congratulations you have completed your UI building!! 🎉🥳

### Adding Some Logic

Now we can add some logic to change the date which was in the `TextButton`.

Remember I told you that in place of "Date" we can put the actual date? Now we are going to work on that.

Let's start by making an instance variable in our `State` class and initializing it with `DateTime.now()` which will assign it today's date.
```dart
DateTime _date = DateTime.now();
```

Now we need to format our `_date` variable and show it to users. For this, we are going to use a package from [pub.dev](https://pub.dev/) named [intl](https://pub.dev/packages/intl) into `pubspec.yaml`.
```yaml
dependencies:
  # Other dependencies
  intl: ^0.16.1
```
`intl` gives us a lot of formatting options you can look at them by yourselves over [here](https://pub.dev/packages/intl).

For formatting date, we are going to pass `_date` to `format` method from `DateFormat` class which will format it.
We can now replace the "Date" with it so the user will get a clear idea of which tasks are for user on which date.
 ```dart
TextButton(
  onPressed: () {},
  child: Text(
    DateFormat("dd/MM/yyyy").format(_date).toString(),
  ),
),
```

Now as the user can see the date they also might want to change, so we are going to implement a date picker in it. As `material` library already gives a date picker we are going to use that. For that, we will make another method in our `class`.
```dart
_showDatePicker() async {
  // To make a variable with today's date as we are going to use it a lot of time
  final today = DateTime.now(); 
  // This will return a `Future<DateTime>` hence we are awaiting it.
  final selectedDate = await showDatePicker(  
    context: context,  // We get it from the `State` class
    initialDate: _date,  // This is the date which is selected in the date picker
    firstDate: DateTime(2020, 11, 1),  // This is the start range in date picker which is selectable
    lastDate: DateTime(today.year + 1, today.month, today.day),  // This is the end range in date picker which is selectable
  );
  // if user have selected any date and selected date and current date
  // is not same then update the date and update the UI
  if (selectedDate != null && selectedDate != _date) {
    setState(() {
      _date = selectedDate;
    });
  }
}
```

As we have written the method `_showDatePicker()` we can call it when the user clicks on the Button.
```dart
TextButton(
  onPressed: () {
    _showDatePicker();
  },
  child: Text(
    DateFormat("dd/MM/yyyy").format(_date).toString(),
  ),
),
```

Woah you have completed your first screen!! 🎉

You can go over [here](https://github.com/CodeVengersTeam/Flutter-TODO-Tutorial/tree/UI-building-part-1) to see the whole code.

Thanks for reading, if you wish you can also join our community on [Discord](https://discord.gg/tzk695K3).

See you soon! 👋 Happy Fluttering.