How to Make Custom Toolbar in Titanium

Custom toolbar in Titanium that works for ios and android

This tutorial will show step-by-step how to make a custom toolbar in Titanium that sticks (or stays put) at the bottom. Titanium has Titanium.UI.iOS.Toolbar that looks and works like a native iOS toolbar, but Android doesn’t have this. Some would argue that you can add the tools on Android’s Action Bar, but what if you want to make one toolbar that would work for both iOS and Android? Besides, it doesn’t hinder User Experience. In fact, since this toolbar will stay put, it will always be there without the user having to scan what options are available.

1. Make a whole new Titanium project

For this tutorial, let’s name it CustomBottomToolbar. Be sure to check iPhone and Android only. The toolbar can fit in iPads and bigger Android screens. But let’s keep this tutorial simple.

2. Choose Default Alloy Project

You can choose the other templates that Titanium Studio offers, but this tutorial won’t be dealing with the views the other templates provide.

3. Open index.xml

Replace the default contents of index.xml with this:


<Alloy>
   <Window class="window">
      <View id="footerToolbar">
         
     </View>
</Window>
</Alloy>

The above code isn’t complete without TSS attribute definitions.

4. Define index.tss

For now, since we only have .window and #footerToolbar declared in the markup, they are the only ones that we’re going to define.


".window": { 
    backgroundColor:"white",

    /* layering the views */
    layout: "composite"
}

"#footerToolbar": { 
    /* Make toolbar stick to bottom */
    bottom: 0,

    /* Spans the screen */
    width: '100%',
    
    /* Set the layout to horizontal
     * so that the contens will be
     * laid-out across the screen
     */
    layout: 'horizontal',
    
    /* iOS toolbar is approximately
       this height. */
    height: '45dp',
    
    /* grey-ish */
    backgroundColor: "#f8f8f8",
    
    borderColor: "#CCCCCC",
}

On line 5, .window has composite layout so that while the toolbar stays put (or sticks) at the bottom, it can be on top of a view that scrolls. Examples of this include, but are not limited to, Titanium’s ScrollView, TableView or ListView. We’ll add one of them later, this way the user can scroll while the toolbar is still visible.

Line 11 is responsible for making the toolbar stick to the bottom.

The basics of this custom bottom toolbar should look like this:

bottom toolbar has now been added

Bottom custom toolbar has now been added

5. Let’s add three buttons

What’s a toolbar without its tools?


<View id="footerToolbar">
   <View id="clickMe" class="button" onClick="clickMe">
     <!-- We will add icon and text here -->
   </View>
   <View id="popUp" class="button" onClick="popUp">
     <!-- We will add icon and text here -->
   </View> 
   <View id="extraYay" class="button" onClick="extraYay">
    <!-- We will add icon and text here -->
   </View><
</View>

So the buttons are also just View tags. Each has it’s own id for unique TSS identification, a class button to style them as buttons and onClick events for interaction. All three of these will give the impression that they are “real” buttons because they will look and act like one after the id’s, class, and click events are defined (in their respective files).

6. Define the functions on index.js

We have to define the functions that have been added onto the onClick events in index.xml now, so that things don’t break once we run the app. Usually, once Titanium Studio runs and sees that a view has a function that is tied to an event, and that said function has not been declared in the controller, the app breaks. Here’s what index.js should look like:


$.index.open();

function clickMe() {
  /* Look at your console tab in Titanium Studio
   * to see this message */
   console.log("You clicked Me");
}

function popUp() {
   alert("I'm a pop up!");
}

function extraYay() {
  /* It just returns 3 */
  return 1 + 2;
}

The main point of this tutorial is to make a toolbar with buttons so these functions are good enough for testing later. If you run the app now, you won’t really see any buttons to tap or click. But if you already get the point, then add some more sophisticated code in each of the functions if you like. Up next, you will add the contents for each button.

7. Add contents to each of the buttons

Here we’re going to add an ImageView as the icon and a Label as the text at the bottom of the icon.


<View id="clickMe" class="button" onClick="clickMe">
  <ImageView image="/images/star.png" height="Ti.UI.SIZE" width="Ti.UI.SIZE" />
  <Label id="starText" class="toolButtonTitle"> Click Me</Label>
</View>
<View id="popUp" class="button" onClick="popUp">
  <ImageView image="/images/heart.png" height="Ti.UI.SIZE" width="Ti.UI.SIZE" />
  <Label id="heartText" class="toolButtonTitle"  >Pop Up</Label>
</View> 
<View id="extraYay" class="button" onClick="extraYay">
  <ImageView image="/images/circle.png" height="Ti.UI.SIZE" width="Ti.UI.SIZE" />
  <Label id="circleText" class="toolButtonTitle"  >Extra</Label>
</View>

8. Define the three buttons in TSS

The icon and text will be stacked up together in a button. So we’re going to define the .button to have a vertical layout.


/* .button layout defintion */
".button" : {
    top: '5dp', /* space at the top */
    
    width: '50dp',
    height: '40dp',
    
    /* contents will 
     * be stacked up */
    layout: "vertical"
}

9. Style the button contents

We give each button group margins so that they’re not too close to each other. They are lined up from left to right in this example. Then we center the text, make it bold so that it can be easily read with a font-size of 10. The text colors are optional, but I thought it’d look good if they match their icons’ colors.


/* Give left margins 
 *to each button groups */
"#clickMe" : {
    left: '5dp'
}

"#popUp" : {
    left: '10dp'
}

"#extraYay" : {
    left: '10dp'
}

/* Toolbar button text */
".toolButtonTitle" : {
    font: {
        fontSize: 10,
        fontWeight: "bold"
    },
    textAlign: "center"
}

