Titanium Mobile App Development Essential Training

Titanium Mobile App Development Essential Training

with Rafael Hernandez

 


In this course, author Rafael Hernandez creates native iOS and Android applications from a single codebase with the open-source Appcelerator Titanium platform. The course explains the difference between browser-based JavaScript and Titanium JavaScript, shows how to create a basic application, and demonstrates building buttons, sliders, switches, and pickers. The course also covers creating tables, implementing maps, providing feedback to users, incorporating multimedia, detecting gestures, and preparing finished apps for distribution.
Topics include:
  • Accessing the Titanium API documentation
  • Navigating the Titanium Studio workspace
  • Detecting platforms
  • Understanding windows and views
  • Listening for events
  • Configuring text fields
  • Adding interactivity to a view
  • Working with a single tab group
  • Creating a map and setting the location
  • Adding and removing map pins at runtime
  • Loading local and remote web pages
  • Loading an external XML feed
  • Setting timers
  • Prompting device vibrations
  • Implementing an activity indicator
  • Reading from and writing to the file system
  • Working with media
  • Reading device orientation
  • Detecting gestures
  • Debugging an app
  • Stepping through a finished app

show more

author
Rafael Hernandez
subject
Developer, Mobile Apps, Web, Mobile Web
software
Titanium
level
Beginner
duration
3h 3m
released
Feb 02, 2012

Share this course

Ready to join? subscribe


Keep up with news, tips, and latest courses.

submit Course details submit clicked more info

Please wait...

Search the closed captioning text for this course by entering the keyword you’d like to search, or browse the closed captioning text by selecting the chapter name below and choosing the video title you’d like to review.



