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.

Master-Detail View on an iPad

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.

Source code of MasterDetailContainer

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.

Source code of DetailRoute

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!



I write code and take photos. 👨‍💻

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store