Inside the Tabris UI
As you may have read in the Tabris 0.11.0 new and noteworthy post, we have created a small UI framework called the “Tabris UI”. In this post I will dive into the details of this framework. Grab a coffee and open your mind ;). Let’s get started…
Background
Almost a year ago we released our first public milestone (back then Tabris was RAP mobile). Since then we have worked hard towards the Tabris 1.0 release. The basic idea behind Tabris was always to use the SWT Java API to create UIs for mobile devices. This idea hasn’t changed much. Since the first milestone Tabris has had many adopters and we’ve received a lot of good feedback. One topic that especially got us thinking was stated as follows: “Tabris is nice and SWT allows me to create a rich UI. But, it doesn’t allow me to use common navigation concepts”. Said another way, the problem for developers is that each platform has it’s own navigation concepts. For Android this is the ActionBar and for iOS it is the View Controllers as highlighted in the screenshot below.
With plain SWT it’s not possible to create a UI using those concepts and as result it was not possible with the early versions of Tabris either. Note here, that the operative word in the last sentence is “was” - because, we have created a small UI framework on top of SWT that enables you to create UIs using native navigation concepts. This framework now forms the core of Tabris.
Abstraction
Tabris is a framework for cross-platform mobile apps. The basic concept of Tabris is that you write the UI in Java and it runs on the server. A device calls the server and renders your UI with native components. This means that when you create an SWT Button on iOS, an iOS button will be created and on Android, an Android button will be created. As a result, you can create applications with one code base that serves multiple platforms. This means that we can’t (and don’t want to) port the concepts of the different platforms to a server side API. We have to create an abstraction! That is, an encapsulation of the concepts of all platforms into a simple, understandable API.
This API is called “Tabris UI”. The key parts are two types, Page
and Action
. To make it clear what these types are we can take a look at another image.
The red shaded area of these images is the Page
which basically contains your controls. In the green shaded boxes you can see two Actions. An Action
is an element that a user can press (to activate) and which is located outside of the Page.
Concepts
Let’s look a little deeper into Pages and Actions. Pages can be chained together in any order. This means a user’s button click can be used to open a new page. When you do this multiple times a chain will be created. Within this chain you will be able to browse backward to the previous page . This concept is called page chaining. Every chain has a root element. This is what we call the “top level” page. One application can have multiple top level pages and all can mark the beginning of a chain. Let’s take a look at a diagram.
This diagram could represent almost any application. The usual flow of an application is that you start on a top level page and browse through several pages, going deeper into the application. As you can see on the image this is what we call chaining. But one top level page is not enough for most application. Think about a bookstore application. The possible top level pages are “All Books, Favorites, Popular Books”. Each top level page will contain another set of books you can browse through. So, when you have several top level pages you need to be able to browse from one top level page to another or to browse from a normal page to a top level page. This is shown with the red arrows on the diagram. What’s not possible is to navigate from one page in a chain to a page in another chain because only one chain can exist at any given time. The pages in a chain are created when they are visited and they will be destroyed when you navigate in reverse and leave them (e.g. when you jump back to the top level page or the previous page).
Actions have a lifecycle similar to Pages. Similar but not exactly the same. Two types of Actions exist. Global Actions and Page Actions. A Global Action is visible regardless of which page the user is on. Page-Actions exist only on a specific page. They are created when the page is created and will be destroyed when the page is destroyed. You can see the difference in the following screenshots. In these images the Global Action is shaded in green. It has application scope. The Page-Action is shaded red. It has page scope.
Programming Model
You will create Page and Action objects to enable the main functions of your applications. And, in most cases you will quickly reach a point where the components need to communicate. Of course, you can access a Page directly from within an Action but this is not good practice. We prefer a loosely coupled communication between components. This communication can be accomplished by using a context. In the Tabris UI it’s called a UI and you can use it for navigation and influencing the state of actions too. The key feature of the communication is that you can a data store from it. When I talk about a store think about a simple Map
, encapsulated in the type PageData
. A PageData object has the same lifecycle as a page. Each page has it’s own data, even top level pages. This is because you will need to pass data in your chain. You can navigate to a new page and pass in a PageData
object which then marks the page store of the new page. Let’s take a look at another diagram.
As you might notice it shows the same page chain as above. What’s different is that it shows the new PageData objects that will be passed to a new page. In this data you can save page state information such as a selection.
Configuration
What we have not described in the preceding paragraphs is how the different components come together. This is all done via configuration. To be explicit the type that matters is called UIConfiguration
. You will need to create an instance and add your Page configurations and Action configurations to it. What are Page and Action configurations? As the name says, they are the configurations of a Page or an Action. A Page doesn’t know anything about it’s title, if it’s a top level page or about it’s image. And this is the same for Actions. This information needs to be declared within a PageConfiguration
or ActionConfiguration
object. The diagram below shows how this works.
As you can see, the Tabris UI framework is responsible for creating Page and Action objects from the configuration. This also means that you will need to add Page or Action Class objects to it’s configuration. After you have created your configuration it can be passed in as a constructor argument into the TabrisUIEntryPointFactory
object. As a result this needs to be added to an Application
within your ApplicationConfiguration
implementation.
Ready to use
Using everything described above, you can write powerful applications that will have a platform specific user experience. We have created an example for the Tabris UI. It’s the bookstore example mentioned earlier. You can see the flow of this app in the picture below.
You can look into this example on github. It’s licensed under the EPL 1.0, so feel free to use it as a starting point for your application.
Outlook
The current implementation is targeted for phones because only one page can be visible at a time. Of course it can be used on tablets too, but having only one page at a time on a tablet is not the way most Apps work. We are working on an enhancement on top of the Tabris UI to be able to define groups of pages that can be visible at the same time for tablet devices.
We hope you will enjoy using the Tabris UI as much as we do. For me, it’s a breakthrough feature for Tabris and for cross-platform development for mobile apps. As always, feel free to disagree ;).