Introduction
Welcome
00:04Hi! I'm Rafael Hernandez and welcome to Titanium Mobile App Development
00:08Essential Training.
00:10In this course, we'll look at using one set of code to create mobile apps that
00:14run on both iOS and Android devices.
00:17I'll start by showing you how to set up a project and how to create images and labels.
00:21Then I'll show you how to add interactivity and gather information from the user
00:26using text fields and text areas.
00:28After that, we'll look at tabGroups and the tableView, which is a common way of
00:32presenting information to the user in an application.
00:35Then we'll look at some of the more advanced functions of Titanium Mobile, such
00:39as implementing a map view, providing the user with feedback, working with
00:43multimedia, and more.
00:46Finally, I'll show you how to prepare your app for distribution in the
00:49Android and iOS app stores.
00:52I'm eager to show you what Titanium Mobile offers.
00:54Now let's get started with Titanium Mobile App Development Essential Training.
Collapse this transcript
About the exercise files
00:00If you're a Premium member of the lynda.com Online Training Library, or if
00:05you're watching this tutorial on a DVD -ROM, you have access to the exercise
00:09files used throughout this course.
00:11I'll be working with the exercise files on my desktop.
00:14The completed states of the files, to which I'll be referring for CodeSnippets,
00:18are organized in folders by chapter and then by movie.
00:24The beginning states, from which I will start each movie, are located inside the
00:28start folder numbered by chapter-movie.
00:34In Titanium Studio, the start state project can be imported by choosing File > Import.
00:40In the next window, select Titanium > Import Existing Titanium Project, then click Next.
00:49Now select the project to import.
00:57Titanium Studio may warn you of problems detected during import.
01:03For most movies I will start with the app.js file in the project's Resources folder.
01:11If you're monthly member, or annual member of lynda.com, you don't have
01:15access to the exercise files, but you can follow along from scratch with your own assets.
01:20I'll show you how to create a project from scratch in a later movie.
01:24Let's get started!
Collapse this transcript
Understanding the prerequisites
00:00For this course, you'll need to be familiar with JavaScript.
00:03It will be great if your knowledge of JavaScript is linked to some sort of
00:06experience working with web development.
00:08Now I'm not completely assuming that you're a JavaScript or web
00:11development master.
00:13Instead, I figured that you have some prior knowledge about how to tweak bits of
00:16JavaScript code within a web page in order to make it interactive.
00:20If you've worked with an external JavaScript library like jQuery, or have
00:24implemented someone's JavaScript plug-in, like an image slideshow plug-in, for
00:28example, that's a great start.
00:30In this course, I'll use some very basic and stock programming techniques.
00:34I will make mention of objects, their properties, and utilize dot syntax to set
00:39and retrieve values for these properties.
00:41I will use lots of conditional statements, especially related to detecting
00:45devices, which I cover later in this course.
00:47I will use for loops to iterate over objects to build multiple visual
00:51elements efficiently.
00:53Though rarely, I will implement some more advanced programming logic to add
00:57sophistication and elegance to the mobile apps I'll be using.
01:01If you need to brush up on JavaScript, I highly recommend you check out
01:05JavaScript Essential Training here in the lynda.com Online Training Library.
01:10On the web development side, I start out with the understanding that you've had
01:14some exposure to CSS.
01:16Titanium features a lot of properties for its objects that closely resemble CSS
01:21in their name, function, and value types.
01:24I do go into a good amount of detail when talking about the properties of
01:28objects in Titanium.
01:29So any familiarity with CSS is great for this course.
01:33You don't have to be a programmer to follow along with me, but it helps if
01:37you've got some exposure with programming techniques and concepts through
01:40working with browser-based JavaScript.
Collapse this transcript
Accessing the Titanium API Documentation
00:00The Titanium Mobile API reference is located at developer.appcelerator.com.
00:06From this landing page I'll chose Docs.
00:09Under the Titanium Mobile column I'll choose API Docs.
00:13On this page, each of the APIs is listed at the left.
00:17I will select the Titanium.UI module and then choose the ImageView object.
00:26At the top right a brief description of the API is given.
00:30More importantly however, is appcelerator's key to platform compatibility.
00:35A module, or objects compatibility, will be indicated by a colored icon for the platform.
00:40Here the Titanium.UI.ImageView platform is compatible with Android, iPhone, and iPad.
00:47To show you an example of a module that isn't compatible across the three
00:51platforms, I'll load the Titanium.Android module, notice that only the
00:55Android icon is colored.
00:57This module and its objects are not compatible with iPhone or iPad.
01:00I will head back to the Titanium.UI module.
01:04We will be working with objects contained within modules.
01:09Notice under objects there is a description column.
01:12Most important here are the links that take me to the specific methods
01:16that create objects.
01:18I'll select Titanium.UI.Label.
01:24On this page, the methods, properties, and events are listed for this object.
01:30What's better, is that at the bottom of the page, there's a code example for how
01:33to implement this method.
01:35Note that not all of the documented APIs have code examples.
01:39I'll go back to the Titanium.UI module page and select
01:45Titanium.UI.DashboardView.
01:50Here, there is a thorough list of the methods, properties, and events for this object.
01:55At the bottom of the page however, no code example is given.
01:59Finally, I will select Q&A from the menu to go to the Developers forum.
02:03This is a helpful place to ask a question of the Titanium Developer Community.
02:08There are lots of individual APIs to use within Titanium.
02:11While I won't cover them all in this course, I'll certainly cover a good number
02:15of them so that you can get started coding your mobile app.
Collapse this transcript
1. Getting Started
Creating your first application
00:00To get started quickly with Titanium Mobile we will create a new Titanium
00:04Mobile project and work with the two-tab application that is presented as a starting template.
00:09Within Titanium Studio I will select File > New > Titanium Mobile Project.
00:18I will give the project a name.
00:21This name will appear as the app title on the device, as well, it will appear as
00:26the project folder title in the project explorer.
00:29I'll leave default location checked.
00:31Under Project Settings I will enter an App Id using a reverse domain name space.
00:37Here I will type com.lynda.ti0101.
00:42Now I'll enter URL.
00:44Note that this field is required.
00:47As of recording, this is the current version of the Titanium SDK, so I will leave it selected.
00:52In the Deployment Targets area I will leave iPhone, iPad, and Android checked.
00:58If you're only developing for one of these platforms, you can uncheck the others.
01:02Note that iPhone and iPad Deployment Targets are available on the Mac only.
01:07You can change the settings for the SDKs used in your Titanium project by
01:11choosing Setup/Configure SDKs.
01:14Later in the course I will return to this screen to make a change for one of my projects.
01:19Now I'll choose Finish.
01:22Titanium Studio will take a few moments to create the project files.
01:25When done, I am presented with a TiApp Editor window.
01:29Here I can see some of the values that I entered during project creation.
01:33If I want to later, I can edit and save these values for the project.
01:37Next to the TiApp Editor tab, is the tab for app.js.
01:42The app.js file is the starting point for all Titanium Mobile apps.
01:46Think of the app.js file as a home base for your application.
01:51All Titanium Mobile apps will launch code in the app.js file first.
01:55I won't make any changes to the code generated by the default project.
01:59Instead, I will choose Project > Clean, make sure the current project is
02:04selected, and choose OK.
02:08Now I'll select the Run As button at the top of the window.
02:12When prompted, I will select the Simulator to run the project on.
02:15I'll choose the iPhone Simulator.
02:19Keep in mind that it isn't uncommon for Titanium Studio to report build problems
02:24the first time you try to build your project.
02:26If you experience build problems, select Project > Clean, and follow-through as I did before.
02:31Then choose Run As to deploy your project to the Simulator.
02:35With the Simulator open, I can now interact with the default project code.
02:43The default application that Titanium Studio will create is a
02:46two-tab application.
02:48It's worth noting that an alternative to selecting Run As to deploy the
02:52Simulator is selecting Run from the Project Explorer or App Explorer.
02:57Under the Run button are options to specifically set and change the platform to test code on.
03:03Now that I've shown you the basics of getting started with a project I'll show
03:06you around the Titanium Studio workspace.
Collapse this transcript
Navigating the Titanium Studio workspace
00:00Titanium Studio is an integrated development environment that works as an
00:04all-in-one package for developing, testing, and building iOS and Android
00:09mobile applications.
00:10The main workspace of Titanium Studio is divided into four main areas.
00:15At the top left, you'll find the App Explorer and the Project Explorer.
00:20The App Explorer allows for the exploration and editing of a single app and its
00:24structure and content.
00:26All opened projects will appear under this dropdown.
00:31The Project Explorer allows for the exploration and editing of all projects
00:35created in Titanium Studio.
00:37I prefer this view for my projects and will be using it for the remainder of this course.
00:42At the top right, you'll find the main authoring area.
00:45When files are opened, they'll appear tabbed in this area.
00:49At the bottom left, you'll find the Samples and Outline tabs.
00:53The more important of the two is the Outline tab.
00:56It displays variables, functions, and methods in outline format.
01:01Finally, at the bottom right are several tabs of which the most important is the Console tab.
01:07When we render our apps to the Simulator, the Console will display lots of activity.
01:17Note that this is normal.
01:18Also, if there are any errors when we build our project, they'll be reported here.
01:25Speaking of errors, Titanium Studio does its best to constantly check for
01:29errors in our code.
01:31In the margin of the File Editor area, you may see a few different symbols.
01:36A red X indicates an error in our code.
01:39If you hover the mouse over the red X, you'll get information about the error.
01:43Sometimes the information is useful and instructive.
01:46Sometimes the error is confusing.
01:49If anything, the error lets you know that something is wrong.
01:52Discovering the problem may take some sleuthing and some patience.
01:56If your code does have an error, a red X will also appear on the icon for the
02:00parent file and the project folder.
02:03Titanium Studio really wants you to know that your code has an error.
02:08On rare occasions when I've used Titanium Studio, an error has been reported
02:12when none was actually present.
02:13I'm not sure why this happens.
02:15In these cases, I've gotten rid of the error marks by cutting the code in
02:19question and re-pasting it in place.
02:22A Minus sign in the left margin of the editing window indicates that a section
02:25of code may be folded.
02:27I won't be using this feature within this course.
02:30In the Titanium Studio preferences, I'll show you how to change the
02:33appearance of the code.
02:35I'll head to Titanium Studio > Preferences, then I'll double-click Titanium Studio.
02:42Now I'll choose Themes.
02:44Here I can set different appearance themes for the Titanium Studio workspace.
02:48Additionally, I can change the font in which the code is displayed.
02:52Your settings will be different than mine here, since I've already changed the
02:56font size and color palette to be easier to see.
02:59I've only scratched the surface as to what features Titanium Studio affords.
03:03Further exploration and experimentation over time will reveal more to you as you
03:07develop your mobile apps.
Collapse this transcript
Browser-based Javascript vs. Titanium Javascript
00:00While Titanium Mobile uses JavaScript, there are some important differences to be aware of.
00:05In Titanium Mobile, scripts are contained to the page in which they reside.
00:10This is similar to scripts on a web page being restricted to the
00:13currently loaded page.
00:15As with advanced techniques in browser- based JavaScript, there are certainly
00:19ways to incorporate external scripts into pages, in order to efficiently
00:23modularize code and reduce redundancy.
00:27As those opportunities present themselves in Titanium Mobile, I'll be sure to point them out.
00:33Browser-based JavaScript features the concept of searching the DOM for elements
00:37to manipulate with code.
00:38In JavaScript for Titanium Mobile, this is much simpler.
00:42There's no need to use getElementById or utilize a framework like jQuery to
00:47search the script for objects according to selection rules.
00:51Instead, Titanium Mobile uses constructor methods for windows, views, user
00:56interface elements, and other objects.
00:59In order to manipulate these objects, I'll simply reference their
01:02variable assignments.
01:04Finally, we want to be sure not to provide a broader scope for variables and
01:08functions than is absolutely necessary.
01:11This will help us to be sure that we don't accidentally create memory leaks or
01:15write code that causes our application to be sluggish.
01:19Now let's move on to some code.
Collapse this transcript
Detecting platforms
00:00It's a common need to test what platform code is being executed on in order to
00:05perform a specific task.
00:07This is especially true given that they are Titanium Mobile APIs that are iOS
00:11or Android specific.
00:13Throughout the movies in this course, I'll write code to detect platforms in one of two ways.
00:18The first way is to set a constant called Platform to the result of
00:21Titanium.Platform.osname and then use that constant within a
00:26conditional statement.
00:27The conditional statement tests for one of the possible results of
00:30Titanium.Platform.osname, iPhone, iPad, or Android.
00:35The second way I'll write code to detect platforms is to use the custom platform
00:39constant within a ternary operator that is part of a variable assignment.
00:44This is a shorthand method for writing a simple if-else statement.
00:47I find it especially useful for setting dimension and positioning properties
00:51because of the different screen sizes present between platforms.
Collapse this transcript
Editing run configurations
00:00It's important that I talk about configuring Titanium Studio to run applications
00:04with both the iOS and Android simulators.
00:07Most of the time, I'll be selecting the Run As button to launch an application
00:11in an iPhone simulator.
00:14Should there be a platform specific feature to show however, I'll need to change
00:17the simulator the project will run in.
00:20To do this, I'll make sure the Project folder is selected in the Project Explorer.
00:26Then I'll select the Run icon.
00:28Here I'm given more choices for launching the app.
00:32I'll select the Run Configurations option.
00:37Titanium Studio brings up a window that contains run configurations for every
00:41project I've launched.
00:43Note that the information you see in this window will probably look a lot
00:46different than mine, in that you've got your own projects that you may have launched.
00:51I'll select an item at the left to edit its run configuration at the right
00:55under the main tab.
00:58To launch this project using an earlier version of the iPhone SDK, I can select
01:02it from the iOS SDK dropdown.
01:05Note that the options for this dropdown and the one similar for Android will be
01:09filled according to your system's iOS and Android SDK configuration.
01:14After changing a run configuration, I'll choose Run at the bottom left of the window.
01:20This causes the selected run configuration to execute.
01:23Note that back in Titanium Studio, the Run As button will launch the most
01:27recently used run configuration.
01:31Now that I've shown you how to get started, it's time to dive into the Titanium
01:35APIs and start creating mobile apps.
Collapse this transcript
2. Windows & Views
Understanding Windows and Views
00:00At the heart of Titanium Mobile lie Windows and Views.
00:04Though they can seemingly be used interchangeably, it is important to point out
00:07an immediate organizational difference between the two.
00:11For our purposes, a Window is the highest level of organization for content.
00:16More simply put, a Window acts as the master container for all other content.
00:20A View on the other hand is one level lower in organization.
00:24In that it is a container for groups of content.
00:28Additionally, most of the UI elements featured in Titanium Mobile are
00:31themselves called Views.
00:33They are each with a much more specific purpose of use as suggested by its
00:37title. An easy rule of thumb for determining when to use Windows or Views, will
00:42be that I will only be using one Window at a time, and each Window will contain
00:46multiple Views that comprise the content of our application.
00:50To get started, I will create a new Titanium Mobile Project.
00:53I will give my project a name, an App Id, and a URL.
01:00Now choose Finish, I'll head to the app.js tab, and blank out the contents of the screen.
01:09And I'll save.
01:11The first thing I'll do is create a Window for our application.
01:14I will switch over to a completed state of the code and select the portion that
01:19will create a new Window.
01:22Now I will switch back over to Titanium Studio and paste the result.
01:27Here, I've created a new Window utilizing the Titanium.UI.createWindow method.
01:32I'm passing in an object that has the following properties.
01:36A title property set to a string Our window title, this title will only show on
01:41Android, on iOS it won't show.
01:43A backgroundColor set to a hexadecimal number within a string.
01:47It's an orangish sort of background, and an exitOnClose property for Android
01:51that will have the application closed when the Window is exited.
01:55The result of this method is assigned to a variable win.
01:59Now I'll open the Window by typing win.open with parentheses.
02:06Now that I've created a Window and opened it, it's time to add Views to our Window.
02:09I will switch back to the completed code and copy the portion that creates a View.
02:16Now back in Titanium Studio, I will paste it.
02:20Here, I am creating a View by using a Titanium.UI.createView method.
02:24I am passing in an object that has several properties.
02:28The first is the height property which is measured in pixels;
02:32this sets the height of the View.
02:33The second is a width property, set in relative measurements, this sets the
02:37width of the View, here to take up the full width of the screen.
02:41Next is a top property which sets the distance of the View from the top of the screen.
02:46After that, is a left property which sets the distance of the left of the View
02:50to the left of the screen, and finally a backgroundColor property, so that we
02:53can see the View, here it's set to purple.
02:56The result of this constructor is set to the variable view01.
03:00Now I'll add this View to our Window, win.add, and within the parentheses the
03:06name of the variable, view01.
03:15Beginning at line 15, I've pasted code that creates three more Views.
03:19Each with subtly different properties.
03:21For example, in view03, I have set an absolute measurement for the width of the
03:25View, and a background color that's a hexadecimal number within a string.
03:30Now I'll add these three Views to our Window.
03:33Underneath the line that added the first View, I will type win.add, and within
03:38the parentheses view02, win.add view03, and win.add view04.
03:49Now I'll render the application to the iPhone Emulator.
03:52Before I do that I will need to head to the Project and choose Clean, make sure
03:57that the current project is selected and choose OK.
03:59I will save the project.
04:01Now I will head to Run As, and select iPhone Simulator, and choose OK.
04:15Here I can see my application in the iPhone Emulator with the orange Window in
04:19the background and the four Views represented by different colors.
04:23Next, I'll show you how to incorporate text into your project by using a
04:26label View.
Collapse this transcript
Using the label view
00:00The label view allows for the creation of single and multiple line text.
00:04The text appearance can be styled in many ways, including its color, size and weight.
00:09I've created a New Titanium Mobile Project and have the app.js file open.
00:13I will switch to the completed code and copy the code necessary to create a Window.
00:20Now I head back to Titanium Studio and paste the code.
00:23I'll write code that will open the window, win.open.
00:28I'll switch to the completed code and copy the code necessary to create our label view.
00:35Now in Titanium Studio, I will paste the code.
00:39Here, I've created a new label view by using the
00:42Titanium.UI.createLabel constructor.
00:45This constructor is fed for an object with the following properties.
00:48The text property takes a string of text that will be displayed to the user
00:52of the application.
00:54The top, left, height and width properties should be used in order to position
00:58the label on the screen.
01:00The text align property sets the alignment of the text within the label view;
01:04options here include left, center and right.
01:08The color property sets the color of the text, here a hexadecimal number.
01:12And finally, I've added a background color property so that we can see the total
01:16width and height of the label view.
01:19Beginning at line 18, I've added three different labels to our application.
01:23Each of the labels is largely similar to the first that I created, but there are
01:27some subtle differences in the properties that are fed into their constructor's.
01:30Label02 features a text align property set to left.
01:34Label03 has a font property which takes an object that has font size and
01:39font style indicated.
01:42With label04 I am creating a label view by just using the text property, by not
01:46specifying any of the dimension or position properties of this label view, the
01:51label will appear vertically centered on the screen with the text aligned to the left.
01:56I've added the three new labels to the Window, by using the add method of the window object.
02:01I will save my file and head to Run As.
02:05And now the file will be rendered to the Emulator.
02:09Here, I see each of the four labels rendered to the window.
02:13Next, I'll show you how to implement images in your application using the
02:16image view.
Collapse this transcript
Using the image view
00:00Images are an essential part of any application.
00:03Thankfully, the image view allows for easy incorporation of both local and
00:07remote images in an application.
00:10I've created a new Titanium Mobile Application and I have written some code to
00:14create a new Window and open that window.
00:17Within my application, there is an images folder under Resources that I've created.
00:22This images folder contains two images, one titled exploreCalifornia.png and one
00:27titled exploreCalifornia@2X.png.
00:31The @2X suffix denotes an image that is twice as large and will be used for
00:35devices running iOS4 or higher.
00:38Switching over to our completed code, I will copy the code necessary to
00:41create an image view.
00:42I will switch back to Titanium Studio and paste the code.
00:48This code creates an image view using the
00:50Titanium.UI.createImageView constructor.
00:54At a minimum, we need to pass the image, height and width properties to the constructor.
01:00The image property contains a string that is a path to the image within
01:04the Resources folder.
01:05The height and width properties are the dimensions of the image in pixels.
01:09I've also specified a top value for this image.
01:13Now we need to add the image to the Window object.
01:16And I will save my progress so far by pressing Command+S or Ctrl+S on the PC.
01:22Let's take a look at what we have in the Emulator.
01:24First we will choose Project > Clean, and make sure the project is selected and choose OK.
01:30Then we will choose the Run As button.
01:39And within the Emulator, there's our image.
01:41Since I will be adding more code to our application, I will quit the Emulator,
01:45head back to Titanium Studio, and above win.add, prepare to paste more code.
01:50I will head back over to the completed code and copy the next code snippet to be used.
01:55And I'll paste it within Titanium Studio.
02:00Here, I am creating another image view with the same image I used before.
02:04But this time I have set the height and width to be different from the original
02:08dimensions of the image.
02:10Using the smallest dimension, Titanium will scale the image proportionally.
02:15Now I'll add the image to the Window.
02:25Save the file, head to the Project > Clean, and choose OK, and now choose Run As to
02:32view it in the Emulator.
02:36Overlayed atop the first image is the proportionally scaled second image.
02:40Titanium has used the smaller dimension property even though I specified a
02:44width of 150, which is the same as the first image.
02:48I'll quit the Emulator and create an image view that loads a remote image.
02:53I will head back to the completed code and copy the code snippet, and back to
02:59Titanium Studio and paste.
03:01The difference in using a remote image versus a local image is that a remote
03:06image utilizes a remote path and a local image uses a path local to the project.
03:13Now I need to add this image to the Window object.
03:15I will Save our file, choose Project > Clean, and choose Run As.
03:30At the bottom of the application window, we can see the Cycle logo has loaded
03:34from the Explore California site.
03:36Next, I will show you how to arrange elements front to back, using z-depth.
Collapse this transcript
Understanding z-depth
Collapse this transcript
Grouping and nesting Views
00:00Similar to the use of the div tag in html, nested views are helpful in
00:05providing block organization and positioning of visual elements within Windows
00:09or other parent views.
00:11Starting with the app.js file in the 02_ 05 folder of the exercise files, I have
00:16created a new Window object.
00:19Next, I will switch to the completed code and copy the code snippet for a new
00:23view to be added to the Window object.
00:25Now I'll add this view to the Window object.
00:31Once again, I'll switch to the completed code and copy some snippets to add to
00:35the newly created view.
00:36I will paste this code above line 16 with the views added to the Window.
00:43At line 16, I've created an image view and at line 24, a label view.
00:48Now I'll add these views to view01 by using view01 add method.
00:54It's important to notice that the positioning of the label and image views is
00:57relative to the parent view.
00:58I will take a look at the results in the Simulator.
01:02I'll save the file and then the project in the Emulator.
01:07The View is represented by the green background with the Image and Label
01:10view stacked on top.
01:12Now I'll close the Simulator and add some more views to the application.
01:20Starting at line 16, I've added three more views with slightly different
01:23properties for size, position and background color.
01:33At line 59, I've added the views to the Window object.
01:36I will head back to the completed code and copy the code snippet for each block,
01:41including the code to add images and labels to the parent view.
01:50I will save my file and take a look again at the result in the Simulator.
01:56Each of the Views is present with their respective images and labels showing.
02:01Adding elements to the Window is the first step in creating a useful
02:04mobile application.
02:06Next, we'll look at adding controls, input fields and the interactivity for an
02:10even richer user experience.
Collapse this transcript
3. Controls, Input & Interactivity
Listening for events
00:00To introduce interactivity into our application, we need to listen for different
00:04events fired by the various views in Titanium Mobile.
00:08While these events do vary from view to view, that means we're listening or
00:12subscribing to them is consistent across the different view types.
00:16Starting with the app.js file in the 03 _01 folder of the exercise files, I've
00:22created a new Window object with four image views and a label view added to it.
00:27I'll listen for a click event on each of the images by adding an
00:30EventListener to them.
00:32Here the click event is really a touch against the screen or a tap event.
00:36I'll head to line 47 to add the code necessary to attach an EventListener to image view 01.
00:45An EventListener takes two arguments.
00:47The first argument is the name of the event;
00:49the second is a callback function.
00:51Here I'll use an anonymous callback function.
00:56Notice that I've passed an E as an argument for the callback function.
00:59This is done so that I can easily access portions of the event object.
01:04I'll write some code that will return the path of each image, that path will be
01:08displayed in the Label view at the bottom of the screen.
01:11Upon each tap of the image, the path will be displayed in the Label view towards
01:15the bottom of the screen.
01:17To do this I'll need to set the .text property of the label view.
01:21To access the image property of the image view, I'll use the .source property
01:25of the event object to access the object listening for the event, which in this case is the view.
01:31Then I'll add the .image property of the source object to grab the path of the image.
01:36I'll repeat these steps for each of the remaining images.
01:40Now I'll take a look at the result in the Simulator.
01:46Notice that the entire absolute path to the image is returned with each click event.
01:51When this is running on a device, the path will be relative to the app.
01:56Within image 04's EventListener, I'll implement remove EventListener to remove
02:00the listener from image 01.
02:06The removeEventListener function requires a string for the event to be removed
02:09and a callback function, even if no actual callback is being implemented.
02:14I'll take a look at the result in the Simulator.
02:21Each of the image views reacts to a received click event.
02:25Notice that after image 04 is clicked, the listener for image 01 is removed.
02:29Next, I'll show you how to create both native and custom buttons to continue
02:33adding interactivity to your app.
Collapse this transcript
Creating buttons
00:00Titanium Mobile allows for the creation of both native and custom buttons.
00:05Starting with the app.js file in the 03 _02 folder of the exercise files, I've
00:10created a new window object.
00:12Next, I'll switch to the completed code and copy the code snippet for creating a new button.
00:17The Titanium.UI.createButton method creates a new button object.
00:22At a minimum, I have to supply dimension properties for the object or else the
00:26button will fill the entire screen.
00:27I've used the title property to display text on the button.
00:31I've also added a custom property called id to the button object.
00:35I'll be retrieving this property with an EventListener in a moment.
00:39With the button object created, I'll add it to the window object.
00:45Now I'll add an EventListener to the button and listen for the click event.
00:57Within the click event I'll create a callback to fire an Alert dialog, that will
01:02a return string containing the source, object's ID property, and the type
01:05property of the event itself.
01:07I'll cover Alert dialogs in more detail later in this course.
01:18Now I'll take a look at the result in the Simulator, when the button is
01:24clicked the Alert fires.
01:27Next, I want to create a button with a custom background.
01:30To do this I'll switch to the completed code and copy the code snippet for
01:34creating that button.
01:40Now I'll add the paths to images to be used for the backgroundImage and
01:44backgroundSelectedImage state of the button.
01:50I'll add customButton to the window object.
01:57I'll copy code to add an EventListener that will fire with a touchend event.
02:02Now I'll take a look at the result in the Simulator.
02:07It's worth noting that the device will resize the image to fit the size of the button.
02:12Next I'll add a slider control to the app to capture different sort of input.
Collapse this transcript
Creating a slider
00:00Sliders allow the user to finally select the number within a range of values.
00:05Starting with the app.js file in the 03 _03 folder of the exercise files, I've
00:10created a new window object.
00:12Next, I'll switch in the completed code and copy the code snippet for creating a
00:16new slider and label view.
00:19Notice that the min and max properties of the slider object have been set.
00:23These two properties set the minimum and maximum value for the slider.
00:27The label view on line 14 will display the output of the slider as it is changed.
00:32I'll add both the slider and the label view to the window object.
00:36I'll add an EventListener to slider1, and listen for the change event.
00:45The callback function I'll create, will write the value of the slider represented
00:48by e.value to the text property of results1.
00:53Now I'll take a look at the result in the Simulator.
00:58As the slider is moved, its value is represented in the results1 label view.
01:05I can implement a custom image for the background of the slider called the track
01:09or for the selection bar called the thumb.
01:11I'll switch to the completed code and copy the code snippet for creating a new
01:15slider with custom track and thumb images.
01:19As well, I'll copy and paste code that creates a new label to display the result.
01:24Next, I'll add the new slider and label to the window object.
01:34The thumb image property of the slider is used to set the image of the thumb.
01:38The highlighted thumb image property is used to set the appearance of the
01:41thumb when it's tapped.
01:43The left and right track image properties are used to set the track image on the
01:46left and right of the thumb position.
01:49Now I'll create an EventListener for slider2 that performs the same way as the
01:53listener for slider1, except that the output of the slider will be displayed
01:57in the result2 label.
01:58I'll take a look at the result in the Simulator.
02:07Notice that the slider thumb does not resemble the default slider thumb found in slider1.
02:11Also the left and right track images are revealed and hidden automatically as
02:15this slider thumb is moved.
02:19On Android I can implement the min range and max range properties of the slider
02:23to limit the movement of the slider thumb on the slider track.
02:26To do this I'll need to implement some device detection code so that the slider
02:30isn't created if the project is rendered for iOS.
02:33At line 43, I'll create code that assigns the current platform to a
02:37variable called platform.
02:39I discussed platform detection in an earlier movie in this course.
02:44Titanium.Platform.osname will return the current device platform with options
02:49being iPhone, iPad, and Android.
02:53Now I'll switch to the completed code and copy paste the snippet that will
02:57implement a slider and accompanying label if the current platform is Android.
03:02Notice that the min and max range properties are set above and below the values
03:06for the min and max properties.
03:08This will constrain the dragging of the thumb to the boundaries set by min and max range.
03:13I'll switch to the completed code and copy/paste the snippet that will attach
03:17an EventListener to these newly created objects assuming that the platform is Android.
03:24Now I'll launch the Android Emulator to view the result.
03:27To do this I'll click on Run in the Project Explorer and choose Android Emulator.
03:35Notice that with the Android specific slider the thumb doesn't move pass the min and max range.
03:43Next, we'll see how to create a switch for collecting yes-no or
03:46on-off responses.
Collapse this transcript
Creating a switch
00:00Switches allow the user to provide yes-no or on-off responses.
00:05On iOS, this results in a switch with on-off choices.
00:09On Android, developers are afforded a little more flexibility to style and label switches.
00:15Starting with the app.js file in the 03 _04 folder of the exercise files, I've
00:20created a new window object.
00:22Next, I'll switch to the completed code and copy the code snippet for creating a
00:27switch and accompanying label view to display the results of the switch change.
00:40Creating a switch simply requires positioning properties and a value for its initial state.
00:45Here set with the value property.
00:47Now I'll add the views to the window object.
00:50I'll add an EventListener to the switch that listens for the switches change event.
01:02I'll copy and paste the callback function that will set the text property of the
01:06results1 label with the value of the change event represented by e.value.
01:12I'll take a look at what I've got so far in the Simulator.
01:17As the switch is changed, the value is displayed in the results1 label.
01:22Note that an iOS, the value of the change is 1 or 0.
01:26On Android the value is True or False.
01:30On Android there are few more options for the Switch view.
01:33First, I'll implement code to detect the current platform.
01:43Then I'll write a conditional statement that creates switches when the Android
01:46platform is detected.
01:52Now I'll copy and paste code for creating a new switch and label.
02:00Notice that the style property of the switch is set to
02:02Titanium.UI.Android.SWITCH_STYLE_CHECKBOX.
02:09This is a constant within Titanium Mobile that allows for the setting of the
02:13style of the switch.
02:15Now I'll add the new switch and label to the window object using a
02:18conditional statement.
02:26Lastly, I'll add an EventListener to the new switch and label that is similar to
02:30the one created for switch1.
02:33Let's take a look at the result in the Android Emulator by choosing Run from
02:36the Project Explorer.
02:46Instead of a Toggle button, switch2 displays as a check box.
02:49There is another customization to switch1 that I can make.
02:53By adding the title on and the title off properties to the switch, I can change
02:57the on-off values displayed to the user.
03:09I'll take a look at the changes in the Android Emulator.
03:15Notice that the value displayed on the switch is the string that I specified
03:18for the true value.
03:20When I change it, since the value becomes false, the button displays Nope.
03:26The actual value of the switch however remains true or false.
03:30Next, I'll show you how to add multiple option selectors to your app with a
03:34single-column picker.
Collapse this transcript
Creating a single-column picker
00:00Pickers allow for the selection of a single item amongst an array of choices.
00:05While the method for creating a picker is the same regardless of platform
00:09within Titanium Mobile, their visual representation is quite different in iOS and Android.
00:15Starting with the app.js file I've created a new window object.
00:19From the completed code I'll copy and paste the code needed to create a picker object.
00:27Notice that in addition to the sole position property for the picker, I set the
00:31selection indicator property to true.
00:34This will display the blue translucent bar over the current selection in the
00:37picker when viewed on iOS devices.
00:41I'll add the picker to the window object.
00:46Right now, the picker isn't populated with any data for the user to select.
00:50To populate the picker, we'll create an array of picker row objects.
00:55To save time, I'll copy and paste the array of picker row objects.
01:00At a minimum, each picker row object needs an object that has a title property set.
01:06The title property represents the text that the user will see within the picker.
01:10I've also added a custom val property for the value that will be returned when
01:14the row is selected.
01:15I'll add the array of picker objects to the picker by using the picker's add method.
01:20Now I'll create a label called results that will display the result of a picker selection.
01:27I'll add this label to the window object.
01:33To grab the value of the picker selection, I'll need to add an EventListener to
01:37the picker and listen for the change event.
01:41For the callback function, I'll set the text property of the results label to the
01:45title and value of the picker row selected.
01:49Let's have a look at the result in the Simulator.
01:53As the picker changes, the selected row title and value are reflected in the result label.
01:59It bears mentioning that the default picker in Android does not look like a
02:02typical iOS spinner.
02:04In the next movie we'll look at implementing the use spinner property to achieve
02:08the similar look within Android.
Collapse this transcript
Creating a multi-column picker
00:00Multi-column pickers allow for the selection of multiple items amongst a
00:04distinct array of choices.
00:06The method for creating a multi-column picker follows closely with the method for
00:10creating a single-column picker except that the columns property of the picker
00:14object is populated with an array of titanium.UI.createPickerColumn objects.
00:20Starting with the app.js file, I've created a new window object; a picker and a
00:25label called results.
00:27Notice that I've set the useSpinner property of the picker to true.
00:30I'll be creating a two column picker.
00:33To start I'll need to create each of the picker columns using
00:36titanium.UI.createPickerColumn.
00:44Because it will have content that's a bit wider, I've set the tour property of
00:47the tour column to 200 pixels wide.
00:51Before I start to add rows to the columns, I'll copy and paste code that creates
00:55two arrays of objects that contain title and val properties.
01:00In order to most efficiently add rows to the columns I'll use a for loop.
01:05This loop iterates over each of the arrays and creates a row using the add row
01:09method of the column.
01:11Then it feeds the arguments that create picker row needs by accessing the title
01:16and val properties of the current array index.
01:21For loops are covered in JavaScript Essential Training, here in the lynda.com
01:25Online Training Library.
01:28Now that the rows have been added to the picker column objects, I'll add
01:31the columns to the picker by setting the columns property of the picker
01:35with an array that contains the picker columns, as they are to be
01:38displayed, left to right.
01:42I'll listen for the change event of the picker in order to display the selected
01:46value in the result label.
01:48Since I'm using columns, I'd like to display a specific result if the user
01:52selects Taste of California from the left column. To do this, I'll code a
01:56condition to test for the first column.
02:02Then I'll test for the value taste as returned by the column rows val property.
02:10When the value is returned as taste, I'll set the text property of the results
02:14object to a string, Taste of California specifically selected.
02:23If I make a selection that is from the second column, I'll simply set the text
02:28property of the results object to a string that grabs the values from both
02:32columns, as represented in the selected value property of the event object.
02:40Here the left column is accessed via the 0 index of the selected value property
02:45the right column is accessed via the 1 index of the selected value property.
02:50Notice that within the string the text \n creates a new line within a label view.
02:56Now I'll take a look at the results in the Simulator.
03:00If I select the taste of California from the left column, I see the specific
03:04text in the results label.
03:06If I select any of the values from the right column, the results label
03:10displays the title and value from both columns selected with each column on its own line.
03:16When the result is viewed in the Android Emulator, notice that the use spinner
03:19property of the picker has formatted as spinner style picker.
03:24Using a multi-column picker is great for pre-populated choices to let a user
03:29select more free-form information, such as a date.
03:32I'll add a date/time picker in the next movie.
Collapse this transcript
Creating a date/time picker
00:00A common usage of pickers in mobile applications is the ability to select date or time.
00:06The type property of the picker object allows for the specific styling of the
00:09picker so that it specifically serves this purpose.
00:13Starting with the app.js file, I've created a new window object with the picker
00:18object and a label called results.
00:20As with our previous picker examples, the picker is listening for its
00:24change event and we'll set the text property of the results label with the selected value.
00:29The type property of the picker object needs to be set to
00:31titanium.UI.PICKER_TYPE_DATE;
00:37this enables a date time picker.
00:41I'll be setting the min date and max date properties of the picker to establish
00:45a range of valid dates.
00:47Note that these properties only work completely on the iOS platform. Before I do
00:51this, I'll create two instances of the JavaScript date object with the year,
00:55month and date properties set.
00:58It's important to note that the set month method of the date object, accepts a
01:02number for months, where each month is one less than its actual number.
01:07So to set November, which is normally the 11th month, I'll set the number 10
01:11instead, this is because the counting of months in JavaScript starts at zero and
01:15progresses to 11 giving us 12 months.
01:18I'll also be setting the value property of the picker so that its initial value
01:22is set to for November 1, 2011.
01:28I'll take a look at the results in the Simulator.
01:34November 1, 2011 is set, as well as an example of the min and max range
01:39properties -- the farthest I can spin the year column is 2011 and 2020.
01:45If I try to spin before and pass these dates, the spinner animates to the
01:49closest valid year.
01:52Before moving on, I'll copy and paste some comments that reveal the other options
01:56for the type property of the picker object.
02:01All of the pickers constants, except titanium.UI.PICKER_TYPE_PLANE take
02:07JavaScript date objects for the min and max range properties and the value
02:11property for the initial value setting.
02:14Next, we'll look at collecting text input from the user via text fields and
02:18text areas.
Collapse this transcript
Creating text fields and text areas
00:00Text fields are meant to allow the user the ability to enter small amounts of
00:04text, similar to the subject line of the web-based email application.
00:08Text areas differ from text fields, and that they allow the user to enter large
00:12amounts of text, similar to the body of a web-based email application.
00:17Starting with the app.js file in the 03 _08 folder of the exercise files, I've
00:22created a new window object.
00:24Next I'll switch to the completed code and copy the code snippet for creating a text field.
00:29Notice that I can use the border style property to style the border of the text
00:33field for iOS devices.
00:35The hint text property displays helpful text to the user about the text field's use.
00:39This text will disappear upon the focus of the field.
00:43I'll add the text field to the window object.
00:48When the text field grabs focus, a keyboard will appear on the device.
00:52In order to hide the keyboard upon clicking outside the text field, I'll need to
00:56add an eventListener to the window object.
01:01The callback function for this listener will cause the text field to lose
01:04focus by using the blur method of the text field object, thereby hiding the
01:09keyboard from the user.
01:10Now I'll take a look at the result in the Simulator.
01:16When I click the text field, the keyboard shows, when I start to enter text, the
01:21hint text disappears.
01:24If I remove all of the text, the hint text reappears.
01:28Next, I'll switch to the completed code and copy the code snippet for
01:32creating another text field.
01:35I'll add the text field to the window object.
01:41I'll also remember to implement the blur method of the text field within the
01:44Windows event listener.
01:47Now I'll switch to the completed code and copy the code snippet for creating a text area.
01:54It's worth noting the suppress return property has been set to false, so that
01:58the Return key on the keyboard can be used for line breaks and not to hide the keyboard.
02:03Also the value property has been set, so the user can see text in the text
02:07area before it's used.
02:08I'll add the text area to the window object.
02:14I'll also utilize the text area's blur method within the window object's
02:18listener to hide the keyboard when the text area is not being edited.
02:24I'll create two event listeners for text area.
02:27The first is a listener for the focus event;
02:29this will fire when the user taps the text area.
02:32The second is a listener for the blur event;
02:35this will fire when the text area loses focus.
02:38Notice that within the focus event there's code to detect a change in the text
02:42area's value property.
02:44If the value property hasn't changed, I'll wipe it out by setting the value
02:48to an empty string.
02:50Within the blur event, I've added code to detect if the value property of the
02:53text area is empty, if it is, it means that the user hasn't made any changes to
02:58the text area and the original prompt should be restored.
03:01I will take a look at the results in the Simulator.
03:05When I click the text area, the text will disappear.
03:08I can start to add text and when I click outside of the area the keyboard hides.
03:15If I click the text area again and wipe out the text, the original prompt is displayed.
03:20Next I'll show you how to enhance the user experience of text fields and text
03:23areas by changing the keyboard type.
Collapse this transcript
Configuring text field and text area keyboard types
00:00Text fields and text areas can be configured so that the user is restricted to
00:05specific types of data entry.
00:07Starting with the app.js file, I've created a new window object with a text field.
00:13The Window also has an eventListener that hides the keyboard when the text area loses focus.
00:19The keyboard type property of a text field, or text area, will set the keyboard
00:23to be used once the element is in focus. There are several keyboard type options
00:27that could be used.
00:29I'll set the keyboard type property to Titanium.UI.KEYBOARD_DECIMAL_PAD,
00:36I'll copy and paste comments that display the other available options for this property.
00:43Now I'll take a look at the results in the Simulator.
00:48Upon selecting the text field, the decimal keypad is presented. I'll exit the
00:53Simulator and implement a different keyboard type.
00:55I'll want to be sure to change the keyboard type property to correspond with the
01:00type of data available with the new keyboard type.
01:04Now I'll take a look at the results in the Simulator.
01:09A different type of keypad is shown, this one is geared toward use with URLs and
01:14email addresses. Presenting the user with context-sensitive keyboards can
01:19improve the user experience significantly.
Collapse this transcript
Creating text fields with embedded buttons
00:00In iOS, text fields have the ability to feature buttons within the field at the left or right.
00:06Starting with the app.js file, I've created a new window object with a text field.
00:12The Window also has an EventListener that hides the keyboard when the text area loses focus.
00:17I'll copy and paste a code snippet that creates two buttons.
00:24To add these buttons to the text field, I'll set the left button and right button
00:28properties of the text field object.
00:34Now I'll add EventListeners to the buttons.
00:37For the Clear button, I'll add a listener for the click event.
00:43I'll create a callback function that clears the text field by setting its
00:46value to an empty string.
00:51For the Submit button, I'll add a listener for the click event.
00:58I'll create a callback function that checks to see if there's a value in the text field.
01:04If there is, an alert will appear with the value, if there isn't, the alert will
01:12prompt the user to enter some text.
01:18Note that because these two buttons have been added to the text field, they
01:22don't need to be added to the Window.
01:25Now I'll take a look at the results in the Simulator.
01:30I'll enter some text in the text field.
01:36When I press Clear the text is cleared and the hint text reappears.
01:42When the Submit button is pressed the value of the text field appears in an alert.
01:48If I try to submit the text field, or it's empty I'm prompted by the alert
01:52to enter some text.
01:55Next I'll show you how to introduce interactivity into any view in your app.
Collapse this transcript
Adding interactivity to any view
00:00You may have noticed in working with the Titanium Mobile documentation that any
00:04view can fire events to be listened to.
00:06Probably the most common event to listen for is a click event, really a tap.
00:11Just as we did with simple and custom buttons, we can broadcast view events
00:15and act on them easily through the addition of an EventListener on the view in question.
00:19Starting the app.js file, I've created a new window object with a view that
00:24contains an image and a label view, and a separate label view called results
00:28that is added to the window object.
00:31I'll add EventListeners to the window object, the view object, and the views
00:34within the view object.
00:40The image, label, and view objects will listen for the touchend event.
00:44For callback function, I'll create a method called touchHandler that they'll all share.
00:54The touchHandler function will set the text property of the results label view
00:57to a string that consists of the ID property of the object that fired the event
01:02and the text was tapped.
01:04The window object will listen for the touchMove event and call the
01:07touchMoveHandler function for a callback.
01:13The touchMoveHandler function sets the text property of the results labeled to
01:17the X and Y of the touch.
01:18If the Y position of the touch is greater than 54 pixels, the X and Y of the
01:24touch event are measured in terms of absolute position of the touch on screen.
01:2700 is the top left-hand corner of the screen.
01:32Let's take a look at the results in the Simulator.
01:37As I touch elements within the view, the touchHandler method is fired.
01:41As I touch the window more than 54 pixels from the top, the X and Y of the touch is returned.
01:47The touchEnd and touchMove events allow for some fantastic interactivity in a
01:51mobile app, ranging from creating a bird flinging game, to scrolling content on
01:55the screen in X and Y directions.
Collapse this transcript
Reviewing the cycle of creation
00:00In recapping what I've shown you so far, it's helpful to consider best practices
00:04for the creation of Views and their associated EventListeners.
00:07Within Titanium Mobile, a well organized and logical execution cycle is
00:12represented by object creation in the following order.
00:15First, a window object is created and its open method is called.
00:20Then before the call to the window objects open method, views are created and
00:24then subsequently added to the window object.
00:27If you're grouping views, the parent view is created and added to the window
00:31object, while the child views are created and added to the parent view.
00:34If there are any helper or utility functions needed, for example, a named
00:40EventListener callback function they're created next.
00:43If an object is to listen to an event, an EventListener is attached to the
00:46object with a callback function implemented as needed.
00:50Finally, the project is launched in the Emulator or device for testing.
Collapse this transcript
4. Tab Group
Understanding tab groups
00:00The default project in Titanium Mobile is one that utilizes a tabGroup.
00:05These sorts of applications are quite common, in fact one example is the iOS YouTube app.
00:11Apps that use tabGroups for their primary structure are convenient in that
00:14each tab can act as its own execution context for content and interactivity.
00:20This means code can be modularized and implemented using separate JavaScript files.
00:25There's a downside to this in that variables are not freely available outside
00:29their execution context.
00:31Also in the past there have been memory management issues with Titanium Mobile
00:35and tabGroups that use separate JavaScript files for each window within a tab.
00:40Appcelerator reports this is no longer a problem, but it certainly does remind
00:44you to use proper coding techniques when wanting to implement this particular UI element.
00:49Another benefit of utilizing a tabGroup is that windows opened within a tabGroup
00:53will automatically feature nested navigation.
00:56This sort of drilling down to the data that you want is really common.
01:00Back buttons that take the user to the previous page, are generated
01:03automatically within a tabGroup.
01:05Of course, if there's only one content area in an application but that area
01:10has lots of content to drill down to, perhaps via tables, it can seem
01:13pointless to use a tabGroup.
01:15Later in this chapter, I'll show you single-tab tabGroup applications and a few
01:20hacks that are useful to employ in order to gain functionality without losing
01:24time in development.
01:25Starting with the app.js file, I've set the background color of the
01:29application to black.
01:31I've also created a tabGroup object, and I've opened the tabGroup using an open
01:35method of the tabGroup object.
01:38This is very similar to how we've been creating Windows for our applications.
01:41The difference here is that we're using tabGroups where windows once were at this point.
01:46Lastly, keep in mind that the default project for Titanium Studio is a
01:50two-tab application.
01:52I'll create two tabs, a Tours tab, and the Specials tab.
02:00Notice that the title property at the tabs has been set to Tours and Specials.
02:05The title is the text that will appear at the bottom of the tab.
02:08I've also set the image property of the tab to the two images I created that are
02:12located within the Resources folder.
02:14I'll add these tabs to the tabGroup using the tabGroup's addTab method.
02:22For the Tours tab, I'll create a new window object and assign it to the
02:26Tours window variable.
02:28Now I'll set the window property of the Tours tab to this Tours window object.
02:33Doing this links the window to the tab, so that when the tab is selected,
02:37the window is open.
02:39For the Specials tab, I'll do something a bit different.
02:42I'll create a window object and assign it to the specialsWindow variable.
02:48For this window, I'll set the URL property of the window object, so an external
02:52JavaScript file can be used for the window.
02:58I'll type the file name, specials.js for this property and then create the file
03:02in the Resources directory of the project.
03:09To create the specials.js file, I'll click on Resources within the Project
03:13Explorer, then File > New > File, and type specials.js.
03:23Upon creation, the file is presented for view.
03:26Within the specials.js file, I'll copy and paste a code snippet that will
03:30prepare the external file for use.
03:35By setting the win variable to Titanium .UI.CurrentWindow, I'm now able to add
03:40views to this window and have them appear within the Specials tab.
03:44Now I'll create a simple label and add it to the view.
03:50Notice that I do not have to call this window's open method.
03:54The window and its contents are opened by the Tab view.
03:57Before looking at the results in the Simulator, I'll create and add an image and
04:01a caption to the Tours window using an Image view and a Label view.
04:08Let's take a look at the results in the Simulator.
04:13Two tabs are present with the title of each of the windows reflected in the nav
04:17bar at the top of the window.
04:19The Tours tab features a window that has an image and a caption, while the
04:23Specials tab features a window that is loaded from an external JavaScript file.
04:27The JavaScript file contains a single label view.
04:31Next, I'll customize the tabGroups to change their appearance.
Collapse this transcript
Customizing tab groups
00:00While most of the focus on using tab groups is in the content each tab presents,
00:05there are a few customizations that can be applied to the tabGroup.
00:08Starting with the app.js file, I am using the Finish state of exercise 04_01
00:14as a starting point.
00:15One of the most basic tab customizations, which I have already shown you is the
00:19changing of the tab's image.
00:21This is accomplished through setting the icon property of the tab.
00:25For iOS, a size of 30x30 pixels is appropriate for the icon, 60x60 for the app to excise.
00:33For Android, the size of the icon will vary according to the size of the screen resolution.
00:37So 30x30 pixels is a good starting place but a bigger size such as 60x60 maybe
00:43appropriate for some devices.
00:45Since the window object we're using is housed within a tab, we can use a few
00:50more of its properties to affect its appearance.
00:52On iOS, setting either the bar color or bar image properties will effect the
00:57background color of the navBar, or set an image instead of a navBar title.
01:02In the specials.js file, I will implement a bar color property and will skip the
01:06bar image property for the window object.
01:12Let's take a look at the result in the Simulator.
01:19Tabs can also be changed programmatically via the tabGroups' setActiveTab method.
01:24I will attach an EventListener to the caption in the first tab in the app.js file.
01:33I will create a callback that we use the tabGroups' setActiveTab method, with
01:37the tab's index to change the tab.
01:43Note, that the tabs are numbered beginning at 0, with 0 being the first tab.
01:48Let's take a look at the result in the Simulator.
01:52As I click the caption, the app switches to the second tab.
01:57In the next movie, I'll show you a commonly used and accepted hack for taking
02:01advantage of the tabGroups navigational structure by setting up a single
02:05tabGroup.
Collapse this transcript
Working with a single tab group
00:00In order to drill down from one window to the next, and the styles similar
00:04to that found in other mobile applications, we will want to utilize a single tabGroup.
00:08The technique we will look at is admittedly a hack, in that it involves bending
00:12the functionality of the API in order to achieve an outcome.
00:16However, it is a frequently recommended method found in the Titanium Mobile forums.
00:21Starting with the app.js file, I have created a tabGroup with a window and an image view.
00:27Hiding the navBar and tabBar is quite easy.
00:30We're going to set the navBar hidden and tabBar hidden properties of the window to true.
00:35As their name suggests, this will hide the navBar and the tabBar from view.
00:40Let's take a look at the result in the Simulator.
00:45There's the image view with no tab or navBar showing in the window.
00:49Android developers, I hate to break the bad news to you, but this technique
00:52only works for iOS.
00:54The tabBars simply can't be hidden on Android.
00:57This may seem like a pointless exercise, but we will be using this technique in
01:00the upcoming chapter on tableViews.
01:02As you will see soon enough, when a tableView row is selected, this method will
01:06enable a Back button with the previous window title for each level we drill
01:10down, thereby saving us the time and hassle, of creating our own animations,
01:15window loading and unloading, and button manipulation.
01:18Trust me, this little tip will save you time in the long run.
Collapse this transcript
5. Table View
Getting to know the Table view
00:01Tables are a staple of many mobile applications.
00:04In this chapter, we will be looking at the Titanium Mobile APIs for creating,
00:08modifying, and interacting with tables and their rows.
00:12Before we start however, it's important to note how we'll be implementing tables
00:15within the application.
00:16We will be utilizing the hidden single tab application technique mentioned at
00:21the end of the last chapter.
00:23The reason for this is that atleast within iOS, we want the ability to open
00:27new windows by sliding the parent table to the left and the new window content to the right.
00:32On Android, this will mean that we can use the device's hardware back button to
00:36head back to the main table, or previously open windows, if the user has drilled
00:40down from other windows.
00:42If we didn't utilize the hidden single tab application technique for hosting our
00:45tables, we have to resort to using an iOS-only navigation group UI, which would
00:51then leave out the Android users, or we'd have to write our own animations for
00:55sliding the table left and opening the windows.
00:59Starting with the app.js file in the 05_ 01 folder of the exercise files, I have
01:04created a single tabGroup with a window, a table and code that will open a
01:08window upon table row selection.
01:10I will be covering the creation of tables, rows and opening windows from table
01:14rows in more detail as I progress with the chapter.
01:18Let's take a look at what I've got in the Simulator.
01:21As you can see, a table with a few rows is presented.
01:25As I tap the table row, the tables slides to left and a new window is presented.
01:30Notice also that on iOS the previous window's title is the title for the back button.
01:35To navigate back to the main table, I'll tap the Main Window button on iOS, or
01:39select the hardware back button on Android.
01:43This basic structure of navigation will form the foundation of how I will create
01:46tables, rows, and their accompanying windows for the remainder of the course.
01:50In the next movie, I'll show you how to quickly and efficiently create a
01:53simple table.
Collapse this transcript
Creating a simple table
00:01Titanium Mobile makes it easy to create a simple table by utilizing a data
00:05source in the form of an array of objects that have specific properties.
00:09Starting with the app.js file in the 05_ 02 folder of the exercise files, I have
00:14created a single tab application, with a window that has its tabBar hidden
00:18property set to true.
00:21Before I create the tableView, I will create a data source for the rows.
00:26This data source is an array of objects.
00:29Each of the objects has a title property, a leftImage property, className
00:33property and optionally, a hasCheck, hasDetail or hasChild property.
00:39The title property will set the text visible to the user in the row.
00:43The leftImage property will set the image that will appear at the left of each row.
00:47Note that I have already prepared images for this table and I have placed them
00:50in an images folder that I created, in the project's Resource folder.
00:54The most important property here is the className property.
00:57This property is used to set a name that will help Titanium to process rows that
01:02have a similar structure.
01:04Here, the row structure is an image at the left, a title and an optional check
01:08or a marker at the right.
01:10Since all of the rows follow this pattern, we will assign each of them the
01:14same className value.
01:15If one of the rows had an image in the middle however, we wouldn't assign it the
01:19same class name as its row structure would be fundamentally different.
01:22Right now, I'll stick to implementing the same kind of structure throughout the table.
01:27Now, I'll create the tableView.
01:31To add rows to the tableView, I will simply set its data property to the array I just created.
01:37Before viewing the result in the Simulator, I will remember to add the tableView
01:40to the window object.
01:44Now, I'll take a look at the result in the Simulator.
01:47Here, we see each of the rows with left images, titles, and checks remarks
01:52towards the right, if the object for the row indicated them.
01:56In the next movie, I will show you how to create more complex table rows by
01:59introducing views into the table row structure.
Collapse this transcript
Creating custom table rows
00:00Each row in the tableView is a view itself.
00:03This means, that like regular blank views, we can implement other views within a tableView row.
00:09Starting with the app.js file, I've created a single tab application with a
00:14window that has its tabBar hidden property set to true.
00:17I will be creating a table that has rows that contain large images with
00:21captions, and Views that act as backgrounds for each caption.
00:25To do this efficiently, I will create an array of custom objects that will act
00:29as a model for each row.
00:31Each object will contain an image property shortened to img, a title property
00:36and an amount property.
00:38Now that I've created the model for the table row contents, I will create an
00:42empty array for the rows themselves.
00:44The idea here is that I will iterate through the custom object array and create
00:48row components according to the custom object properties.
00:53To iterate over the data array, I will create a for loop that progresses from
00:570 upwards, as long as the incrementing variable I is less than the length of the array.
01:05Within the for loop, I will create for views and finally a tableView object.
01:11The first view is an ImageView.
01:12I will set the image property to the img property of the model.
01:16I will also add the dimensions of the image.
01:21The next view is a plain view that has a black background color, this view will
01:26act as a background for the text that will appear on top of it.
01:28I will also set the opacity to 0.6 so that it is translucent.
01:34Note that opacity values are from 0 totally transparent, to 1 totally opaque.
01:40Lastly, all of the dimension and positioning properties will be relative to the
01:44containing table row that I will create in a moment.
01:46I will next create a label view that we will use for its text property; the
01:50title property of the model.
01:51I will also set some positioning, dimension, and appearance properties.
01:57The last view I will create is a label that we will use for its text property,
02:01the amount property of the label.
02:05Since this amount is intended to be read as dollars, I've added a dollar sign to
02:09the beginning of the property.
02:11Now that all of the views have been created, I'll create a row object.
02:19The row object is in the end what the tableView expects for table rows.
02:23Here I will set the height property of the row object to auto so that the row
02:27will expand vertically with the supplied contents.
02:30I will need to add all of the created views to the row object so that they can
02:34be displayed to the user.
02:36This is similar to the now familiar practice of adding views to a window or a view.
02:41In fact, that's one way to think about the tableView row object.
02:44It's a sort of view that can contain other views.
02:50This last step is really important.
02:52I need to push the row object into the array created at line 33.
02:57If I don't, I won't be storing the row objects for the table to use in a moment.
03:03I'll create a tableView and set its data property to the array that contains
03:08the tableView row objects.
03:10I will add the tableView to the window object.
03:18Let's take a look at the results in the Simulator.
03:22Each of the rows has an image, a background for the caption, a caption and a dollar amount.
03:27If you're wondering why I created the caption and amount separately, it was to
03:32specifically justify one left and one right to the table row.
03:38Before moving on, I will add an EventListener to the table and listen for the click event.
03:46For the callback, I will create a function that just returns the source of the
03:49click in an alert dialog.
03:54Let's take a look at the results in the Simulator.
04:00Notice that the views within the row are returned as the source of the click.
04:05This means that by using e.source, we can access each of the rows' view objects
04:10and their properties easily.
04:12In the next movie, I will show you how to open new windows by interacting with
04:15a tableView row.
Collapse this transcript
Opening windows from rows
00:00A common design of mobile applications is the display of table entries with the
00:04option to open up a Window of content that displays additional information
00:08about a particular entry.
00:09With our tab-based application, this is accomplished simply through the addition
00:13of an EventListener to a row.
00:15Starting with the app.js file in the 05 _04 folder of the exercise files, I've
00:20created a single tab application with a window that has its tabBar hidden
00:24property set to true.
00:26I'll create an array of objects to use for the creation of tableView rows.
00:32The title, left image, class name, and hasDetail properties will be used as
00:37I've shown you earlier in this chapter.
00:39Notice that the Snowboard Cali object has additional JS and dataToPass
00:44properties. Later in the movie, we'll be using these properties to open an
00:48external JavaScript file.
00:50Now I'll create a tableView and set its data property to use the array of
00:53objects created at line 20.
00:58Finally, I'll add the tableView to the window object.
01:02I'll set the tableView to listen to the click event.
01:06For the callback I'll create a function that will test whether or not the table
01:10row object contains the hasDetail property.
01:13If the row has this property a new window will be loaded.
01:17If the row doesn't have this property, an alert will show that there is no window to load.
01:21Within the first part of this condition I'll create another that tests for the
01:25existence of a .JS property in the tableRow object.
01:29If the property exists I'll create a new window object and set it's URL
01:33property to the JS property.
01:35Additionally, I'll pass data to this new external window through the custom
01:39dataToPass property of the window object.
01:43If the JS property does not exist I'll create a new window object and label
01:47view, and add the label view to the newly created window object.
01:51Since I'm using the same variable for both of the window objects, I'll call the
01:55tabs open method in order to open the newly created windows.
02:00The first argument of the open method is the window to open.
02:04The second argument is an optional object that contains an object with
02:07an animation property.
02:09This property will set the current window to slide left when the new window is opened.
02:13I'll now create the external JavaScript file referenced by the Windows URL
02:17property at line 46.
02:22In the external.js file I'll create code that will set a variable win to be
02:27the current window.
02:30Now I'll create a label view and set its text property to the dataToPass
02:34property of the window object.
02:36This property was set in app.js line 45.
02:44Before looking at the results in the Simulator I'll add the label to the window object.
02:51Three of the rows have markers at their right.
02:53When these rows are selected, the window slides to the left, and the new window opens.
02:58When the Snowboard Cali row is selected the same happens, but remember that the
03:02content is loaded from an external JavaScript file.
03:06In the next movie I'll show you how to display headers and footers in
03:09tableViews.
Collapse this transcript
Modifying row headers and footers
00:00Headers and footers are used in order to more conveniently group and
00:03organize table rows.
00:05Starting with the app.js file in the 05_05 folder of the exercise files, I'm
00:10starting with the finished state of exercise 05_04.
00:13To add headers or footers to tableViews, I'll add a header or footer property to
00:18selected objects in the data array at line 20.
00:22Now I'll take a look at the result in the Simulator.
00:26As I navigate the table view, the headers and footers move with the rows.
00:30In the next few movies I'll show you how to add, update, delete, and move rows.
Collapse this transcript
Adding rows
00:00At some point you'll need to add or insert rows into your tableView.
00:04Starting with the app.js file in the 05_06 folder of the exercise files, I'm
00:09using the finished state of exercise 05_02.
00:12I'll code an EventListener for the tableView that will append a new row at the
00:16end of the table when any row is clicked.
00:24For the callback function I'll create a new tableView row with the title
00:27property set to Row added.
00:47Then I'll call the appendRow method of the tableView with the newly created
00:51row as the argument.
00:54Let's take a look at the result in the Simulator.
01:01As I click rows, new ones are added to the end of the tableView.
01:10This even happens if I click the newly created tableView rows.
01:16This is because the EventListener is attached to the tableView and there's no
01:20further filtering via code with the callback function.
01:23Now I'll modify the callback to insert rows after the third row,
01:27California Hotsprings.
01:31I'll comment out line 42, then I'll call the insert row after method of the
01:37tableView, and feed is the first argument - The index of the row to insert after.
01:43Here index 2, the third row.
01:48Let's take a look at the result in the Simulator.
01:55As I click the tableView row, new rows are inserted after the third row, index 2.
02:04It's worth mentioning that there's also an insert row before method that does just that.
02:08It inserts rows before the provided index.
02:11Now that I've shown you how to add insert rows I'll show you how to update them.
Collapse this transcript
Updating rows
00:00The ability to update tableView rows allows you to change data in table rows.
00:05This is useful for displaying information from a data source.
00:08Starting with the app.js file in the 05_07 folder of the exercise files, I'm
00:13starting with the finished state of exercise 05_02.
00:17I'll code in EventListener that will update a row when it is clicked.
00:29For the callback function, I'll create a new tableView row with the title
00:33property set to Row updated, then I'll call the Update Row method of the
00:50tableView with the index property of the event as the first argument, and the newly
00:54created row as the second argument.
00:56E.index will return the index of the row being clicked.
01:00Let's take a look at the result in the Simulator.
01:07As I click on each row, it's updated to reflect the new row object.
01:14If you want to change all of the rows in a tableView at once, you can use the
01:17tableView's Set Data method to update the data source for the table.
01:22I'll comment out lines 38 to 42.
01:31I'll create a quick and simple array of objects to be used with the Set Data
01:35method of the tableView, then I'll call the Set Data method with the new array
01:57of objects fed as an argument.
02:09Let's take a look at the result in the Simulator.
02:16When one of the rows is clicked all of the rows are replaced with new ones.
02:21Next I'll show you how to delete rows from the tableView.
Collapse this transcript
Deleting rows
00:00Starting with the app.js file in the 05-08 folder of the exercise files, I'm
00:05using the finished state of exercise 05-02.
00:09I'll add the editable property of the tableView object and set it to true.
00:13I'll also add the allowSelectionDuringEditing property to the tableView
00:17object and set it to true.
00:23This will allow me to switch back and forth between editing and non-editing mode
00:27while taping the rows.
00:28I'll code an EventListener that will cause the table to enter in editing
00:31mode when the row is clicked.
00:33This editing mode is available for iOS only.
00:36For Android, I'll cover row deletion later in this movie.
00:40I'll add a callback that says the editing property of the tableView to true, if
00:43it is false and vice versa.
00:55Finally, I'll add an EventListener to the tableView that listens for the delete event.
01:00This will fire when the user taps the Delete button.
01:05For the callback function, I'll set the editing property of the table back to false.
01:10This will restore the table to non-editing mode.
01:14Let's take a look at the result in the Simulator.
01:21When any row is tapped, the table enters editing mode.
01:26If I tap the row again it exits editing mode.
01:30Upon entering editing mode again, I'll tap the button, this causes the
01:33Delete button to appear.
01:35After the Delete button is pressed, the row is deleted and editing mode is exited.
01:41To delete rows on Android I'll simply call the deleteRow method of the tableView
01:45object and feed it the e.index property with the click event callback function.
01:58This is similar to when I showed you how to add, insert or update a row
02:02earlier in this chapter.
02:06Note that this method of deletion does not fire the delete event.
02:10This method of deletion can also be used for iOS.
02:14The last technique of row manipulation that I'll show you is moving rows.
Collapse this transcript
Moving rows
00:00Starting with the app.js file, in the 05-09 folder of the exercise files, I'm
00:05using the finished state of exercise 05-08.
00:09To move a row the moving property of the tableView needs to be set to true.
00:16Within the click event callback function, I'll change the editing property of
00:19the tableView to moving, as well, I'll delete the code for Android.
00:31The moving property is only supported on iOS.
00:34Now I'll change the delete listener to listen for move.
00:38Within the callback function, I'll the change the editing property of the
00:41tableView to moving.
00:43The alert will show the new index for the row after it's been moved.
00:47Let's take a look at the results in the Simulator.
00:54Notice that by setting the moving property of the tableView to true, the row has
00:59entered editing mode.
01:00This means that I can follow through with row deletion if I wanted.
01:10After a row is moved, its new index is returned.
01:19I've shown you how different properties and methods of the tableView can
01:22enable row manipulation.
01:24However, it's important to remember that with any row manipulation the
01:28data source itself needs to be altered so is to accurately reflect what the user sees.
01:33With the different EventListeners and callback functions I've showed you, we
01:36have a starting point to accomplish this.
Collapse this transcript
Adding a search bar
00:00A feature that's found in many applications featuring tables is a Search bar
00:04that allows for the searching and filtering of table data.
00:07Starting with the app.js file in the 05 -10 folder of the exercise files, I've
00:11created a two-tab application that features a Tours tab and a Specials tab, each
00:16tab features a complete tableView.
00:19The ability to search a tableView is standard in mobile applications.
00:23To add one in Titanium Mobile I'll create a searchBar object.
00:28I'll set the to showCancel and hintText properties of the searchBar.
00:33The showCancel property will determine whether or not a Cancel button will
00:37appear to the right of the search bar.
00:39The hintText will appear as a prompt for the user to enter text to search for.
00:43Now I'll set the search attribute of the tableView to the searchBar.
00:48In order to enable rows to be searched, I'll create an attribute called
00:51searchFilter and add it to the TableViewRow creation at line 49.
00:56It's worth noting that any property can be set to be searched.
00:59I'll set the value of the row object searchFilter property to the title property
01:02of the object being iterated over.
01:04This means that the search bar will use the row title as the main
01:08searchable element.
01:10Before I look at the results in the simulator, I'll set the filterAttribute property
01:14of the tableView to the string searchFilter.
01:17This string matches the name of the custom property I set for the row at line 54.
01:22Let's have a look at the results in the Simulator.
01:26The table filters with each new letter entered into the search bar.
01:30Let's add a search bar to the tableView in the Specials tab.
01:32I'll open specials.js.
01:37Then I'll add a searchBar object with the showCancel property set to true, and
01:41the hintText property set with the string.
01:44I'll set the search property of the tableView to the searchBar object.
01:49During the row creation at line 50, I'll add a custom searchFilter property and
01:53set its value to the title property of the object being iterated over.
01:58Now I'll add a filterAttribute to the tableView and set a string that is equal
02:02to the name of the row property to filter, here searchFilter.
02:06I will load the project in the Simulator.
02:11The Specials tableView now has a search bar.
02:13When I search for any of the captioned text, the tableView filters and shows the
02:17result that matches.
02:19It's worth noting that the footer bar sticks when the result of the search is returned.
02:23This appears to be a bug.
02:25The footer will return to its correct position once the table is scrolled.
02:30Adding a search bar allows the user the ability to search through large amounts
02:33of data and adds another degree of interactivity to your application.
Collapse this transcript
Other properties and methods
00:00To close this chapter I'll briefly mention a few different tableView properties
00:04and methods that are worth looking into.
00:06The style property of a table can be set on iOS with a constant that will
00:10display the table as a group, similar to the way tables in the iOS
00:13Preferences are presented.
00:15This constant is Titanium.UI. iPhone.TableViewStyle.GROUPED.
00:21The headerView and the footerView properties looks at views that can act as
00:25alternative headers and footers for tableViews.
00:29The selectRow and deselectRow methods of the tableView allows for programmatic
00:33selection and de-selection of tableView rows.
00:37The scroll and scrollEnd events allow for the tracking of the position of the
00:40rows in the tableView.
00:42This is helpful if you want to implement a pull to refresh method for
00:45your table.
Collapse this transcript
6. Map View
Creating a map and setting the location
00:00Maps are easy to create and implement within Titanium Mobile.
00:04Both iOS and Android utilize the native Google Maps API when a mapView is created.
00:09Before getting started, it's important to configure the Android Run
00:12configuration so that the Google APIs for Android are used for the Simulator and build.
00:17Without this, the Google Maps API won't function properly.
00:21I will start by opening the tiapp.xml file in the root directory of the Project folder.
00:30In the Overview tab, under Deployment Targets I will choose configure.
00:36In this Preferences window, I will select one of the Google API choices from the
00:40Default Android SDK dropdown.
00:43This enables the Google Maps API for Android in my application.
00:47Note that this change will remain in effect in Titanium Studio for all projects
00:51until changed again.
00:53I'll head back to the app.js file.
00:56Using the app.js file in the 06-01 folder of the exercise files, I have created
01:01a new window object and have called its open method.
01:04Now, I'll create a mapView and assign it to a variable called mapView.
01:13Notice that the auto-complete suggests createMapView as the method for
01:17creating a mapView.
01:18As of this version of Titanium Studio, this is incorrect.
01:22To create a mapView, I will use Titanium.Map.createView.
01:30Before entering the mapView specific properties, I will copy and paste some
01:34position and dimension properties.
01:39The mapType property sets the style of the map.
01:43Choices include a STANDARD map, a SATELLITE map and HYBRID map.
01:47The STANDARD map is the default.
01:49The region property takes an object consisting of the following properties.
01:53The latitude and longitude properties set the coordinates around which the map will center.
01:58The latitudeDelta and longitudeDelta properties determine how near or far the
02:02map is zoomed to the center, the smaller the number, the closer the zoom.
02:11I will set the animate property to true to have the map animate to the provided
02:15latitude and longitude upon open.
02:17The regionFit property will have the mapView attempt to fit the specified region
02:21into the visible area.
02:23Note that if this is set to true, you will get more visible area within the view
02:27than if it's set to false.
02:29This is helpful to know, if you start adjusting latitudeDelta
02:32and longitudeDelta.
02:38Finally, the userLocation property determines the visibility of the user's
02:42current location on the map.
02:44If you have used Google Maps on your mobile device before, this is the pulsing
02:48blue dot that represents you.
02:49I will add the mapView to the window object and then take a look at the
02:53results in the Simulator.
03:02You might be prompted to allow the device to use your current location.
03:06Note that your users will see this as well on the first run of the maps portion
03:10of your application.
03:11Let's change the latitudeDelta and longitudeDelta values and see what happens.
03:18As you can see, the visible area of the map is zoomed in further.
03:23Finally, I'll change the regionFit property to true.
03:32Now more of the map is displayed within the visible area.
03:35This is because the app is trying to squeeze as much as it can into the visible
03:38area, given the region properties.
03:41Next, I will show you how to add simple annotations to your map.
Collapse this transcript
Creating simple annotations
00:00Annotations allow us to direct the user's attention specifically to a place on the map.
00:05The simplest annotations feature a pin, a title and a subtitle.
00:09Starting with the app.js file in the 06 _02 folder of the exercise files, I've
00:14created a new window object with the mapView added to it.
00:18I'll show you two methods for creating annotations.
00:20First, I'll create a single annotation object and set it to a variable called annotation.
00:34I will set the latitude and longitude properties to set the position of the annotation.
00:44Next, I will set a title and subtitle.
00:47The title will be the main text that is shown to the user with the subtitle in
00:50smaller text, underneath it.
01:03The animate property will show the annotation falling from the sky and landing
01:07on the map upon map load.
01:08I will set a customProperty to demonstrate the flexibility of adding custom
01:12properties to annotations.
01:14This is useful for storing and recalling additional data.
01:18To add the annotation to the map, I will set the maps annotations property.
01:22Note that the mapView's annotations property requires an array of annotation
01:27objects, even if only one is provided.
01:30I want the annotation to open when the map loads.
01:33So I will call the selectAnnotation method of the mapView object and pass in the
01:37annotation as its argument.
01:39Let's take a look at what we have so far in the Simulator.
01:47When the map opens, the pin drops and the annotation is displayed.
01:51Remember, that the annotation is showing upon open because I've used the
01:54mapView's selectAnnotation method to display it.
01:58The second method I'll show you for creating annotations is to create an array
02:02of objects that has properties for the annotations to be created.
02:14Similar to how I created table rows earlier, I'll iterate over the array, create
02:18annotation objects and push them into an array called annotationObject.
02:58I will set the annotations property of the mapView to this array of annotations.
03:07I'll comment out the selectAnnotation method on line 56.
03:12Now I'll take look at the result in the Simulator.
03:21Multiple annotations appear on the map.
03:28To simulate pinch and zoom on the iOS Simulator, hold Option while dragging.
03:37Lastly, I will add an EventListener to the mapView so I can grab the
03:41customProperty I set for the annotation.
03:52For the callback function, I will return the customProperty data in an alert
03:56by selecting the annotation object by using e.annotation and then adding .customProperty.
04:03Let's take a look at the result in the Simulator.
04:11When I click on the annotation, it opens and displays the title and subtitle.
04:16Also, the alert is fired.
04:19When I dismiss the alert, the annotation still remains.
04:22Next, I'll show you how to style your annotations by adding custom pins.
Collapse this transcript
Customizing pins
00:00If you have used Google Maps before, you may have noticed pins that look like
00:04icons or have other custom graphics.
00:06It's quite simple to implement these sorts of pins in Titanium Mobile.
00:10Starting with the app.js file in the 06- 03 folder of the exercise files, I have
00:15created a window object, mapView and annotation.
00:18I will set the image property of the annotation to an image I want to use as a pin.
00:29Now I'll take a look at the result in the Simulator.
00:39It's worth noting that the pin is centered on the annotations latitude and
00:42longitude, and its size remains constant and does not scale with the map.
00:52A useful benefit of creating a custom pin is that the total pin image acts as
00:56the tappable area for the pin.
01:01This can be helpful for providing a larger click service for users with bigger fingers.
01:05In the next movie, I'll show you how to introduce more interactivity to
01:08annotations through buttons.
Collapse this transcript
Creating and handling annotation buttons
00:00Just as with other types of UI objects in Titanium Mobile, annotations can be
00:05interactive with via tabs on the annotation itself or through left and right
00:09buttons that can be implemented on the annotation.
00:12Starting with the app.js file in the 06- 04 folder of the exercise files, I have
00:17created a window object, mapView object and annotation.
00:21Buttons can be added to the left and right of an annotation, by setting the
00:25leftButton and rightButton properties.
00:35Note that here a button will just be an image that is loaded to the left and
00:39right of the annotation;
00:40it will not be a button object as created by Titanium.UI.createButton.
00:44I will also set custom leftButtonText and rightButtonText properties to return
00:50data when each of the buttons is tapped.
00:58Now, I will add an EventListener to the mapView so that I can handle the
01:02annotation button events.
01:09For the callback function, I will use e.clicksource to determine the source of the click.
01:27I will set an alert to display the value of the leftButtonText and
01:30rightButtonText properties that are accessed through e.annotation.
01:39Let's take a look at the result in the Simulator.
01:47When I tap the pin an annotation with two buttons appears.
01:52When each of the buttons is clicked, an alert appears indicating successful
01:56handling of the event.
02:01Next, I'll show you how to add and remove pins at runtime.
Collapse this transcript
Adding and removing pins at runtime
00:00Within your application you may want to introduce pins at runtime, such as adding
00:05a pin to the map when the user taps something.
00:07Starting with the app.js file in the 06 -05 folder of the exercise files, I've
00:12created a window object and I've added a mapView to it.
00:16Notice the mapView's annotations property is set to an empty array, this is
00:20necessary for setting annotations later on, I'll be adding and removing
00:24annotations by using two custom buttons.
00:27First I'll create a button to add a pin.
00:38Second I'll create a button to remove a pin.
00:45Last I'll add these buttons to the window object, I'll add them after the
00:49mapView has been added to the window object so that they'll appear on top of the mapView.
01:03I'll add a click EventListener to the addPinButton.
01:16For the callback function I'll create a new annotation object similar to the one
01:20used in an earlier movie.
01:35I'll add the annotation to the map using the Maps addAnnotation method and pass
01:40the newly created annotation as the argument.
01:45Using the Set Location method of the mapView, I'll move the map to the
01:49annotations location.
01:51For an argument, I'll pass an object that has latitude and longitude properties
01:55equal to the annotations.
02:05Finally, I'll set a custom property called hasAnnotation that will be a Boolean
02:09indicating whether or not the map has an annotation, this is useful, in that I
02:14don't want to be able to add the same annotation multiple times.
02:26To ensure that the AddPinButton doesn't add an annotation multiple times I'll
02:30create a condition to check for the hasAnnotation property of the mapView.
02:47Let's take a look what we have so far in the Simulator.
02:55When I tap the green Add button, the map scrolls to the annotation location and shows the pin.
03:08Now I'll write code to remove the annotation.
03:12I'll attach a click EventListener to the removePinButton.
03:19For the callback function, I'll write code that checks if the map already has an annotation.
03:34If the mapView has an annotation, I'll remove it by calling the
03:38removeAllAnnotations method of the mapView.
03:41If I wanted I could also use the Remove Annotation method and pass the reference
03:45of the annotation object.
03:47I won't to do that here, because the variable the annotation is assigned to
03:50is out of scope.
03:54I'll set the hasAnnotation property back to false, so that I can create the
03:57annotation again if I want.
03:59For the else condition I'll create an alert that prompts the user to create an annotation.
04:08Let's take a look at the results in the Simulator.
04:16I can add an annotation with the green button, interact with it, and then
04:23remove it.
Collapse this transcript
7. Web View and XHR
Loading local and remote web pages
00:00WebViews allow you to incorporate local or remote html content into your app.
00:05Starting with the app.js file in the 07_ 01 folder of the exercise files, I have
00:10created a new window object and two buttons.
00:14I'll create a new webView object and set it to a variable called webView.
00:22Then I will add the webView to the Window.
00:26Since the webView is added to the window before the two buttons, it will
00:30appear beneath them.
00:31Now I'll create a click EventListener for the loadLocalButton object.
00:38For the callback function, I will load a local web page into the webView.
00:42I've already created a standard web page and have added it to an html folder
00:46that I created and added to the Resources folder of the project.
00:50Though not required, I like to keep my html content in a separate folder within
00:54the Resources directory.
00:56I will set the URL property of the webView to the path of the html file in the html folder.
01:05Let's take a look at the results in the Simulator.
01:08When I tap the loadLocalButton, the local web page is loaded into the webView.
01:13I will head back to the click EventListener of the loadLocalButton object.
01:18I'll comment out this line.
01:21With the html property of the webView object, I can write html formatted strings
01:26and have them displayed in the webView.
01:31Let's take a look at the result in the Simulator.
01:35When the loadLocalButton is clicked, the html formatted content in the string is
01:39loaded into the webView.
01:41WebViews are also capable of displaying remote html content.
01:45I will add a click EventListener to the loadRemoteButton object.
01:51For the callback function, I will set the URL property of the webView to the
01:55Explore California homepage.
01:59It's worth noting, that you must include the protocol prefix at the start of the URL.
02:04Let's take a look at the result in the Simulator.
02:07When the loadRemoteButton is tapped, the Explore California site is loaded.
02:12Next, I'll show you more about how to take advantage of the webView's events
02:16and controls.
Collapse this transcript
Examining Web View events and controls
00:00Titanium Mobile allows you to tightly control the appearance and navigation of
00:04content within a webView.
00:05This control includes methods for allowing forward and backward navigation of
00:10the current browsing history within the webView.
00:12Starting with the app.js file in the 07_ 02 folder of the exercise files, I have
00:17created a window object with two buttons and a webView.
00:20The URL property of the webView is set to the homepage for Explore California.
00:25Also, the backButton and forwardButton are not showing.
00:28There are three main events that a webView will fire.
00:32The before load event is fired before the webView begins loading it's content.
00:36The load event is fired when the webView content is loaded.
00:40The error event is fired when the webView is unable to load the content.
00:44Adding EventListeners for all three of these events is no different than adding
00:47EventListeners for other objects.
00:49In this movie, I will only be using the load event.
00:52I will create a load EventListener for the webView.
00:58The can go back and can go forward methods of a webView return a
01:02boolean value indicating whether or not the webView has content to navigate
01:06back or forward to.
01:08For the callback function, I will test to see if the webView can navigate
01:11back to a web page.
01:13If it can, I will show the backButton and allow the user to navigate back.
01:17Otherwise, I'll hide the backButton.
01:24I will repeat this for the forwardButton.
01:30Now, I'll create click EventListeners that cause the webView to go back or go
01:34forward by calling the goBack and goForward methods of the webView object in
01:39their callback functions.
01:47Let's take a look at the result in the Simulator.
01:51As I navigate the Explore California web page, the forward and back buttons are
01:55shown and hidden as needed.
01:58Next, I'll show you how to add app to web interactions, within your app.
Collapse this transcript
App-to-Web View for iOS
00:00App interactions can affect the contents of a webView.
00:03Likewise the webView can affect the app via JavaScript.
00:07Starting with the app.js file in the 07_ 03 folders of the exercise files, I have
00:12created a window object with a button and a webView.
00:15The URL property of the webView is set to a local html page I created, located
00:20within the html folder of the Resources directory.
00:24I'll open the index.html file within the html folder.
00:28Notice that jQuery is being loaded into the web page.
00:33A copy of the jQuery Library is located within the html folder.
00:37I will be using jQuery to easily set the content of this div within the web page.
00:41If you're not familiar with jQuery, check out jQuery Essential Training here in
00:45the lynda.com Online Training Library.
00:49Within this web page, I have prepared a jQuery (document).ready function.
00:53Whatever I include in this function will execute when the page loads.
00:57Within the (document).ready function, I will write code that will fire a custom
01:00event when the anchor tag is tapped.
01:04To fire a custom event, I will call Titanium.App.fireEvent.
01:10The first argument is a string indicating what the event will be called.
01:14In a moment, we'll be listening for this event in the app.js file.
01:18The second argument is an object with properties that will be passed with the event.
01:22I will create a property called value and we will assign a string to it.
01:28I'll head back to the app.js file.
01:30Now I'll listen for the custom event I created, by calling
01:33Titanium.App.addEventListener.
01:39The first argument will be the name of the event that I created.
01:43For the callback function, I will fire an alert that contains the value property
01:47of the object that was sent with the event.
01:50Let's take a look at the results in the Simulator.
01:54When I tap the Touch to Fire link, an alert fires with the value of the object
01:58that was sent from the event.
02:01Now I'll write code to have the app.js file fire JavaScript content within the web page.
02:06I will head back to the html file and write a JavaScript function to change the
02:11contents of the div on the page.
02:13I will add a click EventListener to the button object in the app.js file.
02:27For the callback function, I will use the evalJS method of the webView to fire
02:32the function I just created in the web page.
02:40Let's take a look at the result in the Simulator.
02:45When I tap the button, the div within the web page changes.
02:50Keep in mind that the evalJS method will evaluate content within its argument
02:54with no questions asked.
02:56This could be a potential security problem in your app if not used carefully.
03:00In the next app, I'll show you how to load and parse an external XML feed
03:03into your app.
Collapse this transcript
Loading an external XML feed
00:00Using XHR, you can incorporate remote data feeds into your application.
00:04Starting with the app.js file in the 07_ 04 folder of the exercise files, I have
00:10created a window object with a tableView.
00:12Notice that the data property of the tableView is set to an empty array.
00:15I will be pushing row objects into the array, later in the movie.
00:19To load data from an external data source,
00:22I'll have to create an instance of the Titanium.network.createHTTPClient object.
00:28I will have to set the onLoad property of the object to a callback function
00:32reference that will fire once the remote data source has been loaded.
00:36I will set the onerror property of the object to a callback function reference
00:41that will fire if there's an error.
00:43I'll call the open method of the create HTTP client object.
00:47I will use the Get method.
00:49The second argument is the URL of the remote data to load.
00:52I am loading data, formatted as XML from the Explore California site.
01:00I'll create the callback function for the onerror property.
01:06Now, I'll create the callback function that the onLoad property refers to.
01:10I will be using the value of the tour title tags for the tableView rows.
01:14I am able to access the XML formatted data using the keyword this, within
01:23the callback function.
01:25I need to drill down to the tour title tag, or node, of the XML data I am loading.
01:31Now I'll iterate through the tour object and create tableView rows from the tour title tags.
01:39When the row creation is done, I'll push the row into the array that was created at line 7.
01:46When the loop iteration is done, I'll use the setData method of the tableView to
01:51set the tableView rows into the tableView.
01:55Before taking a look at the result in the Simulator, I'll call the Send method
01:59of the create HTTP client object.
02:02Let's take a look at the results in the Simulator.
02:06The tables loaded with the tour titles from the XML feed.
02:09With this, you can begin to create apps such as news or blog readers that use
02:13remote data sources for data feeds.
Collapse this transcript
8. Feedback
Providing Feedback to the User
00:00Providing feedback to the user as a result of an interaction is an
00:03important part of app design.
00:05Device vibration, audio playback and animation of visual components are all ways
00:10in which we can alert, inform and reassure the user about the actions that they
00:14are engaging with in the app.
00:16In this chapter, I'll show you a few of the more commonly used methods for
00:19providing feedback, including using timers, prompting the device to vibrate and
00:24using alert and option dialogs.
Collapse this transcript
Setting timers
00:00Timed, sequenced, and looped actions are commonly found in apps.
00:04Titanium Mobile uses JavaScript's native timer mechanisms setTimeout and
00:09setInterval to execute time-based actions.
00:12Starting with the app.js file in the 08_ 02 folder of the exercise files, I have
00:17created a window object, a button, a switch and two labels.
00:21Before continuing, we will take a look at this in the Simulator.
00:26The button and the switch will fire their associated timers and the results will
00:29appear in the labels above them.
00:31I will add a click EventListener to the setTimeoutButton.
00:38For the callback function, I will create code that will test to see if the timer
00:41created by setTimeout has been fired.
00:44If it hasn't, a timer will be created and will then go off two seconds after the
00:48button has been tapped.
00:49In JavaScript, two seconds is represented as 2000 ms.
00:53I will assign the timer to variable t. Note that since I only need the timer to
00:58fire once, I will use setTimeout.
01:01The first argument of setTimeout is a function reference to call.
01:05I will create an in-line function that will set the text property of the
01:08setTimeoutLabel to Fired.
01:12More importantly, after the text has been set, I will cancel the timer using
01:15clearInterval with the timer reference passed as the argument.
01:19Then I'll set variable t to null.
01:21This is important for ensuring that variable t is marked for garbage collection
01:25and no memory leaks occur.
01:27I will set the second argument of setTimeout to 2000.
01:31Since the timer has been created and fired, I will set this.fired to true.
01:36The fired property is a custom property that tracks whether or not the timer has been fired.
01:40It helps in ensuring that the timer isn't accidentally fired multiple times.
01:45Let's take a look at the results in the Simulator.
01:48When I click the setTimeout button, the setTimeoutLabel above changes, two seconds later.
01:55Now, I'll implement a change EventListener on the setIntervalSwitch.
02:02For a callback function, I will test for e.value.
02:05Remember that this value is a Boolean.
02:07I will create a setInterval timer within the first portion of the condition and
02:13set it to this.timer.
02:16Remember that in JavaScript, that this keyword applies to the object calling the
02:20function here the event object.
02:22SetInterval is similar to setTimeout in that it takes the same arguments.
02:27The first argument is the function to call.
02:29I will write some code that will cause the text to blink by alternating the text
02:32property of the setIntervalLabel.
02:35To create this alternating effect, I'll implement a variable i and set it to
02:40zero outside the setInterval timer.
02:42Then with each firing of the timer, I will increment the variable.
02:45I will create a condition that will test for i modulo 2, this looks
02:50complicated, but all it is really doing is causing an alternation between the
02:54number 0 and the number 1.
02:57In the first part of the condition, I will set the text property of the
03:00setIntervalLabel to an empty string.
03:03In the second part of the condition, I will set the text property of the
03:06setIntervalLabel to Bang!.
03:08I will set the second argument of setInterval to 500 so that it fires every 500
03:12milliseconds, or half a second.
03:15In the second part of the outer condition, I will stop the timer using
03:18clearInterval with this.timer passed as an argument.
03:22As I did before, I'll set this.timer to null.
03:25I will also set i back to 0.
03:29Lastly, I will set the text property of the setIntervalLabel to Stopped.
03:35Let's take a look at the results in the Simulator.
03:38When the switch is turned on, the text starts blinking, when it's turned off, it stops.
03:45The most important aspect of all this, is that when you start a timer, you must
03:49remember to stop it with clearInterval and null it out.
03:52Timers are notorious for causing memory leaks and so it's good coding practice
03:56to take care of their method of disposal as soon as you create them.
03:59Next, I'll show you how to create tangible feedback, by prompting the device
04:02to vibrate.
Collapse this transcript
Prompting the device to vibrate
00:00The simplest and most tangible type of feedback provided to the user is
00:04prompting the device to vibrate.
00:06Starting with the app.js file in the 08_ 03 folder of the exercise files, I have
00:11created a window object and a label.
00:13I will create a vibrateButton object to prompt device vibration.
00:17Next I will add the vibrateButton to the window.
00:22Now I will create a click EventListener for the vibrateButton object.
00:28For the callback function, I will call Titanium.Media.Vibrate.
00:34While I can take a look at the result in the Simulator, nothing will happen.
00:39The computer I am working on can be prompted to vibrate, in order to see or
00:43really feel the result, I need to deploy this to a device.
00:46This is the main reason I created the label.
00:49Should you test this on a device with the code given, I want you to remember
00:52that this only works with the devices that can prompt vibration.
00:56In the next movie, I'll show you how to prompt the user to make selections,
00:59using an alert dialog.
Collapse this transcript
Providing feedback with an Alert dialog
00:00Throughout the course so far, I've been making ample use of the Alert dialog to
00:04provide feedback of various sorts.
00:06In calling alert with an argument to display, I've been really using a
00:09shortcut for the alert view.
00:11In this movie, I will show you how to implement an Alert dialog that has
00:14buttons for user input.
00:15Starting with the app.js file in the 08 _04 folder of the exercise files, I've
00:20created a window object and label.
00:22I will create a button called alertButton to prompt the Alert dialog.
00:27Next, I will add the alertButton to the window.
00:31Now I will create the Alert dialog object and assign it to the
00:34variable colorDialog.
00:36The title property of the Alert dialog object is the header text that will
00:39appear to the user.
00:41The message property of the Alert dialog object is the text that will appear
00:44underneath the title text.
00:47The buttonNames property accepts an array of strings for buttons, as they are
00:50to appear on the Alert dialog from left to right.
00:53The maximum number of entries the array can accept is three.
00:56Put another way, the maximum number of buttons an Alert dialog may have is three.
01:01I will type Yellow and Surprise me for the buttonNames entries.
01:06The idea here is that when the user selects the button marked yellow, the
01:10background color of the window will change to yellow.
01:12When the button mark Surprise me is selected, the background color of the window
01:16will change to some other color.
01:17I will create a click EventListener for the alertButton object.
01:20I will set the colorDialog object to show for the callback function.
01:27All views have show and hide methods.
01:30I will create a click EventListener for the colorDialog object.
01:35For the callback function, I will change the text property of the label to
01:38reflect the current Alert dialog button, index selection.
01:41I will also code a condition that tests for the index of the button tapped
01:45represented by e.index.
01:48If the first button is tapped, I will set the background color of the window to yellow.
01:54If the second button is tapped, I will set the background color of the window to a bluish color.
02:00Let's take a look at the results in the Simulator.
02:03When the Alert button is pressed, the color dialog is shown.
02:08If I choose the button marked Yellow, the background color of the window changes
02:11and the alert is dismissed.
02:14The same thing happens if I choose the other button.
02:18In the next movie, I will show you the Option dialog, which is a variation on
02:21the Alert dialog.
Collapse this transcript
Providing feedback with an Option dialog
00:00The Option dialog is quite similar to the Alert dialog and its primary function is
00:04to prompt the user to make a selection.
00:07The Option dialog is different from the Alert dialog in that it appears at
00:10the bottom of screen.
00:11It also affords more choices for the user to select.
00:14Starting with the app.js file in the 08 _05 folder of the exercise files, I've
00:19created a window object, label and button.
00:22I'll create a new Option dialog and assign it to a variable called colorDialog.
00:28The title property sets text to be displayed to the user as a header on the dialog.
00:34The options property sets the Option buttons to display to the user by using an
00:38array of strings with each string representing an option for the dialog.
00:42These buttons are ordered top to bottom, left to right in the array.
00:46The cancel property specifies which of the option indexes serves as a Cancel button.
00:51Here I will specify index 2, which is the last index.
00:55Remember that JavaScript counts up from 0.
00:57Another property that acts in this way is the property called destructive.
01:02I won't be using that property here.
01:04I'll create a click EventListener for the optionButton.
01:08For the callback function, I will set the colorDialog object.
01:13Next, I'll create a click EventListener for the colorDialog.
01:19For the callback function, I will test the index of the button tapped through e.index.
01:24If the value is less than 2, it means that either of the first two buttons was
01:28tapped, otherwise it means the last button was tapped.
01:31Remember, that this button is set to be the cancel button for the Option dialog.
01:35In the first part of the condition, I will create another condition that will
01:38change the background of the window based on which button is pressed.
01:42Lastly, as helpful feedback to myself, I will set the text property of the label
01:46to display the index of the button that was pressed.
01:49I will also set the text property of the label when the Cancel button is pressed.
01:57Let's take a look at the result in the Simulator.
02:01I can launch the colorDialog and make selections.
02:06If I choose the last button marked No Thanks, the dialog disappears.
02:11This is because the button index is set to be the Cancel button for the dialog.
02:15In the next movie, I'll show you how to prompt the device to dial a phone number
02:19or load a web page in its default browser.
Collapse this transcript
Dial a phone number or load a webpage
00:00In this movie, I'll show you how to programmatically dial a phone number or load
00:04a web page into the device's default browser.
00:06Starting with the app.js file in the 08- 06 folder of the exercise files, I have
00:11created a window object, a label and two buttons.
00:15I'll add to the dialNumber button a custom property called phoneNumber that has
00:19a seven digit phone number in a string separated by dashes.
00:23While the number here is a California phone number, you can just as easily put
00:27any dialing string for any phone number.
00:29I'll add to the openWebpage button a custom property called url.
00:35I'll attach a click EventListener to the dialNumber object.
00:41For the callback, I'll call the function Titanium.Platform.openURL with the
00:46objects phoneNumber property, prefixed by tell with a colon.
00:52The prefix tells a device to send the phone number to the phone app.
00:56Next I will attach a click EventListener to the openWebpage button.
01:03For the callback, I'll call the same function as before.
01:07This time, I'll pass the object's URL property with no prefix.
01:12By default, this method will try to open what is provided in the device's
01:15default web browser.
01:17Let's take a look at the result in the Simulator.
01:21Since the Simulator can't make phone calls, I can't really test the dialNumber button.
01:25I can however, test the Open web page button.
01:28When clicked, the Explore California site is opened in the default web browser.
01:34For the next movie, I'll show you how to implement an activity indicator, to
01:37show device activity.
Collapse this transcript
Implementing an activity indicator
00:00An activity indicator is useful for providing feedback when there's a process
00:04running that the user needs to wait for, such as the loading of a file.
00:08Starting with the app.js file in the 08 -07 folder of the exercise files, I've
00:12created a window object and a switch object.
00:15I have set the background color of the window to blue.
00:18This is so that the activity indicator is easier to see.
00:21I will create an activityIndicator object and assign it to a
00:24variable activityIndicator.
00:28I will set the width and height properties to auto.
00:31This will help in accommodating the message text in a moment.
00:35Next, I will set the message property.
00:36The value here will appear as text to the right of the activityIndicator.
00:41Finally, I will set the style property to
00:44Titanium.UI.iPhone.ActivityIndicatorStyle.Plane.
00:49The three options available for this property are commented below.
00:54Outside of its constructor I will hide the activityIndicator by calling its hide method.
00:59Then I will add the activityIndicator to the window.
01:04I'll add a change EventListener to the activitySwitch.
01:07For the callback function, I will test for the value property of the switch by using e.value.
01:13If the switch is on, the activityIndicator will be seen.
01:17If it's off, the activityIndicator will be hidden.
01:21Let's take a look at the results in the Simulator.
01:25When the switch is turned on, the activityIndicator is seen, when the switch is
01:29turned off the activityIndicator is hidden.
01:32Next, I'll show you how to animate visual elements using the animation object.
Collapse this transcript
Animating windows and views
00:00Content such as Windows and Views can be animated using the animation object.
00:05Starting with the app.js file in the 08 _08 folder of the exercise files, I've
00:09created a window object, an image, and a button.
00:13I'll add a click EventListener to the animateButton object.
00:18For the callback function I'll be animating, scaling, and rotating the
00:21exploreCalifornia image.
00:23First, I'll create an instance of the animation object.
00:28The properties I set here will be applied to the object being animated.
00:31This will cause the object's top value to move to 60.
00:35The duration property indicates the length of the animation in milliseconds.
00:40Now I'll call the animate method of the exploreCalifornia object and pass in the
00:45newly created animation object as the argument.
00:48Let's take a look at the result in the Simulator.
00:51When I press the button, the image animates.
00:55After animating, I want the image to animate back to its original position.
00:59To do this I'll add an EventListener to the animation object and listen for the
01:03event called complete.
01:05The callback function for this event will fire once the animation has been completed.
01:10Within the callback function, I'll implement some visual feedback by setting the
01:14window backgroundColor to yellow.
01:16Now I'll implement a new instance of the animation object and set its properties.
01:22Finally, I'll call the animate method of the exploreCalifornia object and pass
01:26the newly created animation object as the argument.
01:29Let's take a look at the result in the Simulator.
01:34When I tap the button, the image moves to a top value of 60 and back.
01:38The yellow background of the window object indicates that the complete event fired.
01:44To rotate or scale the image, I need to create a new instance of the 2DMatrix object.
01:50Next, I'll call the rotate method of the object and assign it to itself.
01:55The number fed into the rotate method is the amount to rotate measured in degrees.
01:59I'll call the scale method of the object and again assign it to itself.
02:03The number fed into the scale method represents the amount to scale.
02:07A larger number represents scaling upwards and a smaller number
02:10represents scaling downwards.
02:12I'll create a transform property in the first animation object and assign as its
02:16value the newly created transform object.
02:20Within the complete EventListener I'll create another transformation object and
02:24assign it to the animation object.
02:30Now let's take a look at the result in the Simulator.
02:34When the button is pressed, the image animates, scales, and rotates back and forth.
02:41As you work with the animation object, be sure to check the Titanium
02:44documentation for additional properties.
Collapse this transcript
9. Data Management
Setting custom application properties
00:00Application properties are used to store data that needs to persist from one app
00:05session to the next.
00:06Here, a session is when an app is opened, runs and then fully closes, and
00:11it's not multitasking.
00:12Starting with app.js file in the 09- 01 folder of the exercise files, I have
00:17created a window with a label and a button.
00:19I will add a click EventListener to the button.
00:26For the callback function I will test for a custom property that will test to
00:29see if the app has run before.
00:32If it hasn't, I will set the property and display feedback in the label.
00:35If it has, I will display feedback in the label that consists of another
00:39custom property set on firstRun.
00:41I will use the hasProperty method of the Properties module to test if my
00:46custom property exists.
00:48Notice the exclamation point before the call of this method.
00:51This means I am checking for the false condition.
00:54If the result of the test is false, this is the first run of the application.
00:59Using the setBool method of the Properties module, I will set a custom
01:03Boolean property called firstRun that will be used to track the first run of the application.
01:11The first argument is the name of the property set as a string.
01:14The second argument is the value to set here the value will be a 1 or 0.
01:19I will set another custom property that on subsequent runs will be appended to
01:23the text within the label.
01:25I will use the setString method of the Properties module to set a
01:28property called appMessage.
01:37Finally, I will set the text property of the label to indicate the first run of the app.
01:48Using the getString method of the Properties module, I will return the value of
01:52the appMessage property and combine it with some other text to reflect that the
01:55app has been run before.
02:08Let's take a look at the result in the Simulator.
02:14When I tap the button the label reflects the first run of the application.
02:18I will tap the Home button to leave the application.
02:23Then I'll double-tap the Home button to bring up the multitask bar.
02:26I will tap and hold on the icon to close it.
02:31When the app closes, so will the Simulator.
02:33From Titanium Studio I will choose Run As again.
02:39This time when I tap the button, I am given feedback that the application has run before.
02:44To begin with a completely fresh slate of properties, I'll head to the Home
02:47screen by tapping the Home button at the bottom of the Simulator.
02:50I will tap and hold on the app icon to delete it.
02:56When I choose Run As again from Titanium Studio, I am presented with a freshly
03:00built version of the app.
03:02There are other types of data that can get stored and retrieved using
03:05the Properties module.
03:06I've pasted them beneath the firstRun property in the code.
03:12Next, I'll show you how to incorporate the device's file system into your app.
Collapse this transcript
Reading from and writing to the filesystem
00:00Incorporating the device's file system adds more data persistence options to your app.
00:06Starting with the app.js file in the 09 -02 folder of the exercise files, I've
00:11created a window object, a label featuring a button, a text field, a text area,
00:16and a button at the bottom of the window.
00:19An EventListener has been added to the window so that the keyboard can be
00:22blurred if necessary.
00:24I will store text entered within the text field to a file and then display it
00:29within the text area.
00:31First, I will add a click EventListener to the storeButton object.
00:35For the callback function, I will test to see if the textField has any data.
00:39Remember that the hint text property of the textField is set, and this text
00:43won't count as data within this conditional test.
00:50If there's no text present in the textField, I will alert the user to enter some text.
00:55Otherwise, I will proceed with storing the text entered.
00:59All file operations start with using the getFile method of Titanium's Filesystem
01:05module to create a file object.
01:09The first argument of this method expects a constant for a directory in which
01:12to look for this file.
01:17When writing files you will want to pass
01:19Titanium.Filesystem. applicationDataDirectory into this argument.
01:24iOS only allows reading and writing into the application's data directory.
01:30Temporary data can be stored in a separate folder by calling
01:33Titanium.Filesystem.tempDirectory.
01:37In this example, I will show you how to write to the application's data directory.
01:41The second argument expects a string that represents the file name.
01:45Since I haven't created the file yet, I'll create a name here.
01:49Now I will test whether or not this file exists using the exists method of the file object.
01:55This is because the storeButton will serve two functions.
01:58Its first function is to create a file with data from the text field if the file
02:03hasn't been created.
02:04Its second, is to update a previously created file with the data from the text field.
02:09In the first part of the condition, I will call the createFile method of the file
02:13object to actually create the file on the device.
02:16I will place an alert as feedback to let me know the file has been created.
02:24Next, I will use the write method of the file object to write the textField data to the file.
02:31Finally, I will set the value property of the textArea to the value of
02:34the textField data.
02:38In the second part of this condition the file already exists.
02:41I will set the contents of the file to a variable by calling the read method
02:45of the file object.
02:47The read method of the file object returns what's called a file BLOB.
02:52This BLOB is binary data that must be processed in order to be human readable.
02:57Next, I'll create a new variable that appends data from the file to data
03:01within the textField.
03:02Note that I'm using the Text property of the fileContent variable in order to
03:07return data from the BLOB formatted as text.
03:10The overall effect here will be that the total amount of data written to
03:13the file is increasing.
03:15Finally, I will write the new variable to the file and set an alert to provide
03:19feedback that the file has been updated.
03:21I will also blur the textField and reset its value to an empty string.
03:35Let's take a look at the result in the Simulator.
03:37I will enter some text in the textField and choose Store.
03:45The text is stored to a file and presented in the textArea.
03:48I will enter some more text and choose Store again.
03:56The file is updated with the new text and the textArea is updated.
04:00Now I'll write some code to read content from the file on load of the
04:04application and place it in the textArea.
04:06I will access the file again.
04:13Then I'll check to see if it exists on the device.
04:16If it exists, I will set the value of the text area to the file's contents.
04:20I will run the project in the Simulator.
04:25Then I'll close the app and delete it from the Home screen.
04:32This ensures that I will start with a fresh file.
04:34I will run the project again in the Simulator and interact with the text field.
04:42Then I will close the app entirely.
04:49One more time, I will run the project in the Simulator.
04:52Data from the file is loaded into the textArea.
04:55Before continuing I will delete the app from the Home screen to ensure that I
04:58start with a fresh project next time the Simulator loads.
05:06The last thing that I will code is a click EventListener for the deleteButton.
05:18For the callback function I will delete the file from the project if it exists.
05:31I will test to see if the file exists.
05:33If it does I'll delete it by calling the file object's deleteFile method.
05:38I will clear the text within the textArea by setting its value property to an empty string.
05:42I will display an alert for feedback indicating that the file has been deleted.
05:46Let's take a look at the result in the Simulator.
05:50I can enter text in the textField and store it to a file.
05:57Entering more text and choosing Store will update the file.
06:04Tapping the Delete button clears the textArea and deletes the file.
06:07The ability to save data to the device opens up many possibilities for your app.
Collapse this transcript
Sending an email
00:00Providing a means for feedback and sharing information via email can help users
00:05engage with your app.
00:07Starting with the app.js file in the 09 _03 folder of the exercise files, I've
00:12created a window object with a label and a button.
00:15To call the devices native Email dialog I'll use Titanium.UI.createEmailDialog.
00:23The barColor property of the Email dialog object sets the color of the nav bar
00:28at the top of the dialog.
00:30The html property enables HTML formatted content for the body of the message.
00:35If you only wanted a plain text message, this would be set to false.
00:39The toRecipients property sets the recipients of the email by using an
00:43array of email addresses.
00:49There also exists CC recipients and BCC recipients properties for the Email dialog.
00:55Here, I'll only set the toRecipients property.
00:58The subject property sets the subject of the email.
01:01The messageBody property sets the content of the email.
01:10I'll add a click EventListener to the button object.
01:18For the callback function open Email dialog by calling its open method.
01:27Then outside of the button EventListener I'll add an EventListener to the Email
01:31dialog object that listens for an event called complete.
01:35I'll test to see if the email was sent by comparing the result property of the
01:39event object with the SENT property of the Email dialog object.
01:45Notice that the SENT property is in all caps.
01:49If the email was sent, I'll set the text property of the label to say so.
01:53Otherwise, I'll display an alert with the value of the event objects result property.
02:03Let's take a look at the results in the Simulator.
02:07When the button is pressed a pre -populated Email dialog opens.
02:11I can edit any of the fields.
02:17When I choose Send, the label in the window object reports that the email
02:21was successfully sent.
02:22Though it reports as being sent, note that within the Simulator, the email
02:27doesn't actually get sent.
02:29This is a feature which is important to test on a device.
02:33The Email dialog object also allows attachments to be sent with emails.
02:38I'll go back to the button click EventListener and add code to retrieve the
02:42file BLOB for an image located within the images folder of the project's Resources folder.
02:56Then I'll set the Email dialogs addAttachment property to attach the file BLOB
03:01to the email being sent.
03:03It's worth mentioning that the Email dialog can only send binary data formatted
03:08as a BLOB regardless of file type.
03:11Now I'll run the project in the Simulator.
03:17When I tap the button, the Email dialog opens with the picture attached.
03:21Of course, these functions can be extended to include user input for email
03:26addresses, attachments, and other aspects.
03:29Email integration can be a critical component of apps and with Titanium Mobile
03:34you can enjoy this functionality without leaving the app.
Collapse this transcript
10. Media
Using the camera and video
00:00Incorporating media into your application adds another dimension of
00:04expression to your content.
00:06Images, video, and sound can all be created and experienced within Titanium Mobile.
00:11Starting with the app.js file in the 10 _01 folder of the exercise files, I've
00:16created a window object with a button.
00:18Notice that the zIndex of the button is set to 2.
00:21I'll add a click EventListener to the button.
00:26For the callback function, I'll open the camera on the device, use it, save the
00:30result to the device's photo gallery, and then display the captured photo or
00:34video in the window.
00:36I'm assuming that the device has a camera.
00:39The Titanium.Media.isCameraSupported can be used to test the camera within a
00:44conditional statement.
00:46The success property takes a callback function that will fire once the camera
00:50successfully takes a photo or records a video.
00:54I'll be coming back to this property in a minute.
00:57The error property takes a callback function that will fire if an error occurs.
01:04The cancel property takes a callback function that will fire when the camera is canceled.
01:10The allowEditing property determines whether or not the user will be allowed to
01:14edit the photo or video after it's been taken.
01:17I'll set this to true.
01:19The saveToPhotoGallery property determines whether or not the photo should be
01:23saved to the device's default photo gallery.
01:26I'll set this to true.
01:29The mediaTypes property sets what modes of image capture are available to the
01:33user for the camera.
01:35Options must be placed within an array.
01:39Keep in mind that if you specify a mode here, if the device doesn't support it, it won't be shown.
01:46Finally, the videoQuality property sets the quality of the photo or video captured.
01:51I'll set the quality to high using Titanium.Media.QUALITY_HIGH.
01:57I'll return to the success property and code a callback function that will work
02:01in two different ways.
02:02If a photo is taken, the photo will be displayed in a new imageView within the window.
02:08This is done by comparing the mediaType property of the event object with
02:12Titanium.Media.MEDIA_TYPE_PHOTO.
02:18If video is taken, the video will display in a new window, play, and then close.
02:23This is done by comparing the mediaType property of event object with
02:27Titanium.Media.MEDIA_TYPE_VIDEO.
02:32For the photo portion of the condition, I'll create a new imageView and set the
02:36image property to the media property of the BLOB returned by the camera.
02:42Now I'll set some dimension and position properties.
02:47Then I'll add the imageView to the window.
02:52For the video portion of the condition, I'll create a new video player object and
02:56launch it in a new window.
02:59I'll set the backgroundColor to black.
03:03In the videoPlayer object I'll set the media property to e.media.
03:09There are lots of other properties that are valid for this object, including
03:12setting the ControlMode, ControlStyle, and scalingMode.
03:16I'll copy and paste some of them below.
03:20Now I'll add the videoPlayer to the newly created window.
03:24I'll add an EventListener to the videoPlayer that listens for the event called complete.
03:32For the callback function, I'll remove the videoPlayer object from the new window
03:36and set the variable to null.
03:39This is done to ensure the variable is marked for garbage collection.
03:43Finally, I'll call the close method of the window.
03:46In order to test this out, I'll need to build to the device.
03:49I cover building to the device later in the course.
03:54When I click the button the camera appears and I'm able to take either a photo or a video.
04:00If I take a photo I can follow through until finally the photo appears in the window.
04:08If I record video, I can follow through until the video appears in a new window,
04:13plays, and then closes.
04:16Next, I'll show you how to incorporate photos from your device's photo
04:19gallery into your app.
Collapse this transcript
Accessing the photo album
00:00Instead of using the camera to take a picture, you can prompt the user to use
00:04the photo gallery on the device.
00:06Starting with the app.js file in the 10 -02 folder in the exercise files, I've
00:11created a window object with a button.
00:13Notice that the zIndex of the button is set to 2.
00:17I'll add click EventListener to the button.
00:21For the callback function, I'll open the device's native photo gallery using the
00:25openPhotoGallery method of the media module.
00:31The photo gallery method has many similarities to the showCamera method.
00:36For the error and cancel properties, I'll code callback functions to display
00:40alerts that reflect their states.
00:45I'll set the allowEditing property to true, to allow the user to edit the
00:49photograph before bringing it into the image view.
00:52I'll create the imageView in a moment.
00:55For the mediaTypes property, I'll set the Titanium.Media.MEDIA_TYPE_PHOTO
01:02constant, in an array, so that only photos are displayed within the photo gallery.
01:07Setting this value doesn't mean that videos have been deleted from the gallery;
01:11it just means that they're not showing here.
01:14For the success property I'll create an imageView.
01:20I'll set the image property with the image BLOB that's been returned by the photo gallery.
01:25Here it's represented by e.media.
01:28I'll set dimension and positioning properties.
01:33Finally, I'll add the imageView to the window.
01:38Let's take a look at the result on the device.
01:41I'll click the button.
01:43Then I'll choose a photo from the gallery.
01:47Here the photo is displayed in the imageView.
01:49If I want to set a different photo, I'll click the button and start again.
01:54In the next movie I'll show you how to capture visual components of your app and
01:58send them as an attachment in an email.
Collapse this transcript
Capturing the screen
00:00Any image or view can be captured as an image file.
00:04Starting with the app.js file, I've created a window to images, a button, and an Email dialog.
00:13I'll add a click EventListener for the button.
00:19For the callback function, I'll capture an image of the window and attach it to an email.
00:23The toImage method can be used with any window or view to capture its content to an image BLOB.
00:32In order to send this image BLOB as an attachment, I need to save it to a file.
00:37I couldn't find any documentation on what format an image BLOB should be saved as.
00:44So I chose PNG as a file format and it appears to work.
00:49If the file already exists, perhaps because I canceled an earlier attempt to
00:53send the attachment, I'll delete it.
00:59Now I'll create the file on disk and write the BLOB to the file.
01:03At the time I recorded this, I found that the createFile method isn't
01:06supported by Android.
01:08Next, I'll create the file on disk and write the BLOB to the file.
01:13If I send the BLOB itself as an attachment, the reader will get a file that
01:17consists of text reflecting binary data of the image.
01:21So, I'll need to read the file off the device and store it in a variable.
01:28I'll use the addAttachment method of the Email dialog to attach the image to the email.
01:35Finally, I'll call the open method of the Email dialog object.
01:40Before viewing the results in the Simulator, I'll add an EventListener to the
01:43Email dialog that listens for the complete event.
01:49For the callback function, I'll delete the file because it's no longer needed.
02:00Now let's take a look at the results in the Simulator.
02:06When I click the button, the window is rendered to an image and attached to an email.
02:11Note that when I click Send within the Simulator, the email won't actually be sent.
02:16In order for this to happen, I'd have to send this from a device.
Collapse this transcript
Playing back a sound
00:00Titanium Mobile has the ability to play local audio files such as alerts and
00:05remote audio such as podcasts.
00:07Starting with the app.js file, I've created a window, two labels, and two switches.
00:13There are two main methods for playing audio in Titanium.
00:16The first is to create a sound object.
00:19I'll add a change EventListener to the localPlaybackSwitch object.
00:25For the callback function, I'll create a sound object and set its url property
00:29to a file called gulls.mp3 within a folder I created called media.
00:43Now I'll test for the value of the switch, so that when it's on, the audio plays
00:48and when it's off, the audio stops.
00:53Let's take a listen in the Simulator.
00:57When the switch is turned ON, the sound plays.
01:00(Audio Playing)
01:02Even though I've used the documented stop method at the time of recording, when
01:06the switch is turned OFF, the audio doesn't stop.
01:09The sound object is meant for very short sounds like system sounds or alerts.
01:14When used, the sound object will load the entire sound in memory before playback.
01:19Though it does have a preload property that can be set to true, I find that it
01:23doesn't help much with its performance.
01:25As a general rule, I use the sound object for very, very short sounds.
01:31The second method for playing audio in Titanium is to use the
01:34AudioPlayer object.
01:36This object is meant for playing back sounds that are streaming.
01:40As of the time of this recording, it can't playback local audio.
01:44I'll create a new instance of the AudioPlayer object.
01:49Then I'll create a change EventListener for the remotePlaybackSwitch.
01:57For the callback function, I'll set the URL property of the audio object
02:02to remote MP3 file.
02:04To play the audio, I'll use the start method of the AudioPlayer object.
02:08It's worth noting that the methods to begin playback of audio in the sound and
02:12audio player objects are different.
02:15I'll set the audio to stop when the switch is off.
02:20Let's take a listen to the result in the Simulator.
02:23When the remote playback switch is selected, the MP3 streams from the URL.
02:29(Music Playing)
02:33You'll want to test this on the device thoroughly.
02:35Because the file is located remotely, the responsiveness of the audio playback
02:40may be affected by device data connectivity issues.
02:43With the sound and audio player objects, your application can be greatly
02:47enhanced with content that ranges from subtle audio cues to lengthier and more
02:52substantial podcast content.
Collapse this transcript
11. Gesture
Reading device orientation
00:00In this chapter, I'll show you a few of the ways in which Titanium can detect
00:04gestural information.
00:06Titanium is capable of responding to device orientation, a shake gesture, device
00:11tilt, different tap types, and finger swipes.
00:15These gestures can add another dimension of interactivity to your mobile app.
00:20Starting with the app.js file in the 11 -01 folder of the exercise files, I've
00:25created a window object, two labels and a button.
00:28By setting the orientationModes property of the window object, I am able to
00:32specify the orientations that Titanium will respond to.
00:36The orientationModes property expects an array of orientationMode constants.
00:42These constants return a numerical value that I'll access in a moment.
00:47I'll set the app to respond to the two portrait and two landscape orientations.
00:52I'll paste comments about the other constants for device orientation below.
00:58Now I'll listen for the event called orientationChange using
01:02Titanium.Gesture.addEventListener.
01:08For the callback function, I'll write some code to respond to the value of the
01:11orientation, here represented by e.orientation.
01:19Then I'll set the text property of the label to a string that contains feedback
01:23about the orientation change.
01:28Let's take a look at the results in the Simulator.
01:33I'll simulate device rotation by selecting Hardware > Rotate Left from the iOS Simulator.
01:39Notice how the label at the bottom of the window and the button at the top
01:42retain their positions.
01:44Now I'll create a click EventListener for the button object.
01:51For the callback function, I'll override the window orientation to upside down portrait.
01:58I'll do this by setting the orientation property of the Titanium.UI module.
02:05Let's take a look at the result in the Simulator.
02:09When the button is pressed in the Simulator, the device appears to rotate, but
02:13on an actual device, the content would rotate and override the orientation that
02:18was in effect before the button was pressed.
02:20Next, I'll show you how to detect a shake gesture and read data from the
02:25device's accelerometers.
Collapse this transcript
Detecting shakes and reading accelerometer data
00:00A fun aspect of mobile apps is the ability to introduce interactivity through
00:05shaking and tilting gestures.
00:07Starting with the app.js file in the 11 _02 folder of the exercise files, I've
00:12created a window object with a label.
00:15To detect the shake gesture, I'll call Titanium.Gesture.addEventListener and
00:20enter shake as the first argument.
00:24For the callback function, I'll create an alert that confirms the shake gesture.
00:31Let's take a look at the result in the Simulator.
00:35To simulate the shake in the iOS Simulator, I'll head to Hardware > Shake Gesture.
00:42To detect tilt gestures, I'll call Titanium.Accelerometer.addEventListener and
00:48listen for the update event.
00:50For the callback event, I'll set the text property of the label to the results
00:54of the three accelerometer values.
00:57I'll retrieve all the values by using e.x, e.y, and e.z.
01:03The Simulator is not capable of displaying accelerometer events.
01:08So in order to test this, I'll have to build to the device.
01:11I'll cover building to the device later in this course.
01:14But for now, let's take a look at this on the device.
01:18As I tilt the device on the X axis, I can see the reading go from 0 to -1.
01:25As I tilt it back, it goes back to 0 and then to 1.
01:29In the next movie, I'll show you how to detect different tap types and finger
01:33swipes against the device.
Collapse this transcript
Detecting different tap types and finger swipes
00:00The swipe gesture is easily detected by any window or view object.
00:05Starting with the app.js file, I've created a window object with a label.
00:10I'll attach an EventListener to the window that listens for the swipe event.
00:18For the callback function, I'll set the text property of the label to reflect
00:21the direction of the swipe, here represented by e.direction.
00:28Let's take a look at the result in the Simulator.
00:31As I swipe to the left or the right against the window, the direction is
00:35reflected in the label.
00:38Titanium can also detect two finger taps against any window or view.
00:43To do this, I'll attach an EventListener to the window that listens for
00:46the twofingertap event.
00:49For the callback function, I'll set the text property of the label to provide
00:53confirmation of the twofingertap event.
00:59Let's take a look at the result in the Simulator.
01:02To simulate a two-finger tap in the iOS Simulator, I'll hold Option and click on the window.
01:08Capturing swipe gestures is a great way to let your users engage with content
01:12in an authentic way.
Collapse this transcript
12. Preparing for app distribution
App preferences
00:00Applications developed with Titanium Mobile are configured using the tiapp.xml
00:05file located in the root directory of the project folder.
00:09Note that when opening this file, there are two tabs associated with it in the
00:13File Editing window;
00:14the Overview tab and the tiapp.xml tab.
00:18The Overview tab displays information entered when the project was created.
00:22The tiapp.xml tab contains a large list of options presented as an XML file.
00:29Before going any further, I've got to warn you, making incorrect changes here
00:33may cause your project to break.
00:35So proceed cautiously when you work with the tiapp.xml file.
00:40I'll show you some of the more important values to edit here starting with the iOS options.
00:45The persistent-wifi option denotes whether or not the device should be allowed
00:49to intermittently turn off the WiFi radio.
00:52If set to true, the device will not attempt to turn off the WiFi radio if
00:56there's been no activity in the app.
00:58The default setting is false and most of the time, this is okay.
01:03The prerendered-icon option affects the application icon.
01:07When set to false, the glossy effect will be applied to the application icon.
01:11When set to true, the icon will be used as is.
01:15The default setting is false.
01:17The statusbar-style option denotes how the status bar should appear.
01:22There are three choices here;
01:23default, which will present a silvery status bar;
01:27black, which will present a black status bar;
01:29and black translucent, which will present a see-through black status bar.
01:35The default setting is well, default.
01:38The statusbar-hidden option denotes whether or not the status bar should be shown at all.
01:43A value of true will hide the status bar;
01:45a value of false will show the status bar.
01:48The default setting is false.
01:50Skipping down to the iphone tag, there are a few more additional options.
01:57As the name suggests, the orientation tag with the device property set to iphone
02:02will set orientation options for an application when it is run on the iPhone.
02:07The same is true for the orientation tag with the device property set to iPad.
02:12Here, the settings will determine if the app should even consider different
02:15device orientations.
02:17For example, if I were writing a landscape-only app, I'd reflect that by
02:22eliminating the portrait options completely, tag and all.
02:26Note that the settings here only denote what orientations are available to be used.
02:31I still have to write code to act on these orientations.
02:34It's worth mentioning that the iPhone tag essentially acts as a plist for the application.
02:39Any additional iOS plist properties and values can be implemented here.
02:44Values for Android are represented and changed a bit differently.
02:49In order to incorporate an AndroidManifest. xml tree, I need to expand the android tag.
02:59Information on the manifest.xml file can be found at the Android Developers web site.
03:05Lastly, if you're using a mapView within Android, you need to incorporate
03:09the following code.
03:19Here you'll need to specify your Google Maps API key.
03:24You can sign up for a Google Maps API key by visiting code.google.com.
03:29Select Android, Maps API Key, and Learn More.
03:37Then select Maps API Key Signup.
03:40Tiapp.xml offers a lot of flexibility and power in configuring your mobile app.
03:46I've only covered a few of the options available and encourage you to experiment
03:50with incorporating different iOS plist and Android manifest options as you
03:55continue your app development.
Collapse this transcript
Icon badge and splash screen
00:00In this movie, I'll show you the different specifications for iPhone icons and
00:04splash screens for iOS and Android.
00:07iOS app icons and splash screen files are stored in the iPhone folder of the
00:12project's Resources directory.
00:14iOS will automatically add rounded corners and a glossy effect to the app icon.
00:19Remember that you can set the pre- rendered-icon option to true in the tiapp.xml
00:24file if you don't want the glossy effect applied to the app icon.
00:28The rendering of rounded corners on the icon is permanent and cannot be changed.
00:32The file name for the app icon is set in the tiapp.xml file.
00:37This name, minus the extension, forms the base for all other icon file names.
00:41At a minimum, I'm required to have at least the following two icons at specified
00:46sizes with the given names.
00:48If my application also targets iPad, I'll want to use the following icon file, as it
00:52will be used as the default appicon for the iPad Home screen.
00:56There are three other versions of the appicon that I highly recommend using.
01:01Each of these is used with the spotlight feature of iOS.
01:05Finally, the iTunesArtwork file is used to represent the app in iTunes.
01:10This file is a PNG file without the extension that is stored in the project's
01:15Resources directory.
01:16That's right, the Resources directory, not the iPhone directory.
01:20For a splash screen, the following files are needed.
01:23Note that like other files, these are case-sensitive.
01:27For Android, app icon and splash screen files are stored in the android
01:31directory of the project's Resources folder.
01:34There's only one app icon required for Android.
01:37For a default splash screen, I need the following file at a minimum.
01:41Titanium also allows me to store different sized splash screens to be used
01:45automatically when device resolutions match.
01:47These splash screens are located in the images directory of the android folder.
01:52Here there are 10 different pre-named folders, each with a file named default.png.
01:58Yes, the first letter of the file is lower case.
02:01It's important not to rename these folders.
02:04Also, I must use these file names.
02:07Here's a table of file sizes of each of the images within the folders.
02:11Remember that all images have the same file name, default.png.
02:16Next, I'll show you some useful tips for preparing apps that will run on
02:19both iPad and iPhone.
Collapse this transcript
iOS: Universal Binary
00:00On iOS, a Universal Binary App is one that can deploy on both the iPhone and
00:05iPad platforms with the same executable.
00:08This means that within the App Store, there's only one version of the app and it
00:12delivers appropriately formatted content according to what platform it runs on.
00:17The most important step towards creating a universal app is to select both iPad
00:22and iPhone as deployment targets for the project.
00:25This will enable the app to run on both iPhone and iPad when downloaded from the App Store.
00:30Remember that you can change the deployment targets for your app by editing
00:34the tiapp.xml file.
00:37When creating a Universal Binary App, make sure to create all of the necessary
00:41icons and splash screens and place them in the iPhone folder of the project's
00:46Resources directory.
00:48Finally, remember that Titanium.Platform.osname can be used to detect the
00:54current platform and trigger conditional code.
00:57In the next movie, I'll show you how to prepare your app to build on the device
01:01and distribute to the App Store.
Collapse this transcript
Debugging your app
00:00Debugging is a crucial part of developing a successful app.
00:04Apps that are buggy and exhibit symptoms of poorly debugged code can leave a bad
00:09taste in the user's mouth.
00:10Starting with a 12-04 folder of the exercise files, I'll show you three methods
00:15for debugging an app in Titanium Studio.
00:18The first method is perhaps the crudest, but I find it quite effective.
00:22In fact, I've been using this method throughout the entire course.
00:26To debug a specific spot in the code and then generate feedback, I simply use
00:30alert dialogs and then pass information that helps me understand what it is I am looking for.
00:35The second method is similar to the first, except the messages to myself
00:39appear in the console.
00:40I can use the Titanium.API module to log messages to the console.
00:45There are a few different methods within this console to accomplish this.
00:49I use the log method most frequently as it's the most flexible.
00:53The log method of the Titanium. API module takes two arguments.
00:58I'll open the map.js file and create code to log a message to the console.
01:12The log method of the Titanium. API module takes two arguments.
01:17The first is the level at which to log.
01:20The log name is totally customizable.
01:26The second argument is the message to log.
01:32Let's take a look at the results in the Simulator.
01:39When I select the Maps tab, a message is logged to the Console with the name of
01:43the log message in brackets and its value to the right.
01:49The last method of debugging is the most sophisticated, I'll insert a breakpoint
01:55at line 10 of the specials.js file.
01:58This is done by double-clicking the margin next to the line number within
02:01the editing window.
02:04Next, I'll select the Debug button and choose iPhone Simulator.
02:16You'll notice that the entire Titanium Studio workspace has changed, this can
02:21be very disorienting.
02:23All of the windows of the previous workspace are present, but now there's a Debug tab.
02:28I can select any of the icons at the top to manipulate the debugging process.
02:32I'll head to the Specials tab;
02:35I won't go over this window in great detail.
02:38I will however emphasize that this live-action stepping through of the code,
02:42as it's rendered to the Simulator, is important for ensuring that the code is working properly.
02:50To terminate the debug process, I'll choose the Terminate button.
02:55To close the debug perspective, I'll right-click the Debug Indicator at the top
03:00right of the main editing window and choose close.
03:05Now I'm taken back to the previous perspective.
03:09Next, I'll show you how to build your app to a device for testing
03:12and distribution.
Collapse this transcript
iOS: Provisioning and ad hoc distribution profiles
00:00At some point I need to build my app for the device in order to test and distribute it.
00:05For iOS, in order to deploy to a device you'll need an Apple developer account.
00:11Since setting that up is beyond the scope for this course, I recommend you check
00:14out Distributing iOS Applications Through the App Store, here in the lynda.com
00:19Online Training Library.
00:21I'm starting with a 12-05 folder of the exercise files.
00:25Also my device is connected to the computer and iTunes is running.
00:29To build the app to the iPhone, I'll highlight the Project folder in the Project Explorer.
00:33Select the Run button and then choose iOS Device.
00:38I'll click on the Upload link to assign a provision profile to this application.
00:43A provisioning profile I created on the Apple developer web site has been
00:46downloaded here and I'll select it.
00:49This is a common location for downloads, but yours may be in a different place.
00:54I'll leave the SDK version set to 5.0.
00:57My Developer's Certificate is in view.
00:59If you have multiple Developer Certificates, you can select them from this dropdown.
01:05Finally, I'll choose Finish.
01:10After a while, Titanium Studio installs the app in iTunes and on the device
01:14connected to my machine.
01:17I'll press Allow to continue through these dialogs.
01:23In iTunes, under Devices, I'll choose my device.
01:27Then I'll choose the Apps tab.
01:31I'll select Sync Apps, and select the app that was built by Titanium.
01:36Any other apps that you have installed on your device may appear here.
01:40Now, I'll choose Apply to sync the app to the device.
01:49From the Home Screen I'll launch the app.
01:51The app has been loaded to the device and I can navigate through using the
01:56tabs at the bottom.
01:58Now let's take a look at deploying this to an Android device.
02:02I'll head back to Titanium Studio.
02:04From the Run button I'll choose Android Device.
02:13From the Home Screen I'll choose the drawer.
02:15Then I'll launch the application.
02:18I can navigate throughout the application using the tabs.
02:22Choose the Deploy button when you're ready to distribute your application to the
02:25App Store or Android marketplace.
02:31In order to distribute your application to the App Store, you'll need a
02:35Distribution Profile and Distribution Certificate.
02:38Again, since setting that up is beyond the scope for this course, I recommend
02:42you check out Distributing iOS Applications Through the App Store here in the
02:47lynda.com Online Training Library.
02:50Once you've uploaded a Distribution Provisioning Profile and you've set the
02:54Distribution Certificate, you'll set a location to save the application package
02:59that Titanium Studio creates.
03:02I won't be distributing the application to the App Store, so I'll close this window.
03:07To distribute your application to the Android marketplace you'll choose the
03:11Deploy button and then choose Distribute Android.
03:15Since submitting an application to the Android marketplace is beyond the scope
03:19of this course, you can click the question mark to be taken to the Android
03:22Developer Documentation.
03:26Here you'll find information about creating an account and submitting apps to
03:30the Android marketplace.
03:33Testing your application on the device is crucial to creating an enjoyable and
03:37reliable app experience.
Collapse this transcript
Stepping through a finished app
00:00In the 12-06 folder of the exercise files, you'll find an app that has been
00:04created using some of the tools shown throughout this course.
00:08The Explore California app is a tab application with three main areas.
00:13Each area is loaded from an external JavaScript file so as to keep the code to
00:17concise and modular.
00:19In the Tours tab, tables are populated with an array of objects.
00:26The first row of the table launches a video.
00:31The remaining rows launch new pages that consist of different views.
00:36Included on this page is a button that launches a dialog.
00:42In a more developed app, this could be used for allowing the user to book a tour.
00:48The Tours page also features an info window.
00:52From here, the user could call Explore California from within the app.
00:56Because I am in the Simulator, this feature isn't available.
01:00The Specials tab consists of three custom table rows.
01:06The Maps tab has a web view and a table view sharing the screen with select
01:10table rows triggering annotations.
01:14The Map view has pins for our destinations and when the table rows are clicked,
01:18the Map view centers.
01:22For another project that provides a broad overview of the tools that Titanium
01:25Studio contains, check out Appcelerator's KitchenSink app on GitHub.
Collapse this transcript
Conclusion
What next?
00:00In this Essential Training course, I've focused on showing you enough tools and
00:04techniques to get started with Titanium Mobile on either iOS or Android.
00:09I doubt that you want to publish apps that have tightly limited features and
00:12functionality and display alerts all the time.
00:15So from here I encourage you to explore the application showcase at the main
00:19Appcelerator web site and have a look at some of the published apps built with Titanium.
00:24As a further step, I'd encourage you to actually download these apps from the
00:28App Store and use them, ask critical questions about the app's design and
00:32functionality in order to try and figure out how you'd code something similar.
00:37It's also a great idea to take some time to pour over the Titanium Mobile
00:41documentation for an API that you're using in order to discover and implement
00:46other properties and methods of objects.
00:48For example, there are many more events that a window or view can listen
00:53for than a click event.
00:55As a catchall application that excellently embodies its name, the KitchenSink
00:59application from Appcelerator is a wonderful resource for learning more about
01:03the ins and outs of Titanium Mobile.
01:06From the GitHub site, you can download the source code for this app that comes
01:10ready for import into Titanium Studio.
01:13Though, it's still a relatively new platform, there are lots of wikis, boards
01:17and other sites that feature Titanium Studio content, questions and answers.
01:22When searching for anything related to Titanium, I suggest that you include the
01:26keyword's Titanium Mobile Appcelerator in your search along with the object
01:30constructors, methods or properties.
01:33Doing this will increase the chances that you're actually getting a relevant
01:36search results and not some random images of metal, as would happen if you
01:40search for Titanium image, for example.
01:43Don't forget about the Developer Forum at the Appcelerator Developer Center.
01:47I recommend that you first search for your question there, and then ask one of
01:51the community, if you can't find what you're looking for.
01:54Finally, take a look at a few more of the courses in the lynda.com Online
01:59Training Library to expand your knowledge in designing and creating mobile apps.
02:04Any of the titles on designing apps are great for enhancing broad
02:07knowledge about app design.
Collapse this transcript
Goodbye
00:00I hope you've enjoyed this Titanium Mobile Essential Training Course.
00:04This course was designed to expose you to the different tools that Titanium
00:08Mobile offers for building apps.
00:10Now it's time for you to put what I've shown you into action.
00:14Code a few simple apps to become familiar and comfortable with JavaScript and Titanium.
00:18Try out some more sophisticated logic in your EventListeners to ratchet up
00:22the user experience.
00:24Dive into the Titanium Documentation and use your knowledge to implement other
00:28APIs in your application.
00:30Most importantly, from here go forward and create.
Collapse this transcript


