Flutter V: Material Design II — [Flutter 1.0]

Chema Rubio
Dec 10, 2018 · 6 min read

Flutter offers lots of widgets in order to create user interfaces following Material Design principles that have been reviewed so far. Next step in this article series is providing the application with a detail view for each existing contact. To do so, how to manage user´s taps in a list, navigation among screens and more knowledge about widgets will be shared.

Updated to Flutter 1.0 — December 2018


Index

TIP: The whole Flutter series code is available in this repository.


Goal

Main goal for this article is creating a view similar to the following one:

Contact detail

A view in which the contact image shrinks when scrolling the contact information.

Contact Data

On previous tutorials we used service in order to show a lists containing name and an email for each contact. Implementing this new view will need more data to be parsed from RandomUser JSON response.

This changes are needed to be done inside contact_data.dart, now gender and image_url are obtained directly from the map.

Date attribute will be parsed as a String, to do so DateTime.parse will be used, then it will be formatted using DataFormat. If date format follows a pattern like 1983–07–14 07:29:45, it will be transformed into July 14, 1983.

To be able to use them, the following dependency must be added to pubspec.yaml:

intl: ^0.15.7

Then:

flutter packages get

Also two new classes were created so the contact is provided with more complex information such as location and phone numbers. Phone numbers will be defined as a list so several numbers may be shown in the contact detail view.

Contact Detail

Inside /lib/module/contacts folder, create a new file called contact_detail_view.dart that will contain the contact detail view logic.

To do so, let´s create three different widgets:

  • ContactPage: Page showing all the contact´s detail.
  • FlexibleAppBar: This will be a custom app bar containing a shrinkable image.
  • _ContactCategory: This one will be used so data may be separated, each personal data will contain one or more _ContactCategoryItem.
  • _ContactCategoryItem: Will be used to show a specific data item.

The following images explains how the resultant view will be made up from the described widgets.

Contact´s image will be shown in a shrinkable app bar. As this widget is expected to be reused in other views, it will be placed in a different file, not inside contact_detail_view.dart. Inside lib folder, create a new one called widget, inside this folder all custom widgets may be stored. Finally, create a file called app_bar.dart.

FlexibleAppBar extends SliverAppBar from Flutter SDK, SliverAppBar will be called using super inside the constructor. Super will take a size and a flexibleSpace. Flutter´s SliverAppBar already brings flexibleSpace attribute so a widget may be added to be shrinked and expanded.

This flexibleSpace is provided with a new FlexibleSpaceBar that has a title already following Material Design specifications. Talking about the background, it will be custom, made from an image and a gradient.

To build a widget for the background, Stack widget will be used. It is similar to Android´s FrameLayout.

With this widget a gradient will be placed over the image just in the place where the title will be drawn. Next image explains better the purpose of this step.

Flexible App Bar Background

In order to show the image, an Image widget will be used and a DecoratedBox widget in case of the gradient.

BoxDecoration allows using gradients, it should be a linear gradient to achieve the desired effect.

In order to build a LinearGradient begin, end and the color list to be applied must be defined. Both begin and end attributes take FractionalOffset. FractionalOffset(0.0, 0.0) specifies the upper left corner.

Title will be placed at the bottom inside the AppBar, this is also where de gradient must be applied. Important thing here is y and x offsets must be the same so the linear gradient is implemented vertically.

Specifying 0.6 for begin and 1.0 for end means that we want the gradient to start at 60% of the height and to end at 100%. Following image explains this concept.

LinearGradient

_ContactCategoryItem will be used to show each personal data a contact could have inside a category.

Each item contains an icon and a couple of lines for specific personal data.

A Row element is built inside a padding, Row widget allows horizontally showing several widgets, this behavior is similar to Android´s LinearLayout with orientation attribute set to horizontal. The row will be splitted in two sections to separate the data from the icon.

_ContactCategoryItem

The data will be implemented using Flexible widget because this item size will be dynamic. As a child a Column widget is defined so all lines could be vertically aligned.

Items created using _ContactCategoryItem widget are grouped in categories that are created using _ContactCategory widget.

Constructor will take a ContactCategoryItem list and and icon for the category. This widget is build from a Container, in order to show a separation between containers, a decoration will be used.

Category

Now the page containing FlexibleAppBar and categories containing items must be created.

Theme widget will be used, different theme will be applied depending on contact´s gender.

primarySwatch: _contact.gender == ‘male’ ? Colors.teal : Colors.pink

A Scaffold widget will be defined a a child, in order to achieve scrolling, CustomScrollView must be nested to. CustomScrollView will be provided with two slivers, FlexibleAppBar and a SliverList populated from a categories list.

Phone numbers need a specific implementation for their category generation, _buildPhoneCategory. The rest of categories will be generated using _buildCategory.

Navigation

Last but not least, user taps in a contact item will be managed opening its detail view. Let´s see how _ContactListState has changed.

When creating _ContactListItem a lambda is added to onTap attribute so _showContact method is called.

Inside _showContact Navigator class will be used in order to navigate among different pages. Using push method a new page will be placed over the current one, and pop will remove it. MaterialPageRoute must be created providing a route for the settings and the destination page for the builder, the ConctactPage in this case.

Result

Run the application, it should look like this:

Conclusion

Again it has been demonstrated how easy is creating material design oriented user interfaces using widgets, also navigating and sharing data among different pages.

In the next article it will be explained how to add a sidebar menu to the application.

This article matches with step4 from GitHub repository.

Chema Rubio

Written by

Android developer @BBVANext // @develodroid

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade