Weekend Coder: Navigating through your app

We're continuing our series on learning how to write BlackBerry apps from a hobbyist perspective. This edition, we dig into tabbed navigation panes in Cascades...

By Brian Scheirer on 29 Jun 2013 12:47 pm EDT

Presumably when you create an app you can’t (or won’t want to) have all of the content displayed on a single screen.  When using Cascades you have two main navigation types to use: Navigation Pane and Tabbed Pane. Navigation Pane creates a stack of screens that a user can go back and forth between and Tabbed Pane creates user selectable tabs that send them to specific page. Let’s go ahead and take an in depth look at each of these navigation types.

Navigation Pane

Navigation Pane uses a philosophy known as “push” and “pop.” The idea is when you are on a page, you “push” to a new one and when you want to go back to the previous page you “pop” back. This essentially creates a stack of pages (think of it as the same as stack of playing cards). Though you can start with prebuilt NavigationPane project, I will start from scratch to explain the process.  In the main.qml page have your root as a NavigationPane (be sure to give your NavigationPane an id), then within that define a Page, then a Container and then you’ll have all the content of your app within the container. So you’ll have the following:

import bb.cascades 1.0 NavigationPane {     id: navigationPane     Page { Container { }     } }

Now you need a method to push to another page. Your method could be an action (on the action bar), a button (custom or stock) , etc. The method provided in the prebuilt project uses an action however I am going to use a Button, which will be very similar. Let’s go ahead and define a Button somewhere in our Container that is within our NavigationPane, so we’ll have something like:

import bb.cascades 1.0 NavigationPane { id: navigationPane Page { Container { Button { text: "Go to Another Page" onClicked: { } } } } }

Within our button we will like our onClicked signal to send the user to a new page but first we need to create the new page.  In most cases your new page will be another QML file. Right click your assets folder within your Project Explorer and select New -> QML File. In my example I have called this file “AnotherPage.qml.” Now to call this page from our main.qml page we need to have an attachedObject of a ComponentDefintion within our NavigationPane that has an id and source. The id can be whatever you want and the source will be the name of your QML file you want to push to, so “AnotherPage.qml” for our example. Then, back to the onClicked signal within our Button, let’s call the push function to create the ComponentDefintion we just defined using the following code:

import bb.cascades 1.0 NavigationPane { id: navigationPane Page { Container { Button { text: "Go to Another Page" onClicked: { var newPage = secondPageDefinition.createObject(); navigationPane.push(newPage); } } } } attachedObjects: [ ComponentDefinition { id: secondPageDefinition source: "AnotherPage.qml" } ] }

Running this code on a simulator will result in your main.qml page launching with a Button that when pressed will take the user to AnotherPage.qml . When the user arrives on AnotherPage.qml they will be able to go back to main.qml by pressing the back button (appears by default) on the action bar or using the peaking gesture to swipe back. Both the back button and/or the peaking gesture can be disabled. However realize if you disable both of them and you would like for the user to be able to go back to the main.qml page, you need to provide some other means to go back, such as a Button.

To disable the back button you would have to following in your NavigationPane:

