Master-detail View in Flutter
Recently, I started exploring Flutter, an open-sourced mobile app SDK from Google. I found that one of the common UI patterns, especially on tablets, master-detail view was missing from the widget library. Therefore, I decided to create one myself and document how I did it in this article.
The final product looks like the GIF below. However, this is more like a proof-of-concept and it certainly has a lot of room for improvement.
Ok, let walk you through how a ‘master-detail’ view works. Assume that you have a MasterPage
widget that acts as the ‘master’ view and display a list of items, when you click on of the item, you would expect the app present the DetailPage
widget which acts as a ‘detail’ view that displays the detail of the selected item. On a mobile phone, the entire screen would be replaced by the DetailPage
when an item is selected and MasterPage
is no longer visible, this could easily be achieved by callingNavigator.push()
. However, on a tablet, things are a little bit different, we don’t want the DetailsPage
to cover the entire screen. When an item is selected, the MasterPage
remains visible but only occupies about 30% of the screen, the DetailPage
should be presented in the remaining 70% of the screen.
However, it gets a little bit more complicated as iPads have multi-tasking mode that allows two apps to be displayed on screen at the same time. In this situation, if your app happens to be running on the narrower side of the multi-tasking view, it should usually display a mobile layout and vice versa. Besides, you also need to maintain the navigation stack when the user enters or leaves the multi-tasking view.
So, how can we achieve this?
As a Navigator
uses Overlay
to display Routes
by stacking the newer route on top of the older route, I think maybe we could create a subclass of TransitionRoute<T>
and override the bit where OverlayEntry
would be generated. I shall call this DetailRoute
. The content of the OverlayEntry
should be wrapped in a Positioned
widget and a SizedBox
widget the we can use to layout the DetailPage
according to the screen size.
Ok, enough talking about theory and let’s start coding. First, we need a MasterDetailContainer
that fills the entire screen. It would be used to control the size of the MasterPage
and display white background over the DetailPage
's space when nothing is selected.
Next, we need a MasterPage
that displays a list of items, in this case, they are just strings. When an item is selected, we will call our Navigator
to push a new route into the view. However, we won’t be using a MaterialPageRoute
that we’re usually using but a DetailRoute
that we are going to create next.
If you run the project as this stage, you should see something like this:
Now, let’s create the most important part DetailRoute
. I chose to subclass TransitionRoute
because I think it is relatively easy to subclass and not as barebone as a Route
. It would require the understanding of more classes if I were to choose other subclasses, such as ModalRoute
or PageRoute
. Of course, this means I won’t get all the gestures supports and transitions from a MaterialPageRoute
, but I will deal with all those things in a future article. Let’s just focus on the layout for now.
All right, these are pretty much all we need to implement a simple master-detail view. Run the code on an iPad simulator now and you should see something similar to the GIF above. The source code could be found on GitHub at the link below:
Let me know what you think about this implantation of master-detail view in Flutter. Thanks for reading this!