Are you sure you want to delete this bookmark?

cancel

Bookmark this Tutorial

Name

Description

{0} characters left

Tags

Separate tags with a space. Use quotes around multi-word tags. Suggested Tags:
loading
cancel

bookmark this course

{0} characters left Separate tags with a space. Use quotes around multi-word tags. Suggested Tags:
loading

Error:

go to playlists »

Create new playlist

name:
description:
save cancel

You must be a lynda.com member to watch this video.

Every course in the lynda.com library contains free videos that let you assess the quality of our tutorials before you subscribe—just click on the blue links to watch them. Become a member to access all 98,466 instructional videos.

start free trial learn more

If you are already an active lynda.com member, please log in to access the lynda.com library.

Get access to all lynda.com videos

You are currently signed into your admin account, which doesn't let you view lynda.com videos. For full access to the lynda.com library, log in through iplogin.lynda.com, or sign in through your organization's portal. You may also request a user account by calling 1 1 (888) 335-9632 or emailing us at cs@lynda.com.

Get access to all lynda.com videos

You are currently signed into your admin account, which doesn't let you view lynda.com videos. For full access to the lynda.com library, log in through iplogin.lynda.com, or sign in through your organization's portal. You may also request a user account by calling 1 1 (888) 335-9632 or emailing us at cs@lynda.com.