/* Each text will have different colors.
 * This is optional. */
"#starText" : {
    color: "#4ca5cd"
}

"#heartText" : {
    color: "#f37121"
}

"#circleText" : {
    color: "#649369"
}

10. Add the images for the icons

So far, we’ve done a lot but we’re not done yet. We have to add the icons.

iOS

Download icons for iOS

In Titanium Studio, go to the Project Explorer side panel. Then, go to assets and expand iphone folder. Copy and paste the downloaded images folder into the iphone folder.

custom toolbar button icons for ios in Titanium project explorer

Android

Download icons for Android

Back to the Project Explorer panel, go to assets > android and expand images folder. Copy and paste the downloaded res-hdpi folder into the images folder. Do the same for res-ldpi, res-mdpi, res-xhdpi, res-xxhdpi and res-xxxhdpi.

custom toolbar button icons for android in Titanium project explorer

If you run the app, it should look like these

Toolbar with buttons

custom toolbar icons in genymotion using Titanium

11. Let’s add a ScrollView (Add-on)

This step is an add-on and you may skip it. Here, we will add the ScrollView at the top of the toolbar in index.xml. It will contain a very long placeholder text. The text must be long enough to enable the scroll mechanism. This is good for testing. Notice that as you scroll, the toolbar stays put. This is what index.xml should look like now:


<Alloy>
   <Window class="window">
      <ScrollView>
        <Label>Lorem ipsum dolor sit amet, est salutatus dissentiunt in, 
        purto albucius definitiones no usu, quis convenire duo ei. 
        At eius deleniti constituam pri. Pri nobis antiopam ut, qui 
        ne ferri fierent explicari. Ex qui putant inermis, ad meliore 
        insolens qualisque pri, an pro purto noster nostrud. Mea quodsi 
        nostrum copiosae ei, ei posse assum usu, fastidii indoctum cu duo.
                    
        Nostro gubergren signiferumque an pri. In vis facete urbanitas, quo 
        falli dolores lucilius in. Pro putent labore laoreet ei, admodum corrumpit 
        vis ad. Sed legendos intellegat voluptaria id, tollit labitur iuvaret te quo, 
        at eirmod aeterno quo. Ea vero atqui his, sit libris sanctus voluptatibus eu, 
        dico cibo animal qui ne.

        Ad sint justo meliore eam. Adipisci eleifend ut duo. Euismod iudicabit sea ea, 
        sea inani graeco inermis ad, mei et novum vidisse. At ferri soleat sed. Mei legere 
        verear eloquentiam ne.

        Ex velit molestie mel, suas signiferumque id eos. Ea timeam epicuri pri, 
        id possim diceret moderatius has, sea dicam iracundia reprimique an. Maiorum epicurei 
        appetere per id, id gloriatur incorrupte usu, esse purto eam cu. Cu duo magna omnium 
        lobortis.

        Mea no reque saperet admodum, an wisi conceptam ius. Ius eu choro vidisse, id sea probo 
        maiorum. Eos sumo everti minimum te, ius virtute eleifend cu. Quo no enim efficiendi,
        his ne ubique ignota regione, no ius noster appareat placerat. No congue adipisci pro, 
        eos sale graeci ea.</Label>

      </ScrollView>
      <!-- Footer toolbar is here -->
      <View id="footerToolbar">
        <View id="clickMe" class="button" onClick="clickMe">
           <ImageView image="/images/star.png" height="Ti.UI.SIZE" width="Ti.UI.SIZE" />
           <Label id="starText" class="toolButtonTitle"> Click Me</Label>
         </View>
         <View id="popUp" class="button" onClick="popUp">
           <ImageView image="/images/heart.png" height="Ti.UI.SIZE" width="Ti.UI.SIZE" />
           <Label id="heartText" class="toolButtonTitle"  >Pop Up</Label>
         </View> 
         <View id="extraYay" class="button" onClick="extraYay">
           <ImageView image="/images/circle.png" height="Ti.UI.SIZE" width="Ti.UI.SIZE" />
           <Label id="circleText" class="toolButtonTitle"  >Extra</Label>
         </View>
      </View>
   </Window>
</Alloy>

ScrollView added with content long enough for scrolling to take effect.

ScrollView added with content long enough for scrolling to take effect.

Notice that when you scroll all the way to the bottom, the rest of the content is hidden behind the toolbar. That’s because the default height of the ScrollView is reaching all the way to the bottom of the device’s screen. To fix that, we need to specify ScrollView’s bottom property to the height of toolbar. In index.tss the height of this toolbar is 45dp. So we specify the bottom of the ScrollView to 45dp like this:


<ScrollView bottom="45" top="15">

I’ve also added a top property so that ScrollView doesn’t get meshed up with the iOS StatusBar.

The toolbar stays put and the scrollview is properly configured

The toolbar stays put and the scrollview is properly configured

Conclusion

This is one way to make a custom toolbar in Titanium that sticks at the bottom. It’s just a bunch of views with click events and some configurations in the TSS to make the views look like buttons. I didn’t use any Titanium button APIs because the View API is very flexible enough to do what I want. Other APIs have specific properties that I’d rather not have to change or deal with. With View, I started from scratch and made a toolbar. I was able to use Titanium layouts to get the alignments that I wanted. I was able to specify widths and heights and placements. More over, the View has an onClick event which I used to my advantage. When the user taps any of the “buttons,” it does something a user would expect a button in a toolbar would do. I mean run the project in iOS Simulator and Genymotion. Does it not look like a bar with tools (buttons)? You can download the project files on my GitHub.