Sincerest Form of ‘Fluttery’

Jackie Moraa
4 min readDec 3, 2021

--

Last week I talked a little about my struggles with widgets and nesting. In case you missed that post, you can catch up on it here.

This week, in the spirit of continuous practice in the hope of becoming a Flutter guru whizz mad genius scientist, I tried putting some of the learnings from nesting Flutter widgets to the test. I did this by simply imitating an already existing application — gmail. Not the entire gmail. Just this snippet shown in the screenshot below.

Can we schedule time to talk about the threats from Duo? 😂

But before we can delve deep into the layout, how I broke it down and finally implemented it, we would need to understand rows and columns — the widgets (remember, everything is a widget) that made all this possible.

Rows and columns are low level Flutter widgets for horizontal and vertical layouts. A row widget will arrange its children horizontally while a column widget will arrange them… you guessed it… vertically. A child of a row or column can also be another row or column. Thus, nesting. These two are the most commonly used layout patterns but there are other higher level patterns you can employ.

You control how a row or column aligns its children using the mainAxisAlignment and crossAxisAlignment properties. For a row, the main axis runs horizontally and the cross axis runs vertically. For a column, the main axis runs vertically and the cross axis runs horizontally.

Thus, when you need to place widgets side by side, you will need rows.
When you need to place them top to bottom, you will need columns.

So, let’s layout our design!

Gmail inbox imitation — layout sketch

This is what I came up with as shown above:
Container: which will be a column (has two children)
> Row 1
>>Child: Text widget
> Row 2 (has three children)
>> Child: Image (3)
>> Child: Column (4) (has three children)
>>> Child: Row (6) Text
>>> Child: Row (7) Text
>>> Child: Row (8) Text
>> Child: Column (5) (has two children)
>>> Child: Row (9) Text
>>> Child: Row (10) Icon

Now, let’s build it!

If you would be building with me, have a look at this great post by Pranesh Prashar that will take you through the initial steps of writing your first Flutter app. When you have set up the project, the dependencies, the main Run function and the MaterialApp, create the widget classes that will hold our layouts.

The first class I created is the inbox class. Which contained the two rows.

class MyInbox extends StatelessWidget {
const MyInbox({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text("Gmail Inbox"),
leading: const Icon(Icons.menu),
), // AppBar
body: Column(
children: [
const NotificationText(), //first row 1
InboxSection(), //second row 2
],
), // Column
); // Scaffold
}
}

The NotificationText class is a simple class as it only contains one text widget.

class NotificationText extends StatelessWidget {
const NotificationText({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return const Text('Notificaciones');
}
}

The InboxSection class on the other hand has a lot of nested widgets for the rows and columns.

class InboxSection extends StatelessWidget {@override
Widget build(BuildContext context) {
return Row(
children: [
const CircleAvatar(
backgroundImage: NetworkImage(
'https://res.cloudinary.com/crunchbase- production/image/upload/c_lpad,h_170,w_170,f_auto,b_white,q_auto:eco,dpr_1/gavygdwhilk8d2cytkeq'),
radius: 24.0,
),
Column(
children: const [
Text('Duolingo'),
Text('Hi Nairobi, time for Spanish! Keep you...'),
Text('Learning a language requires practice'),
],
),
Column(
children: const [
SizedBox(
child: SizedBox(
child: Text('21:20'),
),
),
Icon(Icons.star_border),
],
),
],
);
}
}

This is what we get when we run the code as is. Pretty bland and meh. No style, just vibes.

Gmail inbox imitation — first iteration

Let me attempt to add some style. 🤞🏾

I went ahead to add a couple of paddings and the mainAxisAlignment and crossAxisAlignment properties for proper spacing and alignment of the widgets. Shown in the code snippet below:

lib/main.dart

And when we ran that, this is our result:

Gmail inbox imitation — end result

Close? I think for our first try, it’s not so bad. Yes? No? However, it’s not lost on me that the execution can be cleaner. I have probably butchered some Flutter best practices and layout standards over here. So, with that said, if you have read this article and know a thing or two about Dart and Flutter, please feel free to share your critique. I highly welcome those. It’s the only way I can get better at this :)

View full source code on my GitHub account here.

‘Imitation is the sincerest form of flattery that mediocrity can pay to greatness.’ — Oscar Wilde

Once again, thank you for reading ❤

--

--

Jackie Moraa
Jackie Moraa

No responses yet