Access to lynda.com videos

Your organization has a limited access membership to the lynda.com library that allows access to only a specific, limited selection of courses.

You don't have access to this video.

You're logged in as an account administrator, but your membership is not active.

Contact a Training Solutions Advisor at 1 (888) 335-9632.

How to access this video.

If this course is one of your five classes, then your class currently isn't in session.

If you want to watch this video and it is not part of your class, upgrade your membership for unlimited access to the full library of 1,893 courses anytime, anywhere.

learn more upgrade

You can always watch the free content included in every course.

Questions? Call Customer Service at 1 1 (888) 335-9632 or email cs@lynda.com.

You don't have access to this video.

You're logged in as an account administrator, but your membership is no longer active. You can still access reports and account information.

To reactivate your account, contact a Training Solutions Advisor at 1 1 (888) 335-9632.

Need help accessing this video?

You can't access this video from your master administrator account.

Call Customer Service at 1 1 (888) 335-9632 or email cs@lynda.com for help accessing this video.


site feedback

Thanks for signing up.

We’ll send you a confirmation email shortly.


By signing up, you’ll receive about four emails per month, including

We’ll only use your email address to send you these mailings.

Here’s our privacy policy with more details about how we handle your information.

Keep up with news, tips, and latest courses with emails from lynda.com.

By signing up, you’ll receive about four emails per month, including

We’ll only use your email address to send you these mailings.

Here’s our privacy policy with more details about how we handle your information.

   
submit Lightbox submit clicked