Flutter – Adaptive Layout

I rotated the screen on the iPhone and it worked, so first strike, no hard coded UI positional issues with the widgets and scaffold so far.

Shows the digest list in landscape.
Shows the digest list in landscape.
Shows the recipe details in landscape.
Shows the recipe details in landscape.

Apple’s human interface guidelines recommend using a split view layout instead of a tab bar on an iPad.

Based on the current phone screens we need something like this:

Split view design for the recipes digest
Split view design for the recipes digest

And some information and logic to detect the device and select the appropriate layout.

Shows the adaptive layout working for iPhone and iPad.
Shows the adaptive layout working for iPhone and iPad.

Ta Da

Three column splitview.
Three column splitview.

In the next post we will add the functionality to the new split view screen and decide on which devices and orientations it will be available in.

XP

For such a seemly simple change adapting the layout to different devices, I had to consider a number of tricky architectural areas and make some structural changes

Hopefully, they will help keep the code base clean and healthy as the application grows.

Device info and layout.

Welcome to the chicken and egg world of relying on data from asynchronous calls.

To decide between tabbed or split view I need to know about the client device and its orientation.

However, the device information is only available after the application loads and builds the screen.

To get around this I created a widget “LayoutSelector”, and a new change notifier provider called ‘Layout’.

When the application first runs the device information is not available and it displays a blank screen.

When the device information call finishes its sets the value on the ‘Layout’ provider, which then notifies the ‘LayoutSelector’ to rebuild.

This time it has the device information and can choose between the tab or split view layout.

The user experience works well because all the layout backgrounds are the same colour, so the screen change between loading and the selected device layout goes un-noticed.

Now we have a loading screen there is an option to improve the Ux when things take longer than usual to complete i.e. add a funky animation that is displayed if the application takes longer than a second to load the layout.

This feels the right way to go, but I welcome comments on this.

One thing to note is I’m trying to keep application state simple and just use providers over a DI package.

Package Imports

I’ve added another requirement to the ‘Done, Done, Done, Done’ check list for development.

  • Relative imports for children and package imports for everything else.

It was tempting to just go with package imports but having relative ones for children makes it easier to move folders around under the \lib dir.

There will be a blog on the ‘done, done, done, done’ checklist later in the series.

Project Structure

It is time for a little bit more structure as the number of files and directories grow.

Up to this point all the screens where under the /lib/tab directory. Now they are shared with the split view they have been separated and we have three directories.

  • \lib\ui\tab
  • \lib\ui\screen (Used by the tabs and split view panels.)
  • \lib\ui\splitview

The number of top level directories had also increased so I added \ui at the top level and moved a number of the top level items under it.

Project structure for /lib & /test directory
Project structure for /lib & /test directory

I follow a general rule of 7s, never more than 7 items at a given level. Not sure who I picked this rule up from.

Links

Sound & Vision

BBC drama: The Tourist

One more thing…

“We do no market research. We don’t hire consultants. We just want to make great products.”

Steve Jobs_

Please follow and like us:

Leave a Reply

Your email address will not be published.