Structure of Shell - The New Navigation Paradigm in Xamarin Forms
In my previous post I talked about how you can start using the new Xamarin Forms Shell in your apps, how to set it up and how to use it to create some tabs. In this post I want to take a closer look at this new navigation paradigm so you can start using it freely to create the apps that you need. We will take a look at its structure and its core features and explore how the flyout view works and how you can create one.
Where we left off
In the previous post we set everything up and created an initial view with the help of the Xamarin.Forms Shell, I created a couple of regular ContentPages and used them as the content for a couple of tabs. The XAML code for the Shell view needed an item and sections for each of the tabs that we needed, each section then had a content and the content had the views, so we ended up with this:
<ShellItem> <ShellSection Title="Main" Icon="main.png"> <ShellContent> <local:MainPage/> </ShellContent> </ShellSection> <ShellSection Title="Secondary" Icon="sec.png"> <ShellContent> <local:SecondaryPage/> </ShellContent> </ShellSection> </ShellItem>
A couple of things to note here.
This already has a Flyout menu!
Something that I didn’t mention in the previous post is that, as it is right now, the Shell already has a Flyout menu! Simply click on the top left corner of the view and you should see it!
There are definitely a couple of things wrong here, but it is right there. What is happening in here is that each ShellItem will be listed in this Flyout view, you can notice it in the screenshot as the gray part that seems to be a selected cell from a ListView, because it is! It just doesn’t have any text right now. That can quickly be solved by setting the Title property for the ShellItem, try it out and you will definitely see it listed now. In fact, the ShellItem even has an Icon property, just like the ShellSection, so in that ListView both an image and a label can be displayed for each ShellItem.
This can be simplified
As you may remember from the previous post, each ShellSection -aka, normal tab- can have some secondary tabs inside, which can be accomplished by defining more than one ShellContent inside, each with its own view, but if you only have one ShellContent in the ShellSection, your definition can be simplified a bit. Take our example, where both ShellSections only contain one ShellContent, our XAML code could be simplified to this:
<ShellItem Title="Example" Icon="main.png"> <ShellContent Title="Main" Icon="main.png"> <local:MainPage/> </ShellContent> <ShellContent Title="Secondary" Icon="sec.png"> <local:SecondaryPage/> </ShellContent> </ShellItem>
As you can see, the ShellContent also has a Title and an Icon property, just like the ShellItem and the ShellSection. The result will be exactly the same but with a bit less code. Of course, if you do need more than one “secondary” tab inside an ShellSection (normal tab), you will have to define the ShellSection explicitly.
Flyout Menu
Now, so far we haven’t really done anything new with our code. Setting a title and an icon perhaps, but let’s figure out how we can define new items in that Flyout menu.
As mentioned above, all you need is to define a new ShellItem, it really is quite easy. Let me share with you this lazy example:
<ShellItem Title="Example" Icon="main.png"> <ShellContent Title="Main" Icon="main.png"> <local:MainPage/> </ShellContent> <ShellContent Title="Secondary" Icon="sec.png"> <local:SecondaryPage/> </ShellContent> </ShellItem> <ShellItem Title="Another one" Icon="sec.png"> <ShellContent Title="Secondary" Icon="sec.png"> <local:SecondaryPage/> </ShellContent> <ShellContent Title="Main" Icon="main.png"> <local:MainPage/> </ShellContent> </ShellItem>
One by one, the ShellItems can be listed inside the main Shell element, and they will be listed in the Flyout menu with their title and icon. The above code, for example, results in this list:
Granted, it currently doesn’t look particularly good on a notched iPhone, but you can see the list right there. If you now take a look at the XAML code above, you can infer what will happen with each item. If “Example” is selected, two tabs will be displayed, first the Main tab and then the Secondary tab, when the “Another one” item is selected from the Flyout menu, still two tabs are displayed but now the Secondary tab goes first. I told you this was a lazy example, but it works to show how this works. Of course, normally you will want different ContentPages inside those individual ShellContents, but I hope you now understand how this works.
Tabs as Flyout Items?
There is one particular thing that I don’t think I will be using, since it seems redundant, but that is possible with these inferred ShellSections. It turns out that the ShellItem can also display its children inside the Flyout menu. I think it is best to explain with an example, if you set the ShellItem’s FlyoutDisplayOptions property to “AsMultipleItems”, each “normal” tab will be displayed in the Flyout menu. Take this modification to our example:
<ShellItem Title="Example" Icon="main.png"> <ShellContent Title="Main" Icon="main.png"> <local:MainPage/> </ShellContent> <ShellContent Title="Secondary" Icon="sec.png"> <local:SecondaryPage/> </ShellContent> </ShellItem> <ShellItem Title="Another one" Icon="sec.png" FlyoutDisplayOptions="AsMultipleItems"> <ShellContent Title="Secondary" Icon="sec.png"> <local:SecondaryPage/> </ShellContent> <ShellContent Title="Main" Icon="main.png"> <local:MainPage/> </ShellContent> </ShellItem>
The second ShellItem is now setting FlyoutDisplayOptions to AsMultipleItems, while the first one remains with the default value (no need to explicitly set it). The resulting Flyout menu now looks like this:
The ShellItem’s Title and Icon have been replaced by the Title and Icon for each of its children. As I mention, this seems a bit redundant since it still ends up showing the tabs in the main view, but it is something you can do.
Secondary Tabs
Another thing that, for what I mention above, you may already imagine how you can do is to add secondary tabs inside of a main tab, it all needs is an explicitly defined ShellSection that has more than one ShellContents inside, each with its own view. To showcase this, I will add a third ShellItem to the example, which will be listed as a single item (default FlyoutDisplayOptions value), have one since ShellSection (so no tab bar is shown), and have two ShellContents inside that section:
<ShellItem Title="Third element" Icon="main.png"> <ShellSection> <ShellContent Title="Main" Icon="main.png"> <local:MainPage/> </ShellContent> <ShellContent Title="Secondary" Icon="sec.png"> <local:SecondaryPage/> </ShellContent> </ShellSection> </ShellItem>
The resulting code and view resemble the first ShellItem a lot, except it only has one Section and the tabs are in a different location.
Awesome, no? The new Shell really makes it so much easier to create this type of interfaces quite easily, from one single file.
One quick note
Now that there are three ShellItems, one of which is displaying its children instead of its title, something became more noticeable in the Flyout menu. Notice that each ShellItem is displayed as a section in that menu. Since the second and third element in this list are from the same ShellItem, they are grouped together. Nice.
More to come
The new Shell has many more things that we need to learn. While I hope this post has helped you understand how to define your app’s navigation when it comes to the flyout menu, tabs and secondary tabs, it still doesn’t cover basic things about the Flyout menu itself (starting with making it look right and show the hamburger icon), more complex things about navigation and search (which is also deeply integrated in the new Shell).
Posts on those things are coming, but for now, I think you now have a better understanding of the Shell.
This topic, along with many many others, is covered in greater depth in my 25-hour long "The Complete Xamarin Developer Course: iOS and Android" course, which you can practically steal from me by