import bb.cascades 1.0 NavigationPane { id: navigationPane backButtonsVisible: false //... }

To disable peak you would have the following in your NavigationPane:

import bb.cascades 1.0 NavigationPane { id: navigationPane peekEnabled: false //... }

To have a method of “pop”-ing back to main.qml from AnotherPage.qml you could have the following in the onClicked signal of a Button. So you could have "AnotherPage.qml" look something like:

import bb.cascades 1.0 Page { Container { Label { text: "This is Another Page" } Button { text: "Go Back" onClicked: { navigationPane.pop() } } } }

This process can be repeated for any number of pages. We have now covered the basics of NavigationPane.


Tabbed Pane

Tabbed Pane creates user selectable “tabs” that appear either in a tab overflow menu (default) or along the bottom action bar. Again you can create prebuilt project of a TabbedPane but I’ll start with a blank project to explain and show some options. Similar to NavigationPane we will change the root of the main.qml from Page to TabbedPane. Within the TabbedPane, define a Tab for each tab you’d like. Then within each Tab you can define a Page. Inside that Page you’ll define all your components. Additionally you should give your Tabs titles and images. Let’s take a look a some code that defines a Tab with a title, image, and a simple page with some text:

import bb.cascades 1.0 TabbedPane { Tab { title: "Tab 1 Title" imageSource: "asset:///images/icon1.png" Page { Container { Label { text: "Info on Tab 1" } } } } }

Continue this process with as many tabs as you’d like. You may be thinking you’ll end up with A LOT of code within your main.qml file if you define quite a few tabs. So I find it best to define custom components for each page within each tab so you’ll end up with something like this:

import bb.cascades 1.0 TabbedPane { Tab { title: "Tab 1 Title" imageSource: "asset:///images/icon1.png" MyTabOne { } } Tab { title: "Tab 2 Title" imageSource: "asset:///images/icon2.png" MyTabTwo { } } }

Where MyTabOne and MyTabTwo are separate QML files that house the code for those tabs. This is not necessary, but definitely helps keep your code organized.

Finally the main option you’ll need to consider is whether or not to have the tabs display along the bottom or in the overflow menu. This is toggled using the following code within the Tabbed Pane:

import bb.cascades 1.0 TabbedPane { showTabsOnActionBar: true //true shows on Action Bar, false shows on overflow menu }

Note that anything beyond four tabs will automatically go to the overflow menu.

Another useful aspect of the TabbedPane is that you can combine it with NavigationPane. Say for instance we copy everything from our main.qml in the NavigationPane example above into MyTabOne.qml. When the user is on that tab they will be able to navigate to AnotherPage.qml then when they “pop” back the main tab screen. A good example of this is in the CB10 app, when you select the forums tab, then select a thread within a forum you are going from a TabbedPane view to NavigationPane view. And I’m sure you’ve seen something similar in many other natively built applications.

That about does it for the two main navigation types in BlackBerry 10 Cascades. There are other types too but these are the foundations of navigating. Beyond these you can start having some custom flows/transitions using Sheets, Dialogs, and any variety of custom components, but that’s a tutorial for another day.

Feel free to sound off in the comments with any questions, comments, and/or suggestions. Glad to see in the past few Weekend Coder articles there has been great feedback from other developers helping each other, so let’s keep that going.

Reader comments

Weekend Coder: Navigating through your app


Please give us the black theme for this CB 10 app.

via CB10 (BB Z10 : BLK : OS 10.1) [ Follow me @EHZAY for BB News & Tech Updates ]

I haven't read all of this post yet but I intend to sit down with a nice glass of Bourbon and hack my way through it later. I just really wish I understood ANY of it!

Posted via CB10

This is true. As much as I love some beer, it doesn't go well with coding. After coding it's a must then :D

Posted via CB10

When are you going to come to Montréal do a salon show on how to create apps and games on blackberry?

I'm waiting you guys. Please come...

I will register for sure

Posted via CB10

The ease of navigation is great! So simple to set up and adding actions is great too.

The learning curve for me is passing info back and forth between pages and making use of c objects and functions from qml.

It has been fun to go through the examples though and slowly build up my app with my new skills :)

Posted via CB10

I have a tutorial that helps with passing the information between NavigationPanes: http://bbcascades.com/index.php/tutorial-list/65-stack-of-screens-passing-information-around I don't use any C++ object though.

Thanks! Really looking forward to trying my hand at app development. Once I get this damned thesis finished :P

I want to take over the world developing apps on my Z10, but need lessons. When are you guys coming to NYC?

Posted via iPhone 4S

I have yet to take the plunge and start coding a Cascades app - mainly focusing on HTML5/WebWorks at the moment... However, I have been keeping an eye on this series of posts, and can DEFINITELY see myself reading (and referring to) the series in a few months' time...

Keep up the great work!

I don't code at all, never did, and I read these articles and think I register about 80% of the information. I enjoy the lease posts even though I always assume beforehand that the subject matter will be over my head.

Sent from my iPuh-lease-as-IF

I have a request. Can you show how to use Activity indicator in conjunction with a list view.


Posted via CB10

There's not much to write about that topic... What you would do is have your ActivityIndicator load first (which will be nearly instant) then when the data is loaded you would change the ActivityIndicator from visible: true to visible: false. Hope that helps in the meantime.

I really want to get into coding, anyone know any good free sites that have hours of lessons building upon one another?

Posted via BlackBerry Z10

What I dislike about tabs is that they are difficult to handle with one hand only. Typical example is BlackBerry World app. If I want to see comments I've got to use my other hand. Swiping right and left would be ideal in this case. I'm just wondering why no one at BlackBerry though about it. :-)