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