navigate site menu

Start learning with our library of video tutorials taught by experts. Get started

Building a Note-Taking App for Android

Building a Note-Taking App for Android

with David Gassner

 


Building an app for one platform just isn't good enough anymore. Android, Windows, and iOS support are all required for a successful product—but learning the different environments is difficult. This course is one of a matched set spanning the three platforms and will demonstrate their similarities and differences. Start with the product most familiar to you, then watch the parallel courses to understand how to bridge your knowledge.

Like its companions, this course will take you through building a complete mobile app from scratch; but this installment uses the Android SDK and Java to get the job done. Author David Gassner shows you how to install the SDK and the Android Developer Toolkit, create a project, save data on a device, build and control screen layouts, and create action bars and icons that control navigation.

These three related courses will use the same assets to develop the same app. (See Building a Note-Taking App for iOS and Building a Note-Taking App for Windows Phone 8 and Windows Store for more information.) Compare and contrast the different steps and discover the similarities and differences!
Topics include:
  • Previewing the note-taking app
  • Creating virtual devices for testing
  • Unique concepts in Android
  • Creating the Eclipse project
  • Using local data storage
  • Adding and retrieving data with the Shared Preferences API
  • Creating screen designs
  • Creating and editing notes
  • Supporting older versions of Android with ActionBarSherlock

show more

author
David Gassner
subject
Developer, Mobile Apps
software
Android
level
Intermediate
duration
3h 7m
released
Jun 24, 2013

Share this course

Ready to join? get started


Keep up with news, tips, and latest courses.

submit Course details submit clicked more info

Please wait...

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



Introduction
Welcome
00:00 (music playing)
00:04 My name is David Gassner, and this is
00:06 Building a Note-Taking App for Android. In this project course, I'll show you how
00:12 to create a complete mobile app from scratch using the Android SDK, and the
00:15 Java Programming Language. After installing Eclipse and the Android
00:21 Developer Tools, and creating a starting project, I'll show you how to save data to
00:26 a device's persistent storage with the shared preferences API.
00:32 I'll then show to create the app's two screen layouts, and create the Java
00:35 classes that control them. I'll create action bars and icons that
00:41 control navigation, and show how to make the app work well on multiple versions of
00:47 Android. This is one of three courses that describe
00:51 how to build a note taking app for mobile devices.
00:54 The others are for iOS and Windows Phone 8.
00:58 I hope this course gives you the information you need to start building
01:01 your app for Android.
01:03
Collapse this transcript
What you should know before watching this course
00:01 This course is designed for software developers who want to learn quickly how
00:05 to build apps for Android mobile devices. If you have experience building apps for
00:10 other mobile environments, such as iOS, Windows Phone, Blackberry or others,
00:15 you'll find that there are a lot of concepts that Android has in common with
00:19 those SDKs. But Android also has its own unique
00:25 vocabulary and application architecture. Here's some of the skills that you might
00:30 find helpful in learning how to build Android Apps.
00:33 You'll be programming in Java, which is a completely object-oriented programming
00:38 language. So, the more you know about
00:41 object-oriented concepts such as inheritance, encapsulation, and
00:45 polymorphism, the more quickly this application architecture will make sense.
00:51 If you don't already know Java, it's good to know at least one other programming
00:54 language. So, you can compare Java to what you
00:57 already know. And the most helpful of these languages
01:01 would be C-style languages, such as C, C# or JavaScript, because they have a lot in
01:06 common with Java in terms of their syntax. To get started with Java, you can watch
01:14 the course, Java Essential Training. In this course, I teach the basic syntax
01:19 of the Java programming language. How to install and use the Eclipse
01:24 development environment. And how to create project packages and
01:28 classes for command line Java applications.
01:32 You can also watch the Foundations of Programming series.
01:37 Most importantly, the fundamentals course and the object oriented design course.
01:42 So, you can learn move about OOP concepts, and how they might be implemented in the
01:47 Android environment. To learn moree about Android, you can
01:51 watch the course Android App Development with Java Essential Training.
01:57 In this course, you'll learn about the basic application architecture of Android,
02:02 including the relationship between activities and screen layouts, and how to
02:05 use graphics and animations. And you'll get a complete tutorial on the
02:11 Android Developer Tools, the Eclipse plug-in that I use throughout this course.
02:16 So, these are the skills that can help you get started more quickly.
02:20 But I'll show you everything you need to know throughout this course.
02:25 Because I'm going to show you how to code the app from scratch.
02:28 And you can use these other courses to go back and understand more about what you've
02:32 been programming.
02:34
Collapse this transcript
Related courses
00:00 This course, building a note-taking app for Android, is one of three courses that
00:05 are being released simultaneously in the lynda.com library.
00:10 The other two courses teach how to build the same sort of note-taking app for other
00:14 mobile platforms. One of them focuses on iOS, the operating
00:19 system that drives the iPhone, iPad and iPod touch.
00:23 The other course shows you how to build a note taking app for Windows Phone 8 and
00:28 specifically for Windows Phone 8, and as a Windows Store App.
00:33 The sort of app you would deploy on Windows 8 and Windows RT.
00:38 The goal of these three courses is to show you how to use the native tools for each
00:42 platform. For Android, you'll be programming in
00:46 Java. For IOS in Objective-C, and for the
00:49 Windows platforms, XAML and C#. And the development tools are different
00:55 too. In this course, I'll be showing you how to
00:59 work with Eclipse, with the Android Developer Tools, or ADT plugin.
01:04 For IOS applications, you build in Xcode. And for Windows phone and Windows store,
01:11 you'll use Visual Studio. All of these programming languages and
01:16 tools have rich capabilities for their particular platforms.
01:20 If you decide you want to build native apps for each platform, these are the best
01:24 available programming languages and tools completely supported by the platform
01:28 vendors.
01:30
Collapse this transcript
Using the exercise files
00:01 This course is accompanied by exercise files that you can use to follow along.
00:05 I've placed the exercise files on my desktop, but you can copy them anywhere on
00:09 your hard disk. The exercise files include one folder for
00:14 each of the course's chapters. And within the folder, you'll find zip
00:19 files. Each of the zip files is an Eclipse
00:22 archive project that you can import into Eclipse when you're using the Android
00:27 developer tools. For example, the O3 getting started folder
00:32 has a zip file called launcher icon. And, if I go back a level.
00:37 And then go the chapter, Data Model. I'll find four ZIP files, for each of the
00:42 four exercises in that chapter. To use one of the exercise files, go to
00:46 Eclipse with the Android Developer Tools, and I'll describe how to install that
00:51 early in the course. From the menu, File > Import.
00:57 In the Import dialog, go to the General category, select Existing Projects Into
01:04 Workspace and click Next. Now, click on Select archive file.
01:11 Click browse navigate to the Exercise Files and go to the folder you want to
01:16 work with. I'll go to 04_DataModel.
01:20 Then, choose the project archive file for that exercise.
01:26 So I'll open one called RetrievingData. Then follow the rest of the prompts to
01:32 complete the import process. You should then be able to open up the
01:37 project tree in the Package Explorer view, and open the source folder in its Java
01:42 classes, and the RES or resources folder, and find all of the applications
01:46 resources. After importing any of the projects from
01:52 the exercise files, if you see a series of red warnings indicating that Java classes
01:56 aren't being recognized, it typically means that there's a problem with the Java
02:00 compliance level. It's a common issue when you have Java 7
02:06 installed. To fix it, go to the Project Properties to
02:10 the Java compiler section. And change your Java compliance level from
02:17 1.7 to 1.6. After saving the change, the errors should
02:21 be cleared. To run the application, click the Run
02:25 button. The first time you run a button after
02:28 you've imported it, you'll see this dialog, the Run As dialog.
02:34 Choose Android Application. If you have an Android device conected to
02:38 your computer and you've enabled it for USB debugging, you'll be able to load the
02:42 application on the device and see it running.
02:46 Or you can use the Android Emulator. I'll describe how to use the emulator
02:52 throughout the course and show you how to create a variety of virtual devices to
02:56 reflect the different screen sizes, pixel densities, and versions of the Android
03:00 operating system. Once you're done with an exercise, you can
03:06 close a project by right-clicking on it in the Package Explorer and selecting Close
03:10 Project. Or, you can remove the project from your
03:14 workspace completely by right-clicking and choosing Delete.
03:19 If you don't want to Delete the project contents, leave this checkbox unchecked.
03:25 Click OK and the project goes away. But it's still there on your hard disk,
03:29 and you can re-import it later. The course is designed so that you can
03:34 work through all of the exercises from beginning to end using a single Eclipse
03:38 project. Or if you prefer, you could open up each
03:42 project for each individual exercise to make sure you're at the right point.
03:47 It's up to you. The exercise files also include a
03:52 solutions folder. And you'll see the same set of chapters
03:55 there. But the zip files there are the solution
03:58 projects, the finished version of each exercise.
04:02 I've named these with the suffix of _solution so that you can open them at the
04:06 same time in Eclipse as the starting project because you can't have two
04:10 projects of the same name. You can then compare the two bits of code.
04:17 Finally, there's an assets folder. The assets folder contains one subfolder
04:22 called logo. And there you'll find a graphic that I use
04:26 as the application's launcher icon. There are two versions.
04:31 One with square corners, and one with rounded corners.
04:34 And I'll describe why those exist, later in the course.
04:39 So those are all the assets that you'll find in the Exercise Files.
04:42 The course is designed, so you can work through and build the app yourself
04:46 following along with each video. There are no typing help files.
04:52 You'll do all the coding yourself. And at the end of the course, you'll have
04:56 a complete working app. The app has already been distributed
05:00 through the Google Play store, and the Android app store.
05:04 So you can't take this version of the app and deploy it yourself, but you can take
05:08 the lessons you've learned and apply them to your own Android apps.
05:13
Collapse this transcript
1. Project Overview
Features of the note-taking app
00:00 Before we gets tarted building the app, I'd like to talk about the specifications.
00:05 The application's requirements. The name of the app is Plain Ol' Notes.
00:11 And there are three versions of the app for three different operating systems.
00:15 In this course I describe how to build the Android version.
00:20 But there are also versions available for Windows Phone and for iOS.
00:25 The application implements these common features of note taking apps.
00:30 Users can create and edit simple notes that are purely text based.
00:35 There isn't any support for storing photographs or other rich media.
00:40 There are two screens in the app. And the application implements navigation
00:44 between the two screens and data sharing between them.
00:49 The notes are saved persistently to the mobile device's storage.
00:54 And we're using a feature of the Android SDK called shared preferences to store
00:58 that data. And finally the application will be easily
01:02 discoverable. That is it follows visual design patterns
01:07 that are common to android apps. And so the user should be able to easily
01:11 figure out how to use the application. The application has two screens.
01:17 The list screen displays notes in a list. Each note occurs on a single line item.
01:24 And only one line of the note is displayed.
01:27 The Editor screen is where you can add or edit a note.
01:31 You get to the editor screen either by touching the Plus icon to create a new
01:35 note Or by touching an existing note. The command pattern at the top of the
01:42 screen is called the action bar. The action bar interface was introduced in
01:48 Android 3, or Honeycomb. And it looks like this.
01:51 It starts with the app logo or launcher icon on the left.
01:57 Then the name of the app and then a series of command buttons.
02:00 In our application, there will be only one command button on the list screen.
02:06 The plus icon to create a new note. In the editor's screen There won't be any
02:10 explicit command buttons on the right. But the launcher icon will transform into
02:16 a back button so the user can easily go back to the list screen.
02:20 The application will work on all versions of Android going all the way back to
02:25 Froyo, or Android 2.2. And the user interface will adapt
02:30 automatically to both different versions of the operating system, and to different
02:35 screen sizes and pixel densities, including phones, and tablets.
02:40 Here's a picture of the app running on a Froyo based phone device.
02:44 On a phone running Jelly Bean or Android 4.2, and on a Nexus 7, also running Jelly
02:50 Bean. There are subtle differences in the user
02:53 interface between each of the three devices, that are driven by the operating
02:57 systems capabilities, and the size of the screen.
03:02 Here are the requirements and features of the list screen.
03:05 As I mentioned the user can create a new note by touching the plus icon.
03:11 On the larger screens, the tablets, the plus icon is accompanied by the text
03:15 create just to the right of the plus icon. For longer notes where the text doesn't
03:22 fit on the line, the list item will be automatically truncated and ellipsis or
03:25 three dots will be shown at the end. And if a note has line feeds, that is if
03:31 it has multiple lines, only the first line will be displayed.
03:35 And once again, ellipsis will be shown at the end.
03:38 Finally, each list item shows a graphic on the right side of the line.
03:45 I've selected a pencil graphic to indicate to the user that they can edit a note by
03:49 touching it, but you can select any kind of graphic that you prefer.
03:54 On the editor screen the data entry will word wrap automatically where necessary
03:59 and will accept explicit line feeds to support multi line text.
04:06 On newer versions of the operating system, the user can stop editing and return to
04:11 the list screen by touching the devices software based back button, or the app
04:15 launcher icon in the action bar. On older versions of the operating system,
04:21 the user can finish editing by pressing the hardware back button, or a back button
04:25 that's a part of the user interface. It'll look like it's in the action bar.
04:32 But that's actually a fake out. The action bar is only availible starting
04:36 with Honeycomb. But you can fake the action bar interface
04:40 by making changes to your screen layouts. This is what the app looks like on a Jelly
04:46 Bean based phone, and it's using a real action bar, and this is what it looks like
04:49 when it's working on Froyo. With the fake action bar.
04:54 In both cases, the list screen has the app logo or launch icon, the name of the app,
04:59 and a plus icon. The appearance is a little bit different,
05:04 but all of the functionality works exactly the same.
05:08
Collapse this transcript
Demoing the finished app
00:00 The app that I'm describing how to build in this course is named, Plain Ol' Notes.
00:05 I'll show you how to build it from start to finish, and provide a completed version
00:09 of the code. But if you'd simply like to load it onto
00:13 an Android device, a phone or a tablet, you can get it from one of two places.
00:19 It's available in the Google Play store on this page under Plain Ol' Notes, and it's
00:23 also available on Amazon.com for Kindle Fire users.
00:28 Again, named Plain Ol' Notes. It's free in both environments.
00:34 If instead you'd like to run through the application on an emulator, you can go to
00:38 Eclipse and import the code from the exercise files.
00:42 In Eclipse go to the menu and select File > Import > Existing projects into work
00:48 space. Browse to choose an archive file.
00:53 Go to the 01 overview folder and choose plainolnotes.zip.
01:01 There are two projects in this archive: Plain Ol' Notes and action bar sherlock,
01:06 an open source library that the application depends on.
01:12 I'll finish the import process, and that imports both projects.
01:18 When you're working on your code and testing it, make sure you have both
01:21 projects open. The Problems view will show a set of
01:24 warnings. You can ignore those, they're produced by
01:27 the action bar Sherlock library and don't do your application any harm.
01:32 To test the application, go to the source folder and to the default package, and
01:37 open up one of the classes. Then run the application on an emulator or
01:44 a device. I'll run it on an emulator that's running
01:49 Android 4.2.2, or Jelly Bean. The application has a very simple UI,
01:55 there's a plus icon on the Action bar and when you click it, you go into an editing
01:59 screen. Here you can type any note.
02:05 I'll type here's a note. And then you can either click the device's
02:08 Back button, or the launcher icon which has turned into an Up button.
02:14 When you return to the List screen, the note is saved persistently.
02:18 I'll click Plus again, and I'll add another note.
02:22 And this time I'll click the Back button. To edit an existing note, click or touch
02:29 it, and then you can make changes and return to the List screen and the changes
02:35 will be saved. And to delete a note, touch and hold for a
02:42 moment, and you'll get a context menu, touch Delete, and the note is gone.
02:47 If you exit the application by returning to the home screen and then restart it,
02:52 the notes will still be there because they're being saved to persistent storage.
02:58 So I'll go to my App list and I'll load the application again, and there's my
03:03 note. So that's it, a very simple application
03:06 that's designed to teach you the critical parts of building a note application.
03:12 Two activities, a single editing environment and saving the data
03:15 persistently on the device, so that it's still available after an application
03:20 restart or a device reset.
03:23
Collapse this transcript
Setting up the developer tools
00:00 To get started building Android apps, you'll need to download the Android
00:05 developer tools available from this web page, at
00:08 developer.android.com/tools/index.html. When you click the link to download the
00:15 Android SDK, you're taken to this page, and you should see a link to download the
00:18 SDK bundle for your operating system. I'm working on Mac OS X, so, I see the
00:24 link for ADT bundle for Mac. The bundle includes both the SDK for the
00:29 latest version of Android and a customized version of Eclipse.
00:34 In order to run Eclipse, you'll need a Java 6 run time.
00:39 You can get that from Oracle if you're working on Windows, or if you're working
00:43 on Mac, on a slightly older version, it might already be on your system.
00:47 But, when you try to start up Eclipse on Mac, if you're prompted to install a Java
00:51 6 run time, you might see a failure when you try to download it from Apple.
00:57 And that's because, as of the time of this recording, Apple has discontinued making
01:01 that available directly. But you can download the Java 6 run time
01:07 and developer tools from this link, atsupport.apple.com/kb/dl1572.
01:15 That will take you to a link that tells you about Java for OS X 2013-002 or a
01:20 later release. And you can click the download link, and
01:25 follow the prompts to install the right version of Java.
01:29 After you've installed the Java runtime and you've downloaded the apb bundle and
01:34 extracted it, you can then run Eclipse by going into the bundle, opening the Eclipse
01:39 folder and double-clicking on Eclipse. Now again, if at this point you have
01:46 problems getting Eclipse started, it will most likely be because you don't have the
01:49 right version of Java on your machine. And you'll have to go get it and install
01:54 it. The bundle is delivered with the SDK, or
01:57 software developer kit for the latest version of Android only.
02:02 As of the date of this recording, that was Android 4.2, Jelly Bean.
02:07 But if you want to support other versions of Android and you'll probably want to,
02:11 then you'll want to download at least one other SDK version.
02:16 To do that, go to the menu and select Window > Android SDK manager.
02:23 The Android SDK manager window will show you what is already installed.
02:27 Now, I've already made some changes in my installation.
02:31 But initially, you should have the Android SDK tools, and the Android SDK platform
02:36 tools installed. And you should have the SDK platform for
02:40 the latest version of Android. You won't have documentation
02:44 automatically, but that's okay, you can get that from the web.
02:47 And you won't have SDKs for older versions of Android.
02:51 I recommend that you install the SDK platform for Android 2.3, that's
02:56 Gingerbread and Android 2.2, that's Froyo. You only need the SDK platform downloads,
03:03 you don't need anything else. And then, if you're working on Windows and
03:08 you want to debug with an actual device as opposed to the software emulator, you
03:12 should also go down to the extras section and download the Google USB driver.
03:19 You only need to do this on Windows. If you're working on a Mac, you'll see
03:23 this message. That this driver is not compatible with
03:27 Mac. And that's because Android devices connect
03:29 pretty much automatically on a Mac computer.
03:32 So, if you followed all these steps. You've made sure you have the right
03:36 version of Java on your computer. You've downloaded and extracted the
03:41 Android developer tools bundle. You've fired up Eclipse.
03:45 You've opened up the Android SDK Manager. And you've added in other earlier versions
03:49 of the SDK, and on Windows, the USB Driver, then you're ready for your next
03:53 step. Setting up some virtual devices that you
03:57 can use for testing on your development computer.
04:00 And I'll show you how to do that in the next video.
04:03
Collapse this transcript
Creating virtual devices for testing
00:00 One of the greatest challenges in building Android apps is the sheer volume of
00:04 Android devices and operating system versions that are out there.
00:08 Just taking into account different versions of Android, you can see from this
00:12 data on the Android developer website the number of different versions and how
00:16 they're distributed in the user population.
00:20 The latest version Jelly Bean 4.2 only has 1.6% usage as of March 2013.
00:29 While Gingerbread, a much older version, has over 40%.
00:33 In large part that's because Gingerbread is the latest version of Android that runs
00:37 well on single core processors. The later versions, Honeycomb, Ice Cream
00:43 Sandwich and Jellyean all run best on Dual and Quad-Core processors such as the
00:47 Quad-Core processor that's in the Nexxus 7.
00:51 So as a developer, you need to test on a variety of operating systems and that
00:56 doesn't even take into account the sheer number of devices out there.
01:02 As of last year, there were over 4,000 distinct Android devices in the market.
01:08 And it's impossible for you to have each one of them in your shop.
01:12 And so, to test your application, you'll need to use the Android emulator and
01:16 create a variety of virtual devices that reflect the different types of screens.
01:22 Pixel densities and operating system versions that you want to test on.
01:27 You can easily create virtual devices from within Eclipse through a piece of software
01:32 called the Android Virtual Device Manager. You can open it by going to the Clips
01:38 menu. And selecting window and then selecting
01:41 the virtual device manager. To test my application, I've created 3
01:46 virtual devices. I have one, that's a phone size and that's
01:51 for the oldest version of android, that I'm going to support.
01:56 Android 2.2 or Froyo and then I have two virtual devices, running on the latest
02:00 version Android, as of the time of this recording.
02:05 One that looks like a phone, and one like a tablet.
02:08 In order to make sure my application behaves on a broad range of Android
02:12 devices, I'll use these virtual devices. I'll also test on actual devices.
02:19 For my testing I use a Nexus 4 and a Nexus 7 for the most recent version of Android,
02:23 an older phone, a Motorola Droid 2 that's running on Gingerbread 2.3, and an
02:28 original Kindle Fire that's also running on Gingerbread, although a modified
02:32 version. To create your own virtual devices, click
02:38 New, and give your virtual device a name. For example, if I wanted to create a new
02:44 virtual device that was a phone running on Gingerbread, I might call it 'Phone
02:48 Gingerbread'. You AVD names can't have any spaces in
02:53 them, but otherwise you can name them descriptively.
02:57 Then, pull down to the device list, and you can either choose one of the four
03:01 named templates that are listed here, or one of the screen sizes that are listed
03:04 below. So, for example If I wanted to emulate a
03:09 phone running on Gingerbread, I might choose the Nexus S.
03:15 That has a screen resolution of 480 by 800, and a pixel density of HDPI.
03:21 Then I would select a target, and I would choose Android 2.3.
03:25 Only the SDKs that you've installed in your copy of eclipse will show up on this
03:29 list. And if you don't see the operating system
03:33 version you're looking for, back out of this process, go back to the SDK Manager,
03:37 and install the right SDK. Then close down Eclipse, restart Eclipse,
03:44 and come back to this screen, and your SDK should show up.
03:49 Next, set options for your virtual device. You can indicate that you want a hardware
03:54 keyboard available, and you can select a skin with hardware controls.
03:59 If the app you're working on is going to use a camera, you can emulate that using
04:04 either a front or a back camera, or both. You can set memory options to reflect what
04:10 your device might have, and you can also set internal storage And in SD card.
04:17 I typically set my SD card size at 64 megabytes.
04:21 Even if you do use the SD card in your app, you probably won't use a whole lot of
04:24 storage space during your testing. And the smaller the size, the faster your
04:30 emulator will start up. Finally, to speed up loading of the
04:34 virtual device, after the first time it's loaded, Turn your snapshot option on.
04:40 The first time your virtual device loads, it's going to be deadly slow no matter
04:44 what you do. And that's even with a very fast
04:47 processor, and even a solid state drive, it's just slow.
04:52 But if you use the snapshot option, the second time you start up that virtual
04:55 device, it'll be a lot faster. After you've selected all your options,
05:01 click OK. And your virtual device will have been
05:04 created. You can either start up your virtual
05:06 device from here, by clicking the start button.
05:10 Or you can wait 'til later, when you're actually ready to test your application.
05:15 And I'll show you how to select and start up a virtual device from within Eclipse,
05:19 when we get to a review of the finished application.
05:23
Collapse this transcript
2. Understanding Android Specifics
Issues in cross-platform development
00:00 This course, and it's related courses, building a note taking app for Android,
00:04 iOS and Windows Phone are designed for developers who want to build a single app
00:09 and then deploy it on multiple mobile operating systems.
00:14 And have decided that the most important thing is to get the best possible
00:18 performance, the broadest access to features of the devices, and if possible,
00:23 direct support from the vendor that created the operating systems.
00:29 If this describes you, then you might decide to use native tools and languages
00:33 for each of the operating systems. That's not the only way to get the job
00:39 done. There are many other options available.
00:43 For example, if you're accustomed to building web sites and web pages, you
00:47 might decide to work with the tools PhoneGap or Sencha.
00:52 Both of these libraries let you build an app interface with web standard languages
00:57 and then wrap those web pages to make them look like native apps.
01:02 The libraries that come with these tools let you work with device features such as
01:07 geolocation centers and others. The purpose of these tools is to let you
01:13 build a single app and then deploy them to iOS, Android, Windows Phone, BlackBerry,
01:17 and any other operating systems that are supported by that tool.
01:23 You can learn more about these tools at these websites.
01:26 There are a number of platforms that are specifically targeted at building game
01:30 apps for multiple platforms. These include Adobe's Flash, partnered
01:36 with AIR, Unity, GameSalad and others. These platforms let you build rich
01:42 graphical interfaces using a variety of tools and then program with a particular
01:46 language that's designed for that platform.
01:51 For example, flash works with actionscript.
01:54 Unity lets you program in Javascript and GameSalad is unique in that it let's you
01:59 build game apps while writing zero code. You can learn about these tools, at these
02:06 websites. You can also choose a platform that let's
02:10 you program with a specefic programming language.
02:14 For example, Titanium, Mono for Android, and Xamarin.iOS.
02:20 These tools are all designed to let you use a language other than the native
02:23 language. And then to take your application and
02:27 deploy it, either to a single operating system or multiple operating systems.
02:32 Titanium lets you program in JavaScript and then deploy an app to multiple
02:36 operating systems. While Mono and Xamarin.iOS are targeted at
02:40 a single operating system and let you program in C Sharp.
02:46 These tools might work well for you. The downside to watch out for is typically
02:51 they won't give you the best performance that's available on the devices or there
02:55 might be other compromises. If you decide to go down the road of
03:00 working with native tools and languages, here's the challenge, you'll need to learn
03:05 and work with multiple programming languages.
03:09 Java for Android, Objective C for IOS and C sharp or Visual Basic for Windows
03:14 phones. You need to learn different vocabularies
03:18 and design patterns and you use different developer's tools.
03:23 You'll find that you can reuse some application assets, such as graphics or
03:27 data files. But for the most part, you'll have to
03:31 rewrite code for each platform. But the benefit of this approach is great.
03:36 You'll get the best possible performance available on that operating system.
03:42 You'll get complete access to all device features.
03:44 You'll get direct support from the operating system vendors and perhaps most
03:49 importantly, you'll get the cleanest upgrade path that's available.
03:54 So, that what you'll need to learn to work with multiple programming languages, Java
03:59 for Android, Objective C for iOS, access to those features first.
04:04 And you won't have to wait for the other platforms to catch up.
04:09 The choice is yours. This course will show you how to build
04:12 Android apps using the native tools, the Java programming language and the Eclipse
04:16 Development Environment.
04:20
Collapse this transcript
Unique concepts for Android
00:00 Here are some concepts, vocabulary and other ideas about working in Android.
00:05 First let's talk about the screens that go into making up an Android app.
00:10 Each screen is known as an activity and it's represented by a Java class.
00:17 When you want to create a new screen, you create a new class, you extend a class
00:21 code activity, and you add the class to your application by editing the app
00:25 manifest. We'll talk about all the details of this
00:31 process later on in the video. The activity's presentation is determined
00:36 by it's layout. You can predefine a layout using an XML
00:41 file or a group of XML files known as fragments.
00:47 Or you can build the layout dynamically at run time with Java code.
00:52 And then when you want to switch from one activity or one screen to the next, you
00:55 create an object called an intent. Just like activities, these are
01:01 represented by Java classes. Each screen has a lifecycle.
01:08 When you launch a screen it goes into a state called created, from there into a
01:12 state called started, and then into something called resumed.
01:17 As you're shutting down a screen, it goes into a phase called paused, then stopped
01:22 and finally destroyed. It doesn't go through all these phases
01:27 every time. In fact a string is only destroyed when
01:30 you explicitly turn off the app or when the device needs to reclaim memory.
01:36 But along the way the android runtime will try to just certain methods of your Java
01:40 classes. These are methods that are already
01:44 implemented and have certain default behaviors.
01:47 But you can override these methods and add your own behaviors.
01:52 When you launch your application, its main activity is launched activity.
01:57 And the method onCreate is called. This is the method where you'll put a lot
02:02 of your initialization code. And I'll show you the types of code we'll
02:06 use in later videos. From the created phase it goes to the
02:10 started phase. And a method code onStart is called.
02:15 And then a method code onResume. And then going back in the other direction
02:19 you'll see methods code onPause, onStop and onDestroy.
02:24 When an activity is in the paused phase, it can immediately go back to the resumed
02:28 phase and then you'll call the method onResume again.
02:33 And when it's in the stop phase, it can restart and that results in calling two
02:37 methods, onRestart and onStart. I won't be using all of these methods in
02:43 this course. My focus will be on the onCreate method,
02:46 but they're all available to you as the developer to extend so that you can
02:50 control your app's behavior. Here's a very small example of an activity
02:57 class. The name of the class is main activity.
03:01 And it extends a class called ListActivity.
03:05 Some activities extend ListActivity if they're going to display lists of data,
03:09 and some activities will extend simply the activity class.
03:13 It all depends on what that activity is going to do.
03:18 And in this class, I've created an override of the onCreate method.
03:23 The first thing it does is to call the super classes onCreate method, and then it
03:26 has some conditional code. Figuring out which version of Android it's
03:31 running on and selecting a screen layout to determine how the screen will look.
03:38 There are another few lines of code toward the bottom of my onCreate method, register
03:42 for context menu and assignment of a variable called datasource and a call to a
03:45 custom method called refresh display. This is actually the onCreate method of
03:51 the finished Plain Ol' Notes application on Android.
03:57 So, if you work through all of the exercises in this course, you'll be coding
04:00 all of this yourself and you'll understand what each line of code does.
04:06 In android, there is no specific difference between a phone and tablet.
04:12 For example, in iOS when you build an app you designate it as an iPhone app or an
04:16 iPad or Universal app. In Android this distinction doesn't exist,
04:23 instead you look at devices based on the screens.
04:28 And a particular screen is defined by its resolution, that is the number of pixels
04:33 it has in width versus the number of pixels it has in height.
04:37 But then those values are categorized by the operating system as small, normal,
04:42 large, and extra large screens. It's also important to know that each
04:48 device is represented by a screen density defined as the number of pixels within a
04:52 physical area of the screen. We referred to this as the dpi or as dots
04:58 per inch. And it's particularly important when
05:02 you're creating graphics for your application.
05:06 All of your graphic files along with other kinds of files such as XML files are
05:10 stored as what are known resources. When you create your graphics, you'll need
05:16 to provide them in multiple sizes for the different screen densities.
05:22 There are four screen densities to match the four standard screen sizes.
05:27 Low, medium, high, and extra high. And I'll talk about how to create graphics
05:33 of different sizes using certain automated tools that are available on the web and
05:37 where to put them in your application. It's up to the Android operating system to
05:43 decide which versions of your graphics it's going to use at run time.
05:49 As you're running your app, the Android operating system looks at the device,
05:53 determines the screen size and the screen density and chooses a set of graphics for
05:58 you. All you need to do is provide the
06:01 graphics. So, that's a look at some of the common
06:04 terms that you'll encounter in Android app development.
06:08 And a look at how Android decides what assets to use on screens of different
06:12 sizes and densities.
06:14
Collapse this transcript
iOS and Windows Phone developers beware
00:00 If you're coming to Android from other mobile operating systems, such as iOS or
00:04 Windows Phone. There are some common challenges that
00:08 Android developers encounter that are worth knowing about.
00:12 I'll categorize these as the following. Android as an open source software
00:17 product. Java and the Dalvik Runtime as a managed
00:21 code environment. The existence of multiple ways to
00:25 distribute apps, and device fragmentation. That is the large number of different
00:31 devices, operating system versions and so on, that exist in the Android ecosystem.
00:37 Let's start with a discussion of Android's open source status.
00:41 Android is an open source product. When Google creates a new version of
00:45 Android, it typically releases that version to the large device vendors first,
00:50 such as Samsung, HTC, and so on. These vendors then modify Android for
00:55 their own devices, and release the devices.
00:59 And at the same time, Google might work with one of the hardware vendors to create
01:03 what they call a reference device. A device that represents what they think
01:08 is perfect to run this version of the operating system.
01:12 Those reference devices are released under the brand name Nexus.
01:16 Google controls the development of the core version of Android, but then gives
01:20 the software away. In the early going for each version, it
01:24 will only go to the device vendors, but then eventually Google will release that
01:27 version of Android to everybody. As of the time of this recording, Android
01:33 4.2 was the most recent version you could find on various devices, but 4.1 was the
01:37 most recent version that was available as pure open source.
01:44 The good news is that because it's open source, you can create your own version of
01:47 Android. That's what Amazon has done.
01:50 It took a version of Android, and then customized it for release on the Kindle
01:54 Fire. When you use a Kindle Fire, that version
01:58 of Android look somewhat like the pure version, but there are a lot of
02:01 differences implemented by Amazon. And the same thing is done by Barnes and
02:07 Noble, and even Samsung, a very large-scale device vendor.
02:11 The downside is that you can only depend on the devices with the Nexus brand to
02:16 have the pure version of Android. Nearly all other devices will have their
02:21 versions of Android modified by the vendors, and this contributes to what we
02:26 call the fragmentation of the Android marketplace.
02:30 I'll talk more about fragmentation at the end of this video, but the open source
02:34 status of Android is one of the great contributors to this issue.
02:38 The second issue to be aware of is that Java is a managed code environment.
02:45 That means that the Java programming language doesn't support explicit memory
02:50 management, it has a garbage collector, and you create one file per class, in
02:54 contrast to say Objective C. This means that Java development can feel
03:01 greatly simplified to developers who are coming from Objective C.
03:06 But some of the control they had over the device, say in the iOS operating system,
03:10 may not be available in the world of Android.
03:14 The downside of the manage code environment is that if you compared apple
03:18 and apples. That is if you take devices of exactly the
03:22 same capability, and you write exactly the same sort of functional code in Objective
03:27 C for iOS and in Java for Android. You might see lesser performance on the
03:33 Android device. Now, the reality of that issue isn't that
03:37 important. The newest devices coming out for Android
03:41 have quad core processors and plenty of resources to run java applications.
03:46 But, if you're used to having very fine tune control over the hardware and the
03:50 operating system in the world of iOS, you might find that you have less of that sort
03:54 of capability in the world of Android. Other issues in the Java programming
04:02 language to be aware of are first that Java is statically typed.
04:07 In order to coordinate different classes and different objects, you need very well
04:11 defined interfaces. If you're coming to Java from a more
04:14 dynamic language, you might find that you have to be much more specific to get your
04:19 Java code to compile. Developers coming to Android from say
04:24 Windows Phone who are accustomed to working with C Sharp will find this a very
04:28 comfortable transition. That's in part because C# is inspired by
04:33 Java. It shares a lot of Java's syntax and a lot
04:37 of its behavior. Particularly in regard to memory
04:41 management. Another issue to be aware of in Java is
04:44 that floating point arithmetic isn't always accurate.
04:47 2 plus 2 doesn't always equal 4. If you're working on an application where
04:52 you're doing floating point arithmatic and you're getting weird results, take a look
04:57 at a class called big decimals. The big decimal class can be used to solve
05:03 common issues, such as inaccurate math. It takes integers and keeps them as
05:08 integers. And it takes a certain number of decimals
05:11 after the point, and retains that information in a way that what we call
05:15 primitive variables in Java might not be able to.
05:19 If you're coming from a programming language where 2 plus 2 always equals 4,
05:23 then this might seem very odd, but it's a common issue in Java, not just in Android.
05:31 And also beware about multi-threading. The world of Java is such that if you're
05:36 doing a multi-threaded application and you encounter a crash condition in one thread,
05:40 the entire app will come down. That's not always the case in other
05:45 environments. But it's true in Android and with Java.
05:48 Once you've finished an application and you're ready to distributed it, you'll
05:53 find that the Android world is very different from say iOS or Windows Phone.
05:59 Users who have iPads or iPhones can only get their apps from the Apple app store,
06:03 and the same thing is true in the world of Windows phone.
06:08 But in the world of Android, there are multiple market places or app stores.
06:13 The default one for most users is the Google Play store.
06:17 Formerly known as the Android app store. This is where you can get the apps that
06:22 have been distributed through Google. But you also have vendors that have
06:27 created app stores for particular app classes.
06:31 Amazon for the Kindle Fire and Barnes and Noble for the Nook.
06:35 Commercial app developers tend to distribute their apps through all of these
06:39 stores if at all possible. To hit the broadest possible population of
06:44 Android device users. And in addition to these major market
06:48 places, there are many smaller websites and app stores available, and I've listed
06:53 some of them here. These represent a small fraction of the
06:58 Android ecosystem, but many Android app developers like to distribute their apps
07:02 through these stores as well. As an app developer, the more stores you
07:07 distribute through, the larger the number of users you'll reach.
07:11 But that means that when you upgrade your app, you'll need to redistribute the app
07:15 through all these stores as well. You don't need to distribute through all
07:20 of the app stores, choose the ones that make sense for you and stick with them.
07:26 The App store capabilities vary in a number of ways.
07:29 In security features, the level of curation, the size of the audience they
07:33 can reach, and their capabilities. For example, the Barnes and Noble Nook app
07:40 store, just recently implemented in-app purchases as of early 2013.
07:46 A capability that's been part of the Google Play store for quite awhile.
07:49 Finally, the biggest problem that Android developers have to deal with is
07:53 fragmentation. As of 2013, there have been more than
07:57 4,000 different models of Android devices that have been created and sold.
08:05 Not all of these devices have broad distribution.
08:09 In fact, only about 150 device models in total make up about 80% of the market.
08:16 But if you're trying to get to everybody, you really have a challenge in how you
08:19 test your app and make it compatible with all of these platforms.
08:24 In addition to device fragmentation, there's the fragmentation of the operating
08:28 system itself. Just taking into account, the pure
08:33 versions of Android released by Google. There are about seven major versions out
08:37 there, starting with Froyo and all the way through the most recent version, Jelly
08:42 Bean. You can find out the current statistics
08:47 for usage of different versions of Android at this website, atdeveloper.android.com.
08:52 But then as I mentioned earlier, there's also the different versions of Android
08:56 that have been customized by different device vendors.
09:00 Device makers such as Samsung are increasingly creating their own services
09:05 that compete directly with Google's. Their own music stores, their own music
09:10 layers and so on. And as an app developer, it's important to
09:15 know what your app will be sitting alongside.
09:18 So, how do you deal with fragmentation. Well, the obvious answer is to test your
09:23 application on as many physical devices as you possibility can.
09:28 I have four different Android devices. An original Kindle Fire, an older Motorola
09:33 Droid 2, and the newer devices, the Nexus 4 and Nexus 7.
09:38 But that's just a small, small fraction of the devices that are out there.
09:43 And so, use the Android simulator. Create as many virtual devices as you feel
09:48 you need to, and test your application in as many different scenarios as you
09:52 possibly can. And then hope for the best.
09:57 When you release your app through any of the app market places such as Google Play,
10:01 if you provide a website for support of your app I guarantee you'll hear from
10:05 users for whom your app doesn't work on their particular device.
10:11 So, that's a look at some of the issues that are common for Android developers,
10:15 and that you might encounter if you're developing for the first time in Android.
10:20 And you're coming from other operating systems such as iOS and Windows phone.
10:25
Collapse this transcript
3. Getting Started
Creating the Eclipse project
00:00 So, let's get started building the application from scratch.
00:04 If you still have the plain old Notes project open in Eclipse, you can remove it
00:07 from the Package Explorer, by right-clicking on the project, and
00:10 choosing Delete. If you don't select the option to delete
00:14 the project contents on disk, the actual project will still be there in the
00:18 background, but it just won't be shown in eclipse.
00:23 So, I'll click OK and I'm starting from a blank slate.
00:27 Now, I'll create my starting project. I'll go to the menu and choose File > New
00:33 > Android Application Project. The application name can be anything you
00:39 want. I'll create my application name as Plain
00:42 Ol' Notes. The application name can contain spaces
00:46 and special characters as needed. The project name however, shouldn't have
00:50 any spaces or special characters. And it must be unique within your Eclipse
00:55 workspace. I'll create this project as starting
00:59 project. The package name must be globally unique.
01:04 To guarantee that, you should start the package name with your domain in reverse
01:08 domain notation. I'm going to set my package name as
01:14 com.davidgasner.plainoldnotes. If you're following along in these
01:19 exercises to learn how to build the app, I recommend using this same package name.
01:25 But when you're ready to submit your own apps to the Google Play or Amazon App
01:28 Store, Or any other Android app store, you should make sure you're using your own
01:32 globally unique name. If you try to submit an app with a package
01:38 that's already in use, it'll be rejected. Next, set the minimum required SDK.
01:45 Eventually, this application is going to support everything from froyo, Android
01:49 2.2. All the way through the most recent
01:52 versions of Android. But to make the early development process
01:57 a little bit easier I'm going to set my minimum required SDK to API-13 or Android
02:03 3.2. In the very last part of the development
02:07 process, I'll be making the application flexible.
02:10 So that it can adapt to different versions of Android.
02:13 But while I'm building it's primary functionality, I'll stick with the most
02:17 recent versions. I'll accept all the other defaults on this
02:21 screen and click Next. On this screen, I'll uncheck the option to
02:25 Create the custom launcher icon. That's the graphic that's shown on the
02:30 Android Start Screen and on the Home screen on the more recent versions of
02:33 Android. I have my own launcher graphic that I'll
02:38 be adding to the application later. So, for the moment, I'll accept the
02:42 default launcher icon, which will be a picture of the Android robot.
02:46 I'll accept all of the other defaults on this screen and click Next.
02:52 I'll accept the default to create a main link activity, and click Next again.
02:58 And I'll also accept these defaults for the activity name, the layout name and the
03:03 navigation type. And I'll click Finish to create my project
03:08 and app. When the application first opens in
03:12 Eclipse, it shows the main activities layout.
03:16 A layout is an XML file. It's displayed here in Wizzy Wig design
03:21 mode, but you can also click the tab at the bottom to see the XML format.
03:27 The root element of a layout file is a layout tag.
03:31 And there are a number of different layouts that you can use.
03:35 We're starting with something called a relative layout.
03:37 And in this app, we'll use a combination of relative layouts and linear layouts.
03:43 Within the layout, there's something called a TextView.
03:47 The Text View is displaying a string that's identified by this id hello
03:52 underscore world and this value and application name are defined in the file
03:57 called strings.xml. You can find that file in this folder
04:03 named values. Which is under another folder called res,
04:07 for resources. I'll double click the strings.XML file,
04:12 and show the hello world identifier is here, and that it has a value of hello
04:16 world. There's also an identifier for the app
04:22 name. I set this value when I created the
04:25 project, and here is how the value is declared.
04:28 With plain old notes and the apostrophe with a prefix of a backslash.
04:35 That's how you escape special characters in simple strings in Android.
04:40 Backslash apostrophe, backslash N for line feed, and so on.
04:45 So, now let's try running the application. To run the application reliably, you
04:52 should always have a Java class open. I'll go to my source folder, and then to
04:57 the package com.davidgassner.plainoldnotes, And I'll
05:00 open the one and only Java class that was created by my new project.
05:06 I'll double click the tab for the Java class to open it up to full screen.
05:10 And show that there are two methods in the Java class.
05:13 The onCreate method is called automatically.
05:17 As this activity or screen opens up on the Android device.
05:23 It's calling a method called set content view, which is in turn, opening the layout
05:28 file activity_main. And that's that same activity main xml
05:33 file we already looked at. There's another method here called on
05:37 create options menu, and we'll come back to that later in the development process.
05:42 With the Java class open, I'm ready to run my application for the first time.
05:48 I'll go to the menu and choose Run and then Run.
05:51 The first time you run a project, you'll probably see this run as dialogue.
05:58 Choose Android Application and then Eclipse should open an emulator.
06:04 Load the application and run it. If this is the first time you've run this
06:08 particular emulator it might take a few minutes to open.
06:12 And you might be asked to click on an icon in the middle and drag it to the right.
06:17 But then once the application has been installed and opened you should see it
06:20 running on screen. I'm just going to drag the emulator to the
06:24 center of the screen and then I'll come back to ecliipse.
06:28 And I'll make one little change. I'll go to my strings.xml file and I'll
06:33 change my hello world id from hello world to hello from plain old notes.
06:41 I'll save my changes by pressing Cmd+S on Mac or Ctrl+S on Windows.
06:49 Then I'll click back on the Java class mainactivity.Java and this time I'll run
06:54 by clicking the Run button on the toolbar. After clicking the button, I'll switch
07:00 back to the emulator and after a moment I should see the new version of the
07:04 application loaded and running in the emulator.
07:09 So, that's how we get started building the simple application.
07:12 There's obviously a lot more work to do, including changing the icon to a custom
07:17 icon, but I'll describe how to do that in the next video.
07:22
Collapse this transcript
Creating a launcher icon
00:00 When you first create an Android application, it's populated by default
00:04 with a launcher icon, a picture of the Android robot.
00:09 Or you can create your own custom icon during the project creation process.
00:13 But when you're building a commercial app, you'll probably have a graphic designer
00:17 create your own custom icon. And you're going to need to create a
00:22 number of different versions of it. One for each of the common pixel densities
00:26 or screen densities that you'll find on different Android devices.
00:30 The launcher icon is shown both in the action bar when you're working on a newer
00:35 version of Android. And, after you've installed the
00:39 application, it'll show up in the application list and sometimes on the
00:42 start screen. You can add the application to the start
00:46 screen by going to the application list, clicking and holding on the application,
00:51 and then dropping it on your start screen. When you first create the object the
00:58 application is populated with three different sizes for the application
01:02 launcher. There's one in a folder called Drawable
01:06 HDPI for high density devices. One in MPDI for medium and in XHDPI for
01:12 extra high density. Your job is to take your original graphic
01:17 design and create the various sizes that are needed.
01:22 Fortunately there's a tool that will make this very easy.
01:27 Here are the graphics that I'm going to be using.
01:30 I'll minimize Eclipse and the Emulator and then I'll go my exercise files.
01:36 Within the exercise files there's an assets folder and under that logo folder.
01:43 I've provided two different versions of my launcher icon design the first is an
01:47 original graphic that might have come from a graphic designer.
01:52 It's a square. Your launcher icon should be the same
01:57 dimension in height and width. And this original graphic is 1024 by 1024.
02:03 But there's an important feature of launcher icons that's required in the
02:06 Android system. Each launcher icon should implement at
02:10 least some transparency or alpha channel to give it a unique silhouette on the
02:15 screen. It doesn't have to be absolutely unique.
02:20 But it shouldn't be a simple square. And so, I've created and have provided a
02:24 version of my graphic that has rounded corners.
02:29 And the corners on the outsides are transparent.
02:32 This is enough transparency to satisfy the Android requirement.
02:36 You can create this sort of png file in fireworks, photoshop, illustrator, and
02:41 many other graphic design applications. For this exercise, I'm going to use this
02:48 finished graphic. The easiest way to create the different
02:52 sizes that you need is with a free web based application called the Android
02:56 Assets Studio. I'll go to my browser.
03:01 And then to the Android Assets Studio, which I've bookmarked.
03:05 The Android assets studio is completely free.
03:07 And it will help you create the different size icons that you need for your
03:11 application launcher, for Action Bar and Menu icons and many others.
03:18 I want to create a launcher icon. So I'll click that link.
03:21 And that takes me to the launcher icon generator.
03:25 You can create Launcher icons using one of these standard clip-art graphics.
03:30 Or you can use text. Or as I'm going to do here, you can use
03:33 your own custom-designed image. I'll click the Image tab and that opens up
03:39 a browse dialogue. Then, I'll navigate to the Logo folder
03:43 under my Assets folder under Exercise files.
03:46 And I'll choose the version of the graphic that has the alpha or transparency.
03:52 It takes just a moment to upload the file to the Android Asset Studio screen.
03:56 Now, I can do all sorts of things to modify it.
04:00 I can add padding, add transparent foreground color, scale it with cropping,
04:04 shapes and add backgrounds, but I'm going to accept it But I'm going to accept it in
04:09 its default setting. Now, scroll down to the bottom.
04:12 And now I see the different size graphics that are going to be generated by the
04:18 asset studio. By default, I'll get four different
04:21 graphics. One for extra high density.
04:24 One for high density. And one for medium.
04:27 But also one for extra extra high. If you're going to be submitting your
04:32 application to the Google Play or Android apps stores.
04:36 also generate a web icon, you'll need that icon when you're ready to submit the app.
04:42 To do that, just click the Generate Web Icon button.
04:45 And you'll get an extra large version of the icon that's suitable for that purpose.
04:52 Scroll back up to above the preview display, and click Download Zip.
04:57 That results in creating and downloading a file called ic_launcher.zip.
05:02 Now go to the folder where that was downloaded.
05:05 It should appear in your Downloads folder. Then, extract its contents.
05:11 On Mac, you can just double click the zip file.
05:14 On Windows, you'll have to write click, and select Extract.
05:19 Then, double click to open the folder that was created.
05:22 And you'll find the 512 by 512 version, plus a folder called RES.
05:28 This RES folder for our resources, matches the RES folder in your project's directory
05:33 structure. And just as with your project, it contains
05:38 name folders for each of the different graphic sizes.
05:41 To take these files and add them to your project go back to the folder that
05:46 contains the RES folder. Select everything and copy it to the
05:52 clipboard. I press Cmd+C on Mac, you can press Ctrl+C
05:56 on Windows. Then come back to Eclipse.
06:01 Go to your project folder, right click and choose Paste.
06:05 When prompted to overwrite select Yes To All.
06:09 That will result in overwriting the default PNG files and where necessary
06:14 creating new folders. You'll have the four different size
06:18 launchers that you created. And you'll have the web version as a
06:22 member of the project root. Then go back and take a look at your
06:26 layout and you should see the new icon is displayed in the action bar.
06:31 Run the application again in the emulator, and you should see the custom icon appear
06:35 next to the application name. And if you go back to the home screen or
06:39 to the application list, you should see the custom icon appear there too.
06:45 So, that's how we take a basic graphic and turn it into a launcher icon with all the
06:49 different sizes you need to display on different Android devices.
06:54 And also the larger web version that you'll use when you submit the app to an
06:58 app store.
07:00
Collapse this transcript
4. Creating the Data Model
Using local data storage
00:00 The Android SDK offers multiple Options for storing and retrieving data
00:04 persistently on Android devices. The Options include: shared preferences;
00:11 arbitrary files in the format of your choice, including XML or JSON, and SQLite
00:16 based relational databases. All three of these options let you persist
00:23 data. That is, save the data to device data so
00:27 that it sticks around between application launches, or between the time you shutdown
00:32 a device and start it up again. The shared preferences API is the simplest
00:38 of these options. A shared preference is simply a data
00:43 object, and the form is a key value pair. The key is always a string, but the value
00:50 can be one of a number of data types, including integers, long integers,
00:54 doubles, Booleans, and strings. You can manage shared preferences data,
01:00 either completely programatically using Java, or through a special kind of
01:05 activity or screen called a preference activity.
01:11 In this course, I'll only be working with shared preferences using the Java
01:14 programming language. You work with shared preferences using the
01:19 API, but the data is actually stored in an XML file that's saved on disk.
01:25 You don't have to use any XML parsing libraries, such as DOM, or SAX, or JDOM,
01:29 that's all done for you by the preferences API.
01:33 And it is important to note that shared preferences are stored unencrypted.
01:40 That is in plain text. That doesn't mean it's easy for users to
01:44 see the data, to get access to shared preferences XML files they have to root
01:49 the device. That is, get complete administrative
01:53 access to it. But it's not encrypted, and if you need
01:56 encryption then shared preferences is probably not the way to do it.
02:01 The Android SDK also has support for creating your own files in what ever
02:05 format makes sense for your application. These files can be created and read on
02:13 persistent media, and they can be read and written with standard Java file APIs.
02:19 There's not particular format for these files.
02:21 You can choose XML or JSON, or delimited data files, or binary files.
02:27 Again, whatever makes sense for you. And it's possible to create read-only
02:31 files that you can toss into an applications resources folder and then
02:35 address through a resource ID. Just like you might with a layout file, a
02:41 drawable graphic file or other resources. And files can be created in either
02:47 internal storage. That is, where it's local to the
02:50 application, or external locations, where the files can be shared with other
02:54 applications. Finally there's SQLite.
02:59 SQLite is a powerful database engine. And the Android SDK has its own API for
03:06 working with SQLite databases on Android devices.
03:10 SQL lite is great where you need to work with highly structured data with multiple
03:15 tables that are joined together, and you want to work with the SQL language.
03:21 Android has its own implementation. And you can find a lot more information
03:28 about SQLite at www.sqlite.org. But, you should look at the documentation
03:33 that comes with android to find out how to work with it in this environment.
03:38 This includes all of the classes and interfaces that are in the
03:42 android.database.sqlite package. So, those are all the options that are
03:47 available for working on Android. In this course, the data we'll be saving
03:52 is notes. And each note is a key/value pair where
03:56 both the key and the value are strings. The key will be a unique date-time stamp
04:02 expressed as a string, and the value will be any Java-based string.
04:08 The shared preferences API is perfect for this.
04:11 It makes it very easy to store key/value pairs.
04:15 And using a little bit of Java wizardry, we can easily sort the data by the keys.
04:21 If you want to learn about other options for working with data on Android devices,
04:25 watch the Lynda.com course, Android SDK: Local Data Storage.
04:30 But in this course, I'll show you everything you need to know about shared
04:34 preferences for building this particular note taking app.
04:38
Collapse this transcript
Modeling a data item with a Java class
00:00 Regardless of how you're going to store data in your Android app the first step in
00:04 creating a data persistence layer is to create a Java class that models the data
00:08 you're going to store. I'm going to be storing notes and each
00:14 note is going to have a key and a value. So, I'm going to create a Java class that
00:19 has those two properties or fields. I'm working in a version of my project
00:24 called data item. And I'll go to the source folder within
00:28 the data item project. Right now, my project only has a single
00:33 package, the application package. I'm going to create a subpackage.
00:39 And I'm going to put all the Java classes that have to do with data management in
00:43 that package. I'll right-click on the existing package
00:48 and choose new package and I'll add a sub package of .data and click Finish.
00:55 Now I'm ready to create my Java class. I'll right-click on the package and I'll
01:02 select new class and I'll name the new class note item.
01:09 You can name this class anything you want, and you'll see a variety of different
01:12 naming conventions. You'll see some developers use a suffix of
01:18 DTO, for Data Transfer Object, or VO, for Value Object.
01:24 I typically use item to indicate that this is an item of data.
01:28 The superclass is Java.lang.object. That is we're not extending or inheriting
01:35 from any particular Java class. This is the kind of class sometimes known
01:40 as a POJO or a Plain Old Java Object. It'll have whatever properties we define
01:47 and whatever methods we define, but nothing else of significance.
01:52 I'll click Finish and that creates my new Java class.
01:56 Next, I'm going to declare the two properties that my object is going to have
02:00 the key and the text value. I'll place the cursor inside the class
02:06 definition, and I'll declare two private fields.
02:10 I'll start with private string, and then the name of the field, key.
02:16 And I'll declare a second field, also a string, and I'll set this ones name as
02:21 text. Whenever you create private fields within
02:25 a class you need to make them publicly accessible to the rest of the application.
02:31 And you do that using getter and setter methods.
02:34 Eclipse is able to generate that code for you.
02:38 So, I'm going to select these two private fields then I'll right click and I'll
02:43 choose Source, Generate Getters and Setters.
02:49 I see the two fields in the class that I just defined, and I'll click Select All.
02:53 I'll set the insertion point for After Text, and then I'll click OK.
03:00 And that generates a getter and a setter for each of the two private fields.
03:05 These values will now be available to anywhere else in the application.
03:10 Finally, I'm going to add some custom code, to this particular class.
03:15 Whenever we create a new node in the application, we're going to automatically
03:19 set the key, using the date, time stamp for the current time, on the android
03:23 device. So, instead of using a standard
03:28 constructor method, that is a method where you say, create a new note with new note.
03:35 Instead, we're going to create a special method called get new.
03:39 I'll be adding more code here, so I'm going to go into full screen mode by
03:43 double-clicking on the tab at the top of the editor.
03:47 Then, I'll place the cursor after my getters and setters and I'm going to
03:50 create a new public method. It's going to be static which means that
03:54 this method can be called from the class without first instantiating the class.
03:59 I'll start with public then static, and then the name of the class, note item, and
04:03 the name of the method, get new. Placing the name of the class before the
04:09 name of the method means that we're going to be returning an instance of that class
04:14 from this method within the method here are the steps we have to follow.
04:22 First, we have to set the key value and that's going to be drawn from the date
04:27 time stamp that is the current time of the current device down to the second.
04:34 Here is the code we'll use. I'll start by declaring an instance of a
04:39 class called locale. I'll type in the name of the class, then
04:43 I'll press Ctrl+Space. And I'll select locale from the list of
04:48 available classes. That results in adding an import statement
04:52 to the top of the class, and it will allow me to use that class throughout all the
04:55 code in this class. I'll go back to the code I'm creating and
05:01 I'll name the object that I'm creating locale also but, with a lower case initial
05:05 character. In Java Conventions, the upper case
05:10 initial character means it's a class and the lower case means it's an object or an
05:14 instance of a class. Next, I'll instantiate the locale with
05:20 equals new. And then, I'll use the locale classes
05:25 constructor method and I'll pass in a string of en_US.
05:32 Even if you're not working in the United States, and even if you're going to be
05:35 translating your application, I strongly recommend using this locale.
05:41 For the task we're about to follow, which is getting the current date time stamp.
05:46 The English US locale will give you a date/time stamp that's easily sortable.
05:50 And that's going to be an important feature of our application.
05:53 Sorting the data by when it was created. Next, we'll call a method called set
05:59 locale. And this is a static method of the locale
06:03 class. So, I'll type Locale.setDefault, and I'll
06:07 pass in my locale object. The locale object's name was suggested by
06:13 Eclipse. And then, I pressed Tab to get to the end
06:17 of the line, and typed in the semicolon to finish the statement.
06:22 Now, I'm ready to use that locale to create a date time stamp.
06:27 To create the date time stamp, I'm going to be using another Java class called a
06:31 simple date format. The simple date format class takes a
06:35 string pattern that indicates the format of the date time I want to get.
06:42 To define that, I'll declare a variable as a string that I'll name pattern.
06:47 And I'll use this string, yyyy in lower case then a dash, then two Ms in upper
06:54 case. Then another dash and two d's in
06:59 lowercase. This will give me the year in a four-digit
07:02 format, the month in a two-digit numeric. And the current day of the month in a
07:07 two-digit numeric, and separated by hyphens.
07:11 Then I'll put in a space, and here's the time.
07:15 HH in upper case, mm in lower case and ss in lower case.
07:22 This time separated by colons. And finally at the end, Z.
07:30 The Z means add notation that shows the offset from Greenwich mean time.
07:35 So, now I'll have a completely unique date time stamp that's generated from the
07:39 current Android device. And the format will be sortable based on
07:44 when it was created. Now, I'll create an instance of the simple
07:48 date format class. I'll type the beginning of the class name,
07:53 simple d and press Ctrl+Space. And that automatically auto completes the
07:59 name of the class and adds an import statement for the class at the top of the
08:02 code. Going back down to where I'm coding, I'll
08:07 name this object formatter. And I'll instantiate it using a
08:13 constructor method of this class. Call a new simple date format.
08:19 Once again, I'll type in the beginning of the class name and press Ctrl+Space.
08:24 And then, I'll choose the version of the constructor method that I want to use.
08:28 A version where I pass in a string pattern.
08:31 I'll select that constructor method. I'll press Tab and finish the statement.
08:37 Finally, I'll create the key value by calling the formatter objects format
08:42 method, and I'll pass in the current date time value.
08:46 That code looks like this. I'll create a string variable named key.
08:51 And I'll get its value from formatter.format, and I'll pass in a new
08:55 instance of the date class. I'll press Ctrl+Space, and select a
09:00 constructor method for that class. That adds an import statement where
09:05 necessary, and I'll Tab and complete the statement.
09:09 And now, I have a string value that will be used for the key of the current note.
09:14 So, now I have a key and I'm ready to create the node object.
09:19 I'll declare a new variable as a NoteItem, and I'll call it note.
09:23 And I'll instantiate using the default no arguments constructor method of this
09:28 class. That code looks like this, new NoteItem.
09:33 In Java, if you don't define an explicit constructor method, the class will be
09:39 given an automatic null arguments constructor method.
09:44 If you prefer you can define it explicitly but at this point its not needed.
09:49 Now, I'll set the note objects key using the set key method that was generated
09:54 earlier and I'll pass in the key value. And I'll set the initial value of the text
10:01 property to an empty string and finally I'll return the note.
10:07 Now, I'll save my changes and I'll see that there's a little warning here and it
10:11 tells me some recommendations for how to use dates in Java.
10:17 This recommendation doesn't apply in this case so to get rid of the warning click on
10:21 the warning icon. And from the quick fix list that appears,
10:27 select the first one, add suppress lint simple date format to get new.
10:34 Suppress lint is a Java directive that tells the lint tool, that's the tool
10:38 that's working in the background, to examine and tell you about potentially
10:42 invalid code. To not worry about this particular method.
10:48 And it's saying specifically don't worry about the simple date format class.
10:53 I know what I'm doing. So, that's the entire editing for item
10:57 class. It has private fields for the values it
11:00 wants to store, public getters and setters to make those values accessible to the
11:05 rest of the application. And then, a special method to generate a
11:12 new instance of the class that populates the object with the key based on the
11:16 current date time stamp. In the next video, I'll show you how to
11:21 create a data source class that starts putting this class to work.
11:27
Collapse this transcript
Creating a data source class
00:00 After you've created the Java class to model a single instance of a note.
00:04 The next step is to create a Java class that will manage all of the data.
00:08 And this is typically called a data source class.
00:11 I'm working in a version of the project called data source.
00:16 And I'll go to my data package that I previously created, and I'll create
00:19 another new class. I'll call this one notes data source.
00:25 And as I did with the note item class, I'll make this a POJO, by extending the
00:29 super class, java dot blank dot object. I'll click Finish to generate the class.
00:36 This class is going to hide all of the functionality that's used to put, get and
00:41 remove data items from the shared preferences data storage.
00:47 And it's going to expose that functionality through a set of methods.
00:52 The first method is going to be called find all.
00:55 And it's going to return a list of notes. I'll place the cursor within the class
01:00 decoration, and I'll create a new method. It'll be public.
01:05 And it's going to return an instance of something called a list.
01:08 In Java, the list is an interface. I'm going to be saying that I'm returning
01:15 a list. But the concrete implementation of the
01:18 list will be something else. That will be defined within the method I'm
01:22 creating. The list should be notated to say what it
01:25 contains. I'll press Control Space, and I'll select
01:29 list. And that adds the import statement for
01:32 that class at the top of my code. And then it completes the name of the
01:37 interface with generic notation. And being asked to declare here, what kind
01:42 of objects this list is going to contain. And I'm going to type in the name of the
01:48 class that I already created Note item. I'm saying that this method that I'm
01:54 defining is going to return a list of note item objects.
01:58 Now I'll name the method, find all, and I'll ass in the braces to indicate the
02:04 body of the method. I'm going to start by creating a list
02:08 containing a single note. It'll look like this.
02:11 First, I'll declare the list itself. I'll use the same syntax I used in the
02:17 return value of the method. List note item and then I'll name this
02:22 item, note list and I'll substantiate it. Using the constructor method for a class,
02:31 called A ray list. It looks like this.
02:34 New, a ray list. I'll type in the beginning of the class
02:39 name. I'll press control, space and choose a ray
02:42 list and notice that eclipse automatically adds generic notation to indicate the same
02:47 member object that I used in the variable declaration here.
02:53 Now I'm declaring the object as a list. But instantiating with ArrayList.
03:00 And that's because ArrayList is a concrete class that implements the list interface.
03:06 I'm using polymorphism to say this is the class I want to use, but this is the class
03:11 I want every one else to think it is. The nature of an ArrayList Is that it
03:18 stores data in the order in which you put it in.
03:21 It doesn't automatically sort anything and it just always stores it in exactly the
03:25 same order. Next, I'm going to create an instance of
03:30 my note item class. I'll create note item, and I'll call it
03:35 note. And I'll get the instance of the note by
03:38 calling that static method that I created earlier, noteitem.getnew.
03:44 So now I have a single note and I'll add it to the list using notelist.add and I'll
03:48 add in my note object. So now I have a list containing a single
03:55 item. And I'll return it from this code, using
03:59 return note list. I'll save my changes, and make sure that
04:03 all the errors and warnings have gone away.
04:06 Now I'll be coming back to this method and filling in a bunch more code later on to
04:10 deal with the data that's stored on disk. But this is enough code to get started and
04:17 test this method. But before I go to testing I'm going to
04:20 add two more method signatures, called updated and remove.
04:25 The update method will be used to add or update a note And it will look like this.
04:31 Public boolean update. So I'm naming the method update and I'm
04:36 going to be returning a boolean value, a true or a false.
04:40 The update method will accept an instance of the note item class, that I'll call
04:45 note. And I'm not going to implement any code
04:49 here yet. I'm just going to return a value of drew.
04:52 Finally I'll add the remove method, it will be very similar to the update method.
04:59 It will be public and it will return a Boolean value.
05:03 The name of the method will be remove and it will receive an argument Data typed as
05:07 a note item. As with the update method, I won't
05:11 implement any specific code yet. I'll just return a true value.
05:17 I'll save my change, and review all of the code in this class.
05:22 It has a findAll method that returns a list of notes, and an update and a remove
05:27 method. Now, I'll go back to the main Activity
05:30 class. This is the class that represents my
05:33 primary screen, the screen that's shown as the application first opens.
05:39 Within the main activity class, I'll declare an instance of my data source
05:43 class. I'll place the cursor after the class
05:46 declaration. And I'll create a private variable.
05:50 Data type as note data source. I'll type in the beginning of the class
05:55 name, and press Control Space. That auto-completes the class name and
05:59 adds its import statement at the top. And I'll name it data source.
06:05 Now, I'm only declaring the variable here. I'm not instantiating it yet.
06:11 I have to instantiate it in the on create method.
06:14 The method that's called as the application comes to the screen.
06:19 So I'll place the cursor in the onCreate method after the call to set content view.
06:25 And I'll data source equals new notes data source.
06:30 As with the note item, I have an automatically generated no arguments
06:33 constructor method that I'm calling here. Now, to test this, I'm going to call the
06:39 find all method of this new object. And then output the note that will be in
06:44 the list that's returned. I'll declare a list.
06:49 Because I'm in a new code set, that is a new Java class, I have to do the process
06:53 of Ctrl+Space and importing the class. (SOUND) I'll name this notes.
07:02 And I'll get it's value from datasource.findAll the source that I
07:06 previously created. Then, I know I'll have a single note so
07:10 I'll retrieve it with this code. NoteItem note equals notes.get and I'll
07:16 pass in a value of zero which means I want to get the first item in the list.
07:23 And then, I'll output the value of the notes key.
07:27 That is the date-time stamp. I’ll do this using a class called log.
07:34 The log class is used to debug Android applications as they’re running.
07:40 Either in an emulator or an actual device. The log class has to be imported like many
07:44 others. And it's a member of a package called
07:48 Android.util. And it has a series of static methods.
07:52 I'm going to use one called i. The i method is called the info method.
07:59 And it's a way of simply outputting a string or a value that you want to see in
08:02 your debug. It takes two arguments: a tag You should
08:06 always use the same value as your tag, it'll make it easier to debug in the
08:11 Eclipse tools. And then I'm going to output the key of
08:16 the note that I just got from the data source, it'll look like this.
08:22 Note, dot, get key. I'll save my changes.
08:26 Now I'm ready for my test. I'm going to debug the first time I run
08:30 the application. That will trigger the logging
08:34 functionality. Once you've triggered it the first time,
08:38 you should be able to run word debug and see the output in a tool called log kept.
08:45 I'll click the Debug button and I'll choose Android Application.
08:50 If you're prompted for the level of logcat output, choose info or verbose.
08:56 I'm not being prompted for that information because I already answered the
08:59 question in a previous session. I'll switch back to the emulator.
09:05 Make sure that the application is running. Then I'll come back to Eclipse.
09:09 And up here I'll go to something called the DDMS perspective.
09:13 With the DDMS prospective selected, I'll then go down to the log cat tab at the
09:18 bottom and double click to Open. The log cat screen shows all kinds of
09:24 information that you may or may not be interested in.
09:29 But to filter it and see only warn messages, click into the Search Textbox.
09:34 And type tag colon and then the name of your tag.
09:39 Which I set as notes. And here's the result.
09:44 I'm getting the key of my note, which is a daytime stamp with an offset from
09:47 Greenwich Mean Time. If you're using an emulator, the date and
09:51 time value could be anything. But if you're working with an actual
09:56 Android device, You should see the date time and offset from that device.
10:03 If you're seeing this value correctly, then you know that you correctly
10:06 instantiating you note, putting it into a list, returning it from the data source,
10:11 and you're ready for the next step, implementing data persistence with shared
10:15 preferences, and we'll get to that in the next video.
10:20
Collapse this transcript
Adding data to shared preferences
00:00 As I previously described, I'm going to use shared preferences to store my notes
00:05 data on the android device. The shared preferences architecture
00:10 supports storage of key value pairs. And using the feed Java classes, it will
00:15 be possible to sort that data when needed. I'm working in a version of the project
00:20 called shared preferences, and I've opened the class notes data source.
00:26 This data source class will hide all the details of the implementation of my shared
00:30 preferences. So if I need to make changes to how the
00:34 data's being stored in the future, all of the changes will be confined to this
00:37 class. I'll double-click the Tab of the editor to
00:41 go to full screen. And then, place the cursor after the class
00:45 declaration to create an instances of a shared preferences storage area.
00:51 All you have to do is to create an object, calling a method called get shared
00:55 preferences. Each instance of this shared preferences
00:59 data storage will be associated with a simple string that identifies it, and
01:04 makes it sharable for the entire application.
01:08 So, I'm going to define a private, static, final string.
01:13 Essentially a constant. It looks like this.
01:16 I'll name it PREFKEY. The naming convention for constants in
01:22 Java is that they're spelled with all uppercase.
01:25 And I'll name this preference simply, notes.
01:28 Then, I'll declare an instance of a class called SharedPreferences.
01:33 I'll once again make it private. I'll type in the name of the class,
01:37 SharedPreferences. Then I'll press Ctrl+Space and select the
01:41 class from the Android.content package and that adds an import statement for the
01:46 class. And I'll name this object notePrefs.
01:53 Now, I have to instantiate that object I'm going to instantiate it as the data source
01:57 class itself is instantiated. So to make that happen, I'll create a
02:02 public constructor method. I'll add the keyword public.
02:07 And then, the name of the class that I'm working right now, NotesDataSource.
02:13 I type the name of the class and press Ctrl+Space for autocomplete.
02:18 As the data source class is instantiated, I'm going to ask for the application to
02:22 pass in something called the context. The context is the superclass of an
02:28 activity, and it's how we'll connect this Java class to the higher-level
02:33 application. I'm going to set up this constructor
02:39 method to receive the context object. I'll type in the name of the class
02:43 Context. Press Ctrl+Space and select the class,
02:47 that make sure I have an import statement for it, and then I'll name the argument
02:51 context in all lower case. Within the method, I'll instantiate note
02:59 prefs using this code notePrefs equals context.getSharedPreferences.
03:07 You have to pass in two arguments to the get shared preferences method.
03:11 The first is the name of the preferences collection and I identified that using my
03:17 constant pref key. The second argument is something called
03:22 the mode. And for all shared preferences objects its
03:26 reccomended that you set a mode of context.mode_private.
03:32 That's a constant that's a member of the context class.
03:35 So now as the data source object is instantiated the shared preferences object
03:39 will be instantiated as well. And if that preferences object doesn't yet
03:45 exist, it will be automatically created for us.
03:48 Now, I've made a change to how this data source class works.
03:52 Previously, I didn't have an explicit constructor method, and Java added a
03:56 no-arguments constructor method for me. But now that I have an explicit
04:01 constructor, whenever I instantiate the class, I must pass in a context.
04:07 So, I'll save my changes. Then, I'll restore the size of the editor.
04:12 I'll go down to my problems view at the bottom of the screen.
04:16 And I'll see I have a new error that says the constructor notes data source is
04:19 undefined. And that's because I have an existing call
04:23 to construct the object here in mainactivity.java.
04:28 I have to change the way I'm instantiating the data source object, so I'll place the
04:33 cursor inside the data source constructor method call and pass in this, meaning the
04:38 current instance of the activity. I'll save my changes and that error goes
04:44 away. And now this activity and the data source
04:48 are connected. Now, I need to add code to create new
04:52 notes. As the DataSource class is instantiated, I
04:56 now have a SharedPreferences object that I can use to create and update Note objects.
05:03 So, I'll go back to the DataSource class, and now I'll fill in code in the update
05:07 method. I'll place the cursor inside the existing
05:11 update method, and here's the code. First, create an instance of a class
05:16 called SharedPreferences.Editor. I'll type in shared PRE and press
05:22 Ctrl+Space. I'll select the shared preferences class.
05:27 Then, I'll put in a dot and choose the editor class.
05:31 This is a field of the shared preferences class.
05:34 And I'll name this new object editor. And I'll instantiate it using this code
05:41 noteprefs.edit. That means give me an editor object that
05:46 knows how to modify data in this particular shared preferences object.
05:51 Now, I'll take the note item object that's been passed into this update method.
05:57 And I'll use its key and text value, and I'll put the value into the shared
06:01 prefrences. That code will look like this,
06:06 editor.putString. Notice that there are number of different
06:10 put methods, including puts for booleans, floats, ints, longs, and strings.
06:16 I'm using this one. And I'm going to pass in the key of the
06:20 current note and the text value of the current note which I'll get from their
06:23 getter methods. That code will look like this note.getkey
06:28 for the first argument and note.gettext for the second argument.
06:33 Finally, after putting the value into the shared preferences object, you must commit
06:38 the changes. And that code looks like this,
06:43 editor.commit. So, now whenever the update method is
06:48 called and a note object is passed in, that notes key and value will be saved
06:52 automatically. If it didn't exist yet it'll be created
06:57 and if it already exists it'll be overwritten.
07:02 Now, I'll add code for the remove method. Much of it will be the same as for the
07:06 update method, so I'll select and copy those first three lines of code and I'll
07:09 paste them into the remove method. For the remove method, instead of calling
07:16 putString, we'll call a method of the Editor object called remove.
07:21 So, I'll get rid of that line of code and I'll replace it with editor.remove, and
07:25 I'll pass in note.getKey. It's a good idea to wrap this code inside
07:30 some conditional logic so that you're only removing preference objects that already
07:35 exist. So, I'm going to place the cursor at the
07:40 top of this code and I'll type in the keyword if.
07:44 I'll press Ctrl+Space and select If statement.
07:49 That adds a code template for a classic Java conditional block.
07:54 I'll set the condition as follows. If noteprefs.contains and I'll pass in
08:01 note.getkey. Then I'll take these three lines of code
08:05 that are removing the object and move them to within the conditional block.
08:10 And now that code will only be executed if in fact that particular note already
08:15 exists and remember its identified by the key.
08:19 Which is the date, time stamp, of when the note was created.
08:23 So, now I have code that can update and remove notes, and I'll go back to my main
08:27 activity and make some changes to fully test this.
08:32 In the, on create method, I already have code, that's creating my instance of the
08:37 data source and the code that's calling the find all method.
08:43 I'll move the cursor after the call to notes dot get.
08:46 And now I'll put the data into the shared resources object using
08:50 datasource.updatenote. And now each time I run the application,
08:54 I'll be adding this note object and saving it persistently.
09:01 I'm not retrieving the data yet I'll show you how to do that in the next video.
09:05 But my goal here is simply to make sure that I can run the code without the
09:09 application crashing or throwing any significant errors.
09:14 So, I'll save all of my changes. And I'll run the application by clicking
09:19 the run button and selecting android application.
09:22 So, if the application opens correctly without crashing, I know I'm executing
09:26 code that's working in the background. But I haven't proved it yet.
09:31 To do that, I need to retrieve this data for persistent storage and see if it's
09:36 still around even after shutting down and restarting my emulator or device.
09:43
Collapse this transcript
Retrieving data from shared preferences
00:00 So far, I've added code to my data source class, that identifies where the data will
00:04 go, a shared preferences object and can update and remove items from shared
00:08 preferences. Now, I'll add code to retrieve all of the
00:13 notes, from my shared preferences object and return them from the data source
00:16 class. I'm working in a version of the project
00:20 called, retrieving data. And I've opened up the notes data source
00:25 class. And I'm going to modify the find all
00:27 method. The first step is to retrieve data from
00:31 the shared preferences object. And we'll do this using a method called
00:35 get all. It returns an object called a map.
00:39 A map is an unordered data collection, where each item in the collection has a
00:44 key and a value. I'll type the word map and press control
00:50 space and select the map interface from Java.util.
00:54 Just as with the list, I'm being asked to identify the data types of the items in
00:58 the map. And now there are two values being asked
01:03 for. The first is going to be a string.
01:06 And what I'm saying is that each item is going to have a string based key.
01:12 The second data type is the data type of the value, and I'm going to put in a
01:16 question mark for this, and that's because the get all method returns a map where it
01:20 knows it's a string, but it doesn't know whether the value is a string, an integer,
01:24 a long, and so on. I'm matching up how the data will be
01:31 returned from the shared preferences object, and how it's going to be received
01:35 and processed. I'll name this new object notes map.
01:40 And I'll get its value by calling notePrefs.getall and notice the signature
01:44 of the return object here in the list. It matches the data type that I used to
01:51 declare the notes map object. I'll double click to Select the method and
01:55 Finish the statement. Now I have retrieved the data.
02:00 But the nature of a map is that it's unordered.
02:03 That is, it doesn't guarantee that the data will be in any particular order.
02:07 So my next step will be to sort the data by the keys with oldest notes first and
02:12 the newest notes last. To do that, I'll need to get a list of all
02:18 the keys of all the notes in the shared preferences object, and I'm going to them
02:23 into an object called assorted set. It looks like this.
02:28 I'll type SortedSet and press control space, and that add the required import
02:33 statement and auto completes the code. Than within the sorted set, I'll say this
02:40 set contains strings. And I'll name it Keys.
02:44 And I'll get it's value by instanchiating a class called Tree Set.
02:50 Which once again, will contain items of strings.
02:53 And within the constructor method for the tree set, I'll pass in something called
02:59 the Key Set method of the map. Here's how all this code works.
03:03 The key set returns a listing of all the keys for all the notes in the shared
03:08 preferences, but in any particular order. The tree set automatically sorts that data
03:16 and returns it in a sorted set. So by the time I had my sorted set called
03:21 keys. It's already been sorted.
03:25 And the default order is the order I want, from oldest to newest based on the
03:29 alphanumeric sort of the date time values. Now I'm going to loop through those keys
03:36 and use the keys to get the items from the preferences one at a time and add them to
03:41 a list object. I already have the list object here, it's
03:47 called note list and I'm going to add a 4 loop.
03:51 I'll type 4 and press control, space and then I'll choose the 4 H code template.
03:58 When I add the 4H code template, eclipse assumes that I'm looping through instances
04:03 of note item, but that's not right. I want to loop through instances of
04:08 string. So I'll change the dated type of the item
04:12 I'm looping on to string and the name to key.
04:15 And then the collection I'm moving through to keys.
04:21 And here's what I have so far, I'm saying loop through the list of key values and
04:25 deal with the keys one at a time. Now, for each key, I'll create a note
04:32 object. I'll set the data type as note item, and
04:35 name it note. And I'll instantiate it with equals new.
04:40 And I'll call the default constructor method for the note item class.
04:44 Then I'll call Note.SetKey, and I'll pass in the Key value.
04:50 And that's the value that I'm currently looping on.
04:53 I'll make sure the names of the two values match.
04:56 So now my Note object has the key, and now it needs its value.
05:01 I'll call Note.SetText, and I'll pass in the following.
05:06 NotesMap.Get and I'll pass in the key. Now when I save my changes to that, I'll
05:13 get an error over here and I'll use the second available quick fix to cast the
05:17 return value to a string because I know my preferences are strings because that's
05:22 what I put into them. So now at the end of this code I've
05:28 created a note object. And it contains the key I'm looping on,
05:33 and the associated string value. And I'll take that note object, and add it
05:38 to my note list. Using notelist.add, and then I'll pass in
05:43 the note object. And finally, I'll return the note list
05:47 object. I'm going to delete these two lines of
05:50 code that I was earlier using for testing. And that's the completed code for the find
05:55 all method. Now when find all is called, it'll
05:58 retrieve the preferences from the shared preferences object.
06:03 It'll sort them using the sorted set and tree set classes.
06:08 It'll loop through the keys and add the associated notes to the list object and
06:12 finally at the end, return the list. So now let's go back to the main activity
06:19 class and review our start up code. In the main activity class We're creating
06:25 an instance of the data source and we're calling the find all method.
06:30 And because we just made those code changes, we'll now be retrieving the data
06:34 that's stored persistently in the shared preferences object.
06:39 Right now, we're simply getting the data. And we're just getting the first icon and
06:43 we're logging it so that we can debug. And see that we're getting correct data.
06:48 But I'm going to add a little bit more testing code.
06:52 After I retrieve that testing note, which is now coming from persistent storage.
06:56 I'll call note.setText. And I'll pass in a static string of
07:00 updated. So I set the text of the object.
07:04 And then I pass it into the update method. And that updated text value is saved to
07:08 persistent storage. Then I'm going to retrieve the data again.
07:13 I once again set the value of notes by calling data source dot find all.
07:19 Notice that I don't have to redeclare the note's object.
07:23 It was already declared above. Then, once again I'll get the note object
07:27 by calling the note's objects get method. And once again, I don't have to redeclare
07:34 the data type, so I'll remove that from the copied code.
07:38 And then I'll log the result, but this time, I'll log both the key and the value.
07:44 After the call to getKey, I'll append a colon and a space, and then I'll append
07:51 note.getText. I'll save my changes, and I'm ready for a
07:55 test. I'll run the application.
07:59 If you see the dialogue asking you how you want to run the application, select
08:03 Android application as before. Then when the emulator comes to the
08:07 screen, wait a moment for the application to settle.
08:12 Go back to Eclipse. And I'm going to restore the editor.
08:15 Depending on your Eclipse configuration You might see the log cap tab appear over
08:20 on the right, or down at the bottom. I'll double-click it to Expand it.
08:27 Then just as I did before, I'll filter, by adding in tag colon notes.
08:32 And there's the result. The updated note has been retrieved from
08:36 persistent storage And shows the value updated.
08:40 So if you have that much code working, you've correctly created a complete
08:45 interface for adding, updating, and removing data from persistent storage
08:49 using the shared preferences API. And we're reading to go on to the next
08:55 major step of building our note taking app, creating the user interface.
09:00 And we'll cover that in the next chapter.
09:03
Collapse this transcript
5. Creating the User Interface
Creating screen designs with layouts and activities
00:00 As you get ready to build a user interface for an Android app, it's important to know
00:05 some basic concepts. Each Android application has at least one
00:09 screen. And depending on its complexity, it can
00:12 have as many screens as are needed. Each screen needs two elements.
00:18 First, an activity, which is a Java class, and then a definition of the screen
00:24 layout. A screen layout could be very simple, and
00:28 be just a container into which you add your own components at runtime, or it
00:32 could define everything that the user sees.
00:36 To create a screen layout, you'll create an XML file.
00:40 Each app can have as many layout files as are needed.
00:45 And a single screen can either be built from a single layout file, from multiple
00:49 layout files, sometimes known as fragments.
00:52 Or can choose between layout files at runtime.
00:56 All layout files have .xml extensions. And are placed in a layout folder, which
01:02 is under a folder called res for resources.
01:06 You can create your layout files using pure XML, or you can use the design tools
01:11 that are included in the Android Developer Tools or ADT.
01:16 When you create a layout file, it becomes something called an app resource.
01:21 Each files in the res or resources folder, is automatically given an ID in an auto
01:27 generated Java class named R. You'll find it in the package explorer
01:33 under a folder named gen, or gen for generated.
01:37 The ID that's assigned to your resource is defined by the R class, then the name of
01:42 the folder, and then the name of the file without the file extension.
01:49 So, for example, let's say you created a layout file called activitymain.xml and
01:53 you placed it in the layout folder, where it should be.
01:58 That would generate an ID that you can use to reference the activity at runtime in
02:02 your Java code. And it would be R, the name of the auto
02:07 generated class, .layout, matching the name of the folder, .activity_main.
02:14 Notice that the equivalent ID does not include the file extension.
02:18 And that's true for XML files, for PNG files or graphics, and many other kinds of
02:23 resource files. So, you use the layout file to describe
02:28 what your screen looks like, and an activity to describe how it behaves.
02:34 An activity is a Java class, and each activity manages a single screen of your
02:39 application. As a screen comes up, a method called
02:44 onCreat is automatically called. It's up to you to write the Java code that
02:50 loads the layout file that's built for that activity.
02:54 Here's an example. I have a main activity class that extends
02:59 the activity class. The activity class is a part of the
03:05 Android SDK. Then, I create my own onCreate method, and
03:09 it's an override. Which means that it's overriding the
03:13 version of onCreate that's a part of activity, the super class.
03:17 Within the on create method, I call a method called, set content view, and I
03:22 refer to my activity layout file. So, now I have defined how the activity
03:28 and the layout are matched together, and it's all done in pure Java code.
03:35 So, once you understand the difference between an activity and a layout.
03:39 That is, that an activity is a java class, and the layout is an XML file, and that
03:43 they're put together at runtime. You're on your way to creating the user
03:47 interface for Android apps. And I'll show you how to create the
03:51 activities and layouts for this application in the following videos of
03:55 this chapter.
03:56
Collapse this transcript
Displaying lists of data
00:00 In a previous chapter, I described how to create a data source class, and the class
00:04 to model the data that you'll be using in your application.
00:08 Now its' time to display the data using something called a list activity.
00:12 I'm working in a version of the project called List Screen, which has all of the
00:16 previous code, and now I'm going to transform the main activity.
00:21 That is the first screen that's shown when the app starts into the list activity to
00:25 show a list of notes. I'll start in the main activity class.
00:30 When you create a new activity by default it extends a class called activity and to
00:35 show a list of data. One of the easiest ways is to instead
00:39 extend a class called List Activity. So, I'll delete the Activity class from
00:45 the Extends class, and instead I'll set it to List Activity.
00:49 I'll type the beginning of the class name and press Ctrl + Space to auto complete
00:53 it. Now, I have to follow the rules of the
00:56 list activity class. One of the most important rules is that
01:00 the layout for a list activity must contain something called a list view.
01:06 So I'll go to the layout. ActivityMain.xml and I'm going to delete
01:10 the text view object, that was placed on this layout, when I created it.
01:16 Then, I'll go to the composite category and I'll drag in a list view object.
01:22 Don't worry too much, about where it is placed initially.
01:24 Just drop it into place, then click and drag and move it as far up to the top left
01:29 as you can, then drop it again. Now go into the XML view.
01:36 Remove the four padding attributes from the relative layout tab.
01:41 That will cause the list view to expand, to fill the entire screen.
01:45 Then, change the id. The list activity class has a required ID
01:50 for the list view control. That's how it finds it at run time.
01:55 And the required ID looks like this. Start with the @ character.
02:00 Then android in all lower case, then a colon, ID, then a forward slash and list.
02:09 Make sure that it's all lower case and that there aren't any spaces.
02:12 And that's all we have to do in the layout.
02:15 Now, let's go back to the main activity class.
02:18 I'm going to need to add a bit of code to update the display.
02:22 To retrieve data, and then use something called an array adaptor class.
02:27 The array adaptor class will be used to wrap around the data, and feed that data
02:31 to the list display. I'm going to be doing this pretty
02:36 frequently once the application is finished.
02:39 So I'm going to create a special method for this purpose.
02:43 I'll place the cursor in the on create method, just after the code that
02:46 instansiates the data source object. And I'll call a method that doesn't exist
02:51 yet called, refresh display. Once I finish typing in that line, I get a
02:56 quick fix indicator on the left. It says the method isn't defined.
03:01 I'll click it, and I'll select the Quick Fix to create the method, refresh display.
03:06 Now before I implement that method, I'm going to change some of this code.
03:12 First, I'm going to take this code that's declaring the list of notes and move just
03:16 the declaration to the top of the class. I'll select just the declaration and the
03:23 variable name and cut it to the clip board.
03:25 Then I'll move up to the top of the class right after the class declaration and
03:29 after the declaration of the data source and I'll paste it in.
03:34 And I'm going to use a variable named this time of notes list.
03:40 I'm not going to instantiate this object yet, I'm just declaring it.
03:44 Now, I'll go back to the On Create method, and I'm going to get rid of all this other
03:49 code. This was being used for testing and it
03:52 will no longer be needed. Now I'm ready to implement refresh
03:56 display. When the refresh display method is called,
03:59 I'll retrieve all the data from the persistent data store.
04:04 So I'll use this code. Notes list equals data source dot find
04:10 all. Remember the find all method was created
04:13 in a previous chapter. Now I'm going to create an instance of the
04:18 Arrayadapter class. This is a core class of the Android SDK.
04:24 I'll type in the beginning of the class name, press Ctrl + Space, and select the
04:28 class from the list. The Arrayadapter class has generic
04:33 notation. It wants to know what kind of data is
04:36 being stored. And I'll tell it that it will contain
04:40 instances of the note item class. And then I'll name the object adapter.
04:47 Then I'll instantiate it using one of the array adapter classes constructor methods.
04:53 I'll start with new. I'm going to need a little bit more width.
04:56 So I'll expand to full screen. Then I'll type in the beginning of the
04:59 class name again, and I'll just select the first constructor method, signature.
05:05 I'm going to be using a different signature, but this is good for now.
05:08 When I construct the array adapter. It first wants to know the context.
05:14 And I'll pass in this for the current instance of the current activity.
05:20 Next, I'm going to tell it how it should lay our each list item.
05:24 And I'm going to use a built in layout that's included with the Android SDK.
05:30 The code looks like this. Android.R make sure the R is upper case,
05:37 then layout, then simple list item 1. This is an identifier, pointing to a
05:46 simple list item that displays a single text view.
05:51 Then I'll pass in my notes list. And this is how I'll be telling the array
05:55 adapter, what data it should be displaying.
05:58 So now I have an array adapter that's wrapped around my data and that's
06:02 indicating how the data should be displayed.
06:06 And I'm ready to attach the adapter to the current activity.
06:10 I'll call a method called set, list, adapter.
06:14 And I'll pass him the adapter variable and finish the code.
06:19 So now whenever refresh display is called, I'll get the data using the find all
06:23 method, I'll wrap the adapter around it, and I'll attach the adapter to the current
06:27 list activity. I'm ready for a test.
06:32 So I'll click the Run button in the toolbar, and I'll come back to my
06:35 emulator. And when the app opens, it displays
06:39 something in the list. But this is the hash value of the object
06:43 that was returned from the data store. Not it's values.
06:46 And that's because my note item classes tostring method is using the default
06:52 tostring method. That's a part of all Java classes.In order
06:57 to display the value that I want, that is the text value.
07:02 I need to override that two string method. So I'll go back to Eclipse.
07:07 And I'll go to my note item class in the data package.
07:11 I'll go down to the bottom of the code. I'll place the cursor before the closing
07:16 brace. And I'll type in the name of the method I
07:19 want to override to string. I'll press Ctrl + Space, and select the
07:24 method. And that adds in the required method
07:27 signature. I'll get rid of the to do comment.
07:31 And then I'll change the return statement to returnthis.gettext.
07:37 I'll save and run again. And now I'm seeing the correct data
07:40 appear. The text value of the one and only data
07:43 object that I added to the data store. So now my list view is working.
07:50 I'm retrieving data from the persistent data store, the shared preferences.
07:54 I'm wrapping the data in an adaptor and I'm connecting the adapter to the list
07:59 activity. As I add data to the data store, the list
08:03 will continually expand to display all of the notes.
08:07 We're not done with the list activity yet. I'm going to customize its appearance
08:11 quite a bit. Then I'll show you how to do that in
08:14 another video.
08:15
Collapse this transcript
Customizing the appearance of list items
00:00 My note taking apps list activity is correct displaying data from persistent
00:04 data storage. But I'd like to customize the appearance
00:08 of each list item. I'd like to add a visual icon to the right
00:11 of the text that gives the user a visual indicator that they're suppose to touch
00:16 the item to edit it. First, I need to create a graphical icon.
00:21 And I need to create a number of different sizes for various pixel densities.
00:26 So, I'll go back to the Android Asset Studio.
00:29 The same tool that I used to create my launcher icons.
00:32 I'll go to the generic icons screen. You can create generic icons from your own
00:37 image, from clip art, or from text. I'll choose clip art.
00:43 Then I'll scroll down and I'll choose an Edit icon, a picture of a pencil.
00:49 Some designers prefer a right pointing carrot for this kind of icon to indicate
00:53 that you'll be going from screen to screen, but I'm being very specific in my
00:56 design. I'm saying when you touch this item,
01:01 you'll be editing it. After I select the graphic, I'll scroll
01:05 down a bit, and I'll change the size of the graphic.
01:09 The default is 24 dip and I'm going to reduce it to 20 dip to better fit within a
01:14 list item. Then I'll set the name of the icon, the
01:19 default is ic_example. And I'll change it toi ic_listitem_edit.
01:27 You can name this anything you like as long as you keep it all lower case, and
01:30 don't include any spaces. I'll scroll down and look at the preview,
01:35 then I'll download the zip file that was created for me.
01:39 Once the zip file has been downloaded, I'll go to Finder or Windows Explorer for
01:44 Windows, and then I'll extract the contents of the zip file.
01:50 The zip file has a folder called res for resources, and three folders for three
01:55 different sizes of graphics. I'll select all and copy, go back to
02:01 Eclipse, go to the res folder of my application, and paste those folders in.
02:09 When prompted, I'll say yes. I want to override.
02:12 And now my graphics for editing are a part of the application.
02:17 Notice that I'm working in a project called List items, and this is a
02:21 continuation from a previous exercise. So, now I have my graphic, and I need a
02:27 way to display the graphic next to the text value of each note.
02:32 To do this, I'm going to create a custom layout.
02:35 Layouts always go in the custom folder under res.
02:39 So, I'll go to that folder, I'll right click on it.
02:44 And I'll choose new > Android XML file. In this dialog box, I'll make sure the
02:50 resource type is set to layout. That's the default, and I'll set the file
02:55 name to list_item_layout.xml. Just as with any resource, the ID has to
03:02 be all lower case with no spaces. I'll click Finish, and that creates the
03:08 layout. The layout first opens in WYSIWYG mode.
03:14 I'll look at it in XML mode, and show that it starts as a linear layout.
03:18 And I'm going to make a whole bunch of changes here.
03:21 The default layout that I'm already using for my list items consists of a single
03:25 text view object. I'm just going to replace that Text View,
03:30 and I'm not going to wrap any other objects around it.
03:34 So, I'll change the route element of this XML file from linear layout to Text view.
03:38 Next, I'll change the width from match parent to fill parent.
03:45 And that's saying that this text view object should expand to fill all available
03:49 horizontal space. Then I'll change the layout height from
03:53 match_parent to wrap_content, so that the height matches whatever font size I assign
03:58 to the text field. I don't need the orientation attribute
04:03 that was for the linear layout and doesn't apply to the Text view.
04:08 But I do need a number of other settings. First, I'll set the gravity.
04:15 The gravity determines where the text falls vertically.
04:19 And I'll set its value to center_vertical, and that will cause the text to have the
04:24 same amount of space above and below. Next, I'll set padding to 5dp.
04:30 That means add a little bit of space around the text, so that the text values
04:34 aren't crammed right next to each other. Next, I'll set the display to single line.
04:43 Setting single line equals true. And that means that even if the text value
04:47 has more than one line, only show one of the lines.
04:52 And finally, I'll set the text size to 20 sp.
04:57 You can play with this size and get the size that you want, but this size feels
05:01 readable on a variety of devices to me. Now, I'm going to add a couple of other
05:06 special features. If a note's text value is too long to fit
05:11 on a single line, by default it just truncates.
05:15 But I'd like to show ellipses, three dots at the end of the line.
05:20 To do that, add an attribute called ellipsize, and set it's value to n.
05:25 And then if the text is too long to fit in the available space, you'll get those
05:30 three dots. And finally, I'll add my graphic.
05:35 Notice that I'm only doing this with the single control or a single view.
05:40 I don't have a layout combining a text view and a graphic.
05:44 Instead, I'll use an attribute of the text view Called drawable right.
05:50 You can add a drawable component to the left, right, start, end, top, or bottom.
05:57 By saying you want a drawbable right, the icon will always appear on the far right
06:01 side of the Text view no matter how long the text is.
06:06 And I'll set that to the ID of the icon that I created, using @drawable, that's
06:10 the name of the resource folder in which it's stored, and then the ID of the icon.
06:17 IC list item edit, and that's my new custom layout for each item in my list.
06:25 I'll save those changes, and I'll go back to the main activity.
06:30 In the main activity, I'm currently assigning the built in layout, simple list
06:35 item one. And I'm going to replace that with my own
06:39 custom layout that I just created. And that will be r.layout.listitemlayout.
06:48 Each time you create a new layout, an ID for it is created in the automatically
06:52 generated R class. The next value is the name of the folder
06:57 layout, and the next value is the ID of the layout file without the .xml
07:01 extension. I'll save and test my code.
07:06 And now, the list item is displayed with its text value, and with the graphical
07:11 icon on the right side. As I add more items to the list, I'll see
07:16 one instance of the graphical icon for each list item.
07:21 And the user we'll know by seeing the icon, that they can touch that item and
07:26 edit its value.
07:28
Collapse this transcript
Creating the editor activity and layout
00:00 My note taking app will require two screens.
00:03 The lists screen, which I've already created, and an editor or detail screen.
00:08 When the user touches one of the notes in the list, they'll be taken to the editor
00:12 screen. The text value of the selected note will
00:15 be displayed, the user will be allowed to edit it and when they return to the list
00:19 screen, their changes will be saved automatically.
00:23 To create the second screen, you'll need to create two files.
00:27 A layout and a Java class. I'll start with the layout.
00:32 I'm working on a version of the project called editor activity that continues from
00:35 the previous exercise. I'll go to the layout folder within the
00:39 resources section. I'll right-click on that folder, and
00:45 select New > Android XML File. The Resource Type is Layout.
00:51 And I'll set the file name to activity_note_editor.xml.
00:58 The default route element for this new layout is a linear layout.
01:01 I'm instead going to choose Relative layout.
01:04 This will allow me to more easily control the positioning of the contained object.
01:10 Which will simply be a text editor object. I'll click finish and that creates the XML
01:16 file. I'll then double click to open the XML
01:19 file if it didn't open automatically, and that opens the file.
01:24 If your file opened to the graphical interface as mine did, click on the XML
01:28 tab at the bottom And you'll see that the starting layout is simply a root element
01:33 of a relative layout. Now go back to the graphical layout and
01:38 we'll add in a text field. Click on the text field section in the
01:42 palette and then click and drag a plain text text field and then drop it into the
01:47 activity. Don't worry about where you're dropping it
01:52 initially. Or changes positioning and size when we
01:55 get back to the raw XML view. Now go back to the raw XML view, and we'll
02:00 make some changes. First change the ID.
02:04 The default is edit text one. Change it to note text.
02:10 That's the ID we'll use in our Java code to address this object.
02:14 Next, change both the width and height from wrap content to fill_parent.
02:21 That will cause the edit text object to fill all available space.
02:26 Then remove both align attributes that were generated for you.
02:31 You don't need those. And also, remove the margins.
02:34 Now, look at the object in graphical layout.
02:36 And you'll see that the object has expanded to fill all available space.
02:41 Now we'll set some attributes that are needed.
02:46 Place the cursor inside the beginning tag and we'll add these attributes, set single
02:51 line to false, that will make sure that the user can add multiple lines to the
02:56 note, including pressing a return button to add a line feed.
03:02 Next, set the gravity attribute to top. This will cause the text to start at the
03:07 top of the Edit Text control, regardless of how long it is.
03:11 Next, set the inputType attribute to textMultiLine, and that's it.
03:18 Your layout is complete, and you can now use this layout in an activity.
03:24 The next step is to create a Java class for the new activity.
03:27 Go to the Source folder in your package explorer and go to the default package,
03:32 right click and select New Class. Set the name of the class to note editor
03:40 activity and then set the super class to activity.
03:47 Make sure you're using the activity class in the Android.app package.
03:52 Click finish, and your new class has been created.
03:56 Now, before we fill in any of this code. We need to register this class with the
04:01 application manifest. Go to androidmanifest.xml.
04:06 You'll find it at the bottom of the package explorer.
04:08 Double-click to open it. And then, click on the Android
04:13 manifest.xml tab at the bottom of the editor.
04:16 I’ll expand to full screen. And then we just need to add a new
04:21 activity element inside the application that ensures that our new activity class
04:26 is loaded with the application. Place the cursor after the end tag of the
04:32 existing activity. And add a new line.
04:36 Add a new activity tag, set its name attribute to dot, and then the name of
04:43 your new job of class. NoteEditorActivity.
04:51 Then, complete the tag with empty tag syntax.
04:53 You don't need any other attributes, also, because I put a dot before the name of the
04:58 class, I didn't need to include the entire package name.
05:03 You can if you want to, but it's not required as it is with the main activity.
05:08 Save your changes to the manifest and now go back to the new java class.
05:13 Note editor activity. As this activity comes to the screen it
05:17 has to load its layout so we'll need to create an override of the on create
05:21 method. That's the method that's called
05:25 automatically, as the activity appears. Place the cursor inside the class
05:30 declaration, type oncreate, press CTRL Space and choose the first item in the
05:35 list. And that generates the onCreate method
05:40 signature. Remove the to do comment, place the cursor
05:44 after the call to super.onCreate and then call setContentView.
05:50 And passing the id of your new layout. R.layout,activity_note_editor.
05:55 And now the two files are bound together. The Java class, the activity is registered
06:01 in the application manifest and as the activity is opened.
06:08 It loads its own way out. So far this activity isn't completely
06:12 integrated into the application. There's no way to go to it yet.
06:16 But we'll handle that in the next video, when I describe how the navigational
06:21 pattern of this application is going to work.
06:25
Collapse this transcript
Creating an action bar command item
00:00 We've created our screen definitions, and now it's time to add a user interface for
00:04 navigation. The first step is to add an icon that lets
00:08 the user indicate that they want to create a new note.
00:13 On newer devices, I'll do this with the Action bar.
00:16 The Action bar was introduced in Honeycomb, Android 3.
00:21 And it's a way of adding command icons to the top of the application next to the
00:25 name of the application and the launcher icon.
00:29 I'm working in a version of the application called Action bar.
00:34 And I'll start by creating a new graphical icon to use in the Action bar.
00:39 I'll go back to the Android Asset Studio, and this time, I'll click on Action bar
00:44 and Tab Icons. I'm going to once again use clipart to
00:48 create my icons. You could create your own images if you
00:52 prefer. I'll click the clipart section, and I'll
00:55 scroll down till I find the plus icon. This is clearly an indicator that I want
01:01 to create something new. I'll select the item, and I'll scroll down
01:06 a little bit further. I'll set the name of the icon to
01:11 create_note. The help text on the left indicates that
01:16 this string will be appended to ic_action_, then I'm going to set the
01:21 theme to holo dark. This will match the look of my
01:26 application's action bar because of the theme that I selected when I created the
01:30 app. Now, I'm ready to download the zip file.
01:35 I'll click and download. I'll go to the Finder window, or Windows
01:38 Explorer. I'm going to get rid of some of these
01:41 older files, I don't need them anymore. And then I'll extract the zip file that I
01:46 just created. As before, I'll have folders for the
01:51 different pixel densities. And the names of the files will match what
01:55 I requested in the Asset Studio. I'll come back to the Resources folder,
02:00 Select All and Copy, and then return to Eclipse.
02:05 I'll go to the resource folder and I'll paste into resources and overwrite all.
02:12 And that adds the graphics to my drawable folders.
02:17 Now, I'm ready to use those graphics in my action bar.
02:21 The next step is to modify a Menu file. Menu files are defined as XML files, and
02:28 they're also in resources. When you created the new application, it
02:33 was automatically populated with this default Main menu file.
02:37 And it has a single item with an ID of action_settings.
02:41 Our application isn't going to have any preferences or special settings.
02:46 So, I'm just going to reuse this item. When you create an item in a menu, it can
02:52 either show up in a menu or in the action bar, and that's determined by this
02:57 attribute, showAsAction. I'm going to change the value of
03:02 showAsAction to always. Then I will change the idea of this item
03:08 from action_settings to action_create. I'm also going to reset the title.
03:14 Right now, it's using a string resource that's in the strings.xml file.
03:20 I am going to jump to that file, I'll hold down the Cmd key on Mac or Ctrl on
03:25 Windows, and then click the item. And that jumps to the item in the
03:31 strings.xml file. This file is actually in the values folder
03:35 here. I'll change the name of this resource from
03:39 action settings to action_create, and change its value to create.
03:45 And then, while I'm in this file, I'll do a little bit of cleanup.
03:49 I'm not saying, hello plain old notes anymore.
03:53 So, I'll delete that string resource and save.
03:55 I'll come back to the Main menu, and now I see an error on the title because that
04:00 resource doesn't exist anymore. And I'll change it from action settings to
04:06 action_create. Now, let's go back to the icon.
04:10 Remember that I created the icon and added it to the resources.
04:15 So, I'll add an icon attribute, and I'll set it to the ID of my new icon
04:20 @drawable/ic_action_create_note. If there's room, I'd like to show both the
04:27 icon and the create text. To make that happen, I'll go back to
04:32 showAsAction and I'll add a pipe character, and then after that, withText.
04:38 And that means if you have space, show the text, but if you don't, just show the
04:42 icon. Now, that's pretty much all I need to do
04:46 to display the icon and that's because my main activity class already has the code
04:51 to load the menu. You'll find that in MainActivity.Java down
04:57 toward the bottom in the On Create Options menu method.
05:01 Here, it's inflating the main menu and adding it to this activity.
05:06 So, it's time for a test. I'll run the application, and when it
05:11 reloads in the emulator, the plus icon is displayed.
05:16 Right now it's not doing anything, but we'll add functionality to it later.
05:20 But I'm also going to test in a tablet. I'll go back to Eclipse, I'll click the
05:27 down arrow next to the Run button and choose Run Configurations.
05:33 When the Action Bar project opens, I'll click on Target, and then select Always
05:38 Prompt to Pick Device. I'll click Run, and then I'll launch a new
05:44 Android Virtual Device from my tablet device which is emulating a Nexus 7
05:50 running Jelly Bean. When the emulator for the tablet loads, it
05:57 shows the icon on the right, including both the plus icon and the text that I
06:02 requested. In this emulator, I had previously added
06:07 some data. And now, we're seeing how the list
06:10 activity will look when I populated it with more than a single note.
06:15 I'm still not able to go to the detail editor screen, but we'll see how to do
06:19 that in the next video. When I describe how to wire up the event
06:23 that occurs when the user touches the create icon in the Action bar.
06:28
Collapse this transcript
Creating a new note
00:00 In our application, I've created two screens and added an action bar item that
00:04 allows the user to say they want to create a new note.
00:08 Right now though, the Action Bar icon doesn't do anything.
00:12 Now I'm going to add functionality so that when the user touches the Action Bar add
00:16 icon, a new note object is created in memory.
00:20 And then the screen changes to the editor screen.
00:24 The user will then be able to touch the Back button on the device or a Back button
00:28 that's a part of the application to return to the list screen.
00:32 I'm working in a version of the application called create note that
00:36 continues from the last exercise and I'll start in the main activity class.
00:42 When the user selects an item in the Action Bar or in the Options menu, which
00:47 we're not using right now, it triggers a method called on options item selected.
00:53 I need to create an override of that method in my class so I'll move the cursor
00:58 to after the existing code and I'll start typing the name of the method,
01:02 onoptionsitem. Then I'll press Ctrl + Space and select
01:08 the method from the list that's presented. That creates the method signature.
01:14 I'll delete the to do comment, and then add co before the return statement.
01:20 When onoptionsitem selected is called in the menu item that was selected as an
01:26 object. The name of that argument is item.
01:29 So you could evaluate which item was selected by looking at a method called get
01:34 item ID. My menu only has one item but I'll make
01:38 absolutely sure that the right one was selected using an if statement.
01:43 I'll type if, and press Ctrl + Space and choose the if code template.
01:49 Then I'll set the condition as follows. Item.getItemId is equal to
01:54 R.id.action_create and that's the ID of the menu item that I created.
02:02 If that item was selected from the menu, I'll call another method called create
02:07 note. I'll type the name of the method, which
02:11 doesn't exist yet, then I'll press Cmd + 1 on Mac, or Ctrl + 1 on Windows, and select
02:16 a quick fix to create the method. I'll scroll down to the new method, I'll
02:22 delete the to do comment, and I'll implement this method.
02:27 First I need to create a new note object. I'm going to create it here in the main
02:32 activity, then pass it to the editor activity.
02:36 I'll declare a new note object, data type does note item and I'll get the object by
02:40 calling the get new method of the new note item class.
02:45 Now, I'm ready to create Navigation between the two screens.
02:49 To navigate from one screen to the next, I'll create an intent object.
02:54 I'll type in the name of the intent class and I'll choose it from the list to make
02:58 sure I have the right import and I'll name the object intent in all lower case.
03:04 I'll instantiate it using intent classes instructor new intent.
03:10 And I'll pass in the first argument as this, meaning the current activity or
03:14 context. And then I'll indicate which class I want
03:19 to use to create the new activity. And that will be NoteEditorActivity.class.
03:26 Notice that you don't pass in an instance of the activity, you're simply telling
03:30 Android which class to use. And then Android instantiate the class for
03:36 you. Next, I need to pass data to the new
03:39 activity. For that, I'll use a method called put
03:44 extra. It's possible to create a complex object
03:48 and pass the entire object. But it takes quite a bit more code than if
03:52 you're just passing a couple of simple values.
03:55 If you want to learn how to pass complex objects, take a look at my course, Android
03:59 SDK Local Data Storage. I described the process there.
04:04 But if you're only passing a couple of simple strings as we're going to do here,
04:08 it's easier just to call the put extra method a couple of times.
04:13 So I'm going to call Intent.putextra. Notice the put extra method has a number
04:19 of different signatures. They all require a string as the first
04:23 argument, but then you can send a different types of data as the second
04:27 argument. We're going to use this one.
04:32 Put extra for passing a string. The first argument identifies the value
04:38 that's being passed in and I'm going to give that a value of key.
04:42 Then, I'll pass in the note object's key, calling note.getkey.
04:50 Remember that the key is generated as a date, time stamp indicating to the second
04:54 when the note was created. Then I'll call intent.putextra again.
05:00 This time I'll pass in a first argument of text, and I'll pass in note.getText.
05:07 So now the intent object is an envelope. It contains all the information that's
05:12 needed to navigate to the new screen. The activity that's going to be used and
05:17 the values, the key and the text of the current note.
05:22 And I'm ready to start the activity. I'll call a method called start activity
05:26 for result. There are a couple of signatures for this
05:29 one. I'll choose the first one.
05:32 The first argument is the intent. And the second is something called a
05:36 request code. The request code is an integer value.
05:40 When you start the activity, you pass in the request code.
05:44 When the activity is finished, it passes back the request code.
05:48 And when the first activity receives the request code it can figure out which
05:52 screen it came from. The request code integer can be anything.
05:56 I'll pass in a value of 1001. Later on when I clean up this code, I'll
06:00 turn that into a constant but that's good for now.
06:05 So now my create note method is creating the note object It's creating the intent
06:10 indicating what screen I want to go to. It's passing in the data and it's starting
06:17 the activity. Now let's go to the editor activity.
06:20 I'll open NoteEditorActivity.Java. And I have some work to do here.
06:26 First, I'll declare a persistent note item object.
06:32 Within the task declaration, I'll create a private field data typed as note item, and
06:37 I'll call it note. In the on create method, which is called
06:42 automatically as the activity starts up, I'll once again get a reference to the
06:47 intent. I'll create a variable called intent, data
06:52 typed as intent, and I'll get its reference by calling this.getIntent.
06:57 This now gets referenced to the same intent object that was created by the
07:02 first activity. Next, I'll instantiate the note object
07:07 that I already declared. Note equals new note item.
07:11 Then I'll populate it with the values. This time by calling the intent
07:17 getStringExtra method. The code looks like this: note.setKey, and
07:22 I'll pass in intent.getStringExtra. And I'll pass in the key value that I used
07:29 in the main activity Key. Once again, when I clean up all this code,
07:34 I'll turn these strings into constants, to make sure I'm using the same values every
07:39 time. So I've retrieved the key and saved it in
07:44 my note object. I'll do the same thing for the text value,
07:48 with note.setText. And I'll again call intent.getStringExtra,
07:54 and I'll pass in text. So now I've reconstructed the note object
07:58 as the editor activity starts up. And I'm ready to display the note's text
08:04 value in the edit text control that's a part of this layout.
08:09 I'll create a reference to the edit text object.
08:13 I'll declare a new variable, data typed as edit text.
08:17 I'll be sure to include an import and I'll name it et and then I'll call findViewbyId
08:23 and I'll pass in r.id.noteText that's the edit text object id that I created in the
08:29 layout. When I finish the line of code I have an
08:35 error and that means that I need to add a quick fix and set the casting And set the
08:39 casting of the return value as an edit text object.
08:44 Next, I'll set the text property of the edit text object.
08:48 I'll call et.setText and I'll pass in note.getText.
08:53 And finally, because this code is going to be exactly the same, regardless of whether
08:58 I'm creating a new note or editing an existing note.
09:04 I'll place the cursor at the end of the existing text value.
09:09 With this code, et.set selection and then I'll pass in note.getText.length.
09:16 And that's all the code I need to receive the values that were sent in by the main
09:22 activity. Save them persistently in the private note
09:28 object and then display the value of the notes text so that the user can add, edit,
09:33 or remove it. I'm ready to test the application again.
09:37 I'll run the application in the emulator and when I click the Plus icon, I'm taken
09:42 to the editor's screen where I can start typing my notes value.
09:48 Saying this is a new note. Now for the moment, when I click the Back
09:52 button, nothing happens. I'm not actually creating the note yet.
09:57 That will come in a later exercise. But I've successfully linked the two
10:01 screens together, allowing the user to start at the list screen and then click
10:06 the Action Bar icon to navigate to the editor screen.
10:11
Collapse this transcript
Editing an existing note
00:00 At this point, the note-taking app has the ability to add a new note and view it in
00:04 the editor, and return to the list screen but not yet to save the note to persistent
00:08 storage. Before I get to that step, though, I'd
00:13 also like the user to be able to touch one of the existing notes and be able to open
00:17 up that note in the editor screen. And it turns out that that takes a very
00:22 small amount of additional code. I'm working now in a project called edit
00:26 note. Which continues from the last exercise.
00:29 And I'll start in the main activity class. The main activity class extends list
00:34 activity. And that class has a method called
00:38 onlistitemclick. This method is called automatically when
00:42 the user touches one of the items in the list.
00:45 When the method is called, you'll receive arguments that tell you which item was
00:49 selected and you'll be able to manipulate the application from there.
00:54 So, I'll go down to the bottom of the code, I'll go into Full Screen, and I'll
00:58 place the cursor after the last method, createNote.
01:04 And I'll create a new method called onlistitemclick because this is an
01:07 override. All I have to do is type the name of the
01:11 method, press Ctrl space and select a method from the list that appears and that
01:15 creates the overwrite signature. I'll remove both the to do comment and the
01:21 call to the super classes version of this method.
01:25 And I'll implement my own version. The first thing I need to do is get a
01:29 reference to the Note object that the user selected, and this is available through
01:34 the position argument, which is passed in as the third argument of the method.
01:40 I've already stored my data persistently in this class as a list called notesList.
01:46 So, I'll get a reference to the selected note item by using the notesList and it's
01:50 get method, and passing in the position argument.
01:55 That code will look like this. NoteItem note equals notesList.get.
02:02 And I'll pass in the position argument. So, now I have the note the user selected.
02:10 And the rest of the code is identical to how I pass data in createNote.
02:15 So, I'm going to select and copy that code, starting with creating the intent,
02:20 and I'll paste it into the onlistitemclick method after I've created the Note object.
02:27 And that's it, now when the user selects one of the objects by touching it, this
02:31 method will be called and the note will be opened in the editor screen.
02:37 I'll save my code and run the app in my Emulator.
02:41 I'll click with my mouse to simulate the touch event, and the note is opened in the
02:45 editor screen. Once I'm in the editor, I can add new
02:49 text, new lines and so on. But when I click the Back button, I come
02:53 back to the list screen and that's because I haven't added the code that will be
02:57 needed to save this data to persistent storage.
03:01 I'll take care of that task in the next video.
03:04
Collapse this transcript
Saving notes to persistent storage
00:00 The note taking app now has the ability to add a new note to the editor, allowing the
00:05 user to type in new information or to edit an existing note.
00:12 But in neither case is it saving changes to persistent storage.
00:16 And that's the feature that I'll add next. I'm working in a version of the project
00:20 called save note that continues from the last exercise.
00:25 The first step in saving data, is to pass data from the editor activity back to the
00:30 main activity. So, I'll go to the note editor activity
00:34 class I'll expand to full screen and I'm going to add a couple of features.
00:40 First of all, I'm going to add a new method that I'll call, save and finish.
00:46 When you go from one activity to another activity, returning to the previous
00:50 activity is called finishing. And there's a method named finish you can
00:55 use to make that happen. But before you call that method, if you
00:59 want to pass data back, you have take a few other steps.
01:03 I'll create a new private void method, that I'll call saveAndFinish.
01:07 The first step when the user touches the back button, is to get the text that
01:11 they've typed into the editor. To do that, I'll use this bit of code
01:16 that's getting a reference to the EditText object.
01:20 I'll copy and paste that into the new method.
01:23 Then, I'll declare a new variable data typed as a string that I'll call noteText.
01:28 And I'll get it's value, by calling et, that's the variable pointing to the
01:35 EditText object, .getText.toString. Be sure to use the to string method, if
01:42 you just reference he getText method, you won't get a valid string.
01:47 So, now I have the value that the user has entered or updated and I'm ready to
01:50 package it to send it back to the main activity.
01:55 For that purpose, I'll use an intent object.
01:58 I'll create a new intent variable and I'll instantiate it using the intent class's
02:03 constructor method. Then, I'll put the values in that I want
02:08 to pass back to the main activity. This code will be almost exactly the same
02:13 as when I passed data from the main activity to the editor activity.
02:19 So, I'll go to the main activity and copy these two lines of code that are calling
02:22 the intent object's putExtra method. I'll go back to the editor and paste that
02:28 code in. This time, I'm referring to the key of the
02:31 note object that I saved persistently when the editor opened and so I'm passing the
02:36 key back to the main activity. For the text though, I want to pass the
02:42 value that the user typed in. And that's the variable noteText.
02:48 So, now I have an intent wrapping the data to send back and I need to send a message
02:52 back to the main activity saying, everything's okay, save this data.
02:58 I'll call a method called setResult, and I'll pass in two values, a result code,
03:04 and an intent. For the result code, I'll use a constant
03:08 of the activity class called RESULT_OK. And for the intent, I'll pass in the
03:13 intent object that I've just created. And now, I'm ready to go back to the main
03:19 activity. And I'll call a method called finish.
03:23 The finish method simply means, I'm done. Go back to the activity that called this
03:29 one. Next, I need to provide a way of calling
03:32 this method. This method will be called in one of two
03:35 circumstances. Either, when the user presses the device's
03:39 back button or a back button that I'll place back into the application.
03:44 Let's start with the applications back button.
03:47 In applications hosted in Honeycomb or later, that is Android 3, the action bars
03:52 launcher icon can be easily transformed into a back button.
03:58 And that's the preferred way to create a back button in these latter versions of
04:01 the operating system. To do this, you just need to call a single
04:06 line of code. Go to the onCreate method, place the
04:10 cursor after the call to set content view and call this code
04:14 getActionBar.setDisplayHomeAsUpenabled and pass in a value of true.
04:23 When you call that method, the launcher icon is transformed into an options button
04:27 and that automatically generated options button will have an ID of home.
04:34 So, now to handle the event that happens when the user touches that button, we'll
04:39 use the method on options item selected. I'll go down to the bottom of the code,
04:45 and I'll add in a new method. Onoptionsitemselected.
04:51 This is an override so, I'll type in the first part of the method name, Ctrl space
04:56 and select it. When the method is called, the selected
05:00 menu item is passed in as an argument named item and I'll use conditional code
05:05 to check the item id. of that item.
05:09 Within an if statement, I'll use if item.getItemId and I'll compare its value
05:15 to this item id. Android.R.id.home.
05:22 If those two values match, I'll call my new method save and finish.
05:27 And then either way, I'll return a value of false, meaning I've handled this event,
05:32 don't do anything else. So, now let's test that much code to see
05:37 if the back button appears. I'll run the application in the emulator,
05:43 and when it comes to life, I will touch the item in the list and I'll see that the
05:47 launcher icon has transformed successfully into a back button.
05:52 Now I'll add one other way to call this function, and that's when the user touches
05:56 the device's back button. That triggers a method called
06:00 onBackPressed, and I'll override that. I'll type the beginning of the method name
06:05 and select it, and instead of the super class's version of the method, I'll call
06:10 my save and finish method. So, now regardless of whether the user
06:15 touches the launch icon or the device is back button, I'll be sending data back to
06:19 the main activity. Now, lets handle what happens when the
06:23 main activity comes back to life. From the main activity, I launched the
06:29 editor by calling the method startActivityForResult.
06:34 And I passed in this value 1001, that was the request code.
06:39 Now, I've used this value a couple of times and to ensure consistency, I'll turn
06:44 this into a constant. I'll select one of the versions of 1001,
06:49 then right click, and choose Refactor > Extract Constant.
06:55 And I'll set the name of the constant to editor activity request.
07:03 That creates the constant at the top of the code but also changes the version
07:06 here. I'll copy that and then I'll paste it in
07:10 here where I'm also using the same value. Now, when the editor activity returns to
07:16 the main activity, a method called onActivityResult will be triggered.
07:22 And as before, it's an override. I'll type the beginning of the method
07:26 name, press Ctrl+space and choose the method, and then I'll get rid of the
07:30 default implementation. When this method is called, it's a good
07:35 idea to make sure you're coming from the activity you expect, and that you get the
07:39 right result code. These values are passed into the method as
07:45 these arguments, requestCode and resultCode.
07:49 So, within the method I'll create an if statement and I'll set the condition to
07:52 the following. If the requestCode matches my constant,
07:57 EDITOR_ACTIVITY_REQUEST and the resultCode matches the constant, RESULT_OK.
08:04 Then, I'm ready to take that data and save it to persistent storage.
08:12 First, I'll collect the data and put it into a note object.
08:16 I'll create a new note item that I'll call note.
08:20 And I'll instantiate it with the note arguments constructor.
08:23 Then I'll set its data. I'll call note.setKey, and I'll pass in
08:29 the key that was passed back from the editor.
08:34 Using this argument, the data argument which is an instance of the intent class.
08:39 This is the same intent object that was passed back from the editor activity.
08:45 I'll get the key value by calling data.getStringExtra and I'll pass in key.
08:51 And then I'll do the same thing for the text value.
08:54 Calling the notes's setText method and passing in the data intent's
08:58 getStringExtra method. And passing in text.
09:08 Now, I'm ready to save the data to persistent storage.
09:11 And to do that, I'll use the update method of the data source class.
09:15 I created this method a while back, and all it does is to take a shared
09:19 preferences editor, use a put string method passing in the key and the text
09:23 value, and commit the change. I'll go back to the main activity, and
09:30 I'll use one more line of code, a call to my refreshDisplay method.
09:36 And that means now that I've made changes to my persistent storage, re-request the
09:40 data for persistent storage and update the display of the list.
09:44 And now, I'll test the application completely.
09:48 I'll run it in the emulator again and I'll create a new note.
09:53 I'll type in, get groceries. And then I'll click the launcher icon, the
09:57 back button and confirm that the data appears.
10:02 And this time I'll click the updated note and change it.
10:08 And this time I'll click the device's back button and confirm that that update works
10:12 as well. So, now I'm able to add and update notes.
10:18 And the data is being saved to persistent storage.
10:20 The functionality of my note taking app is almost complete.
10:25 I'll just need to add a delete feature, that lets the user delete a note and the
10:28 initial version of my app would be complete.
10:31
Collapse this transcript
Deleting notes
00:00 The note taking app now has the ability to add and update notes and now I want the
00:04 user to be able to delete notes as well. The user interface pattern for deleting
00:11 items from a list varies from one app to the next.
00:15 Unlike other mobile operating systems, there's no single required user interface
00:19 for this operation but the most common one you'll see, is the context menu.
00:25 When the user clicks and holds on an item, and then releases it.
00:29 Instead of being registered as a click, it's registered as a request for a menu.
00:34 Then the menu can contain an option that lets them delete the selected item.
00:40 So that's how we'll implement it in our app.
00:42 I'll do all of this work in the main activity Java class.
00:46 The first step is to take the list control that's a part of our list activity and
00:51 register it for context menus. You do this by calling a method called
00:57 register for context menu. And you pass in the list view that's a
01:02 part of the list activity. I'll do this in the on create method, I'll
01:06 look at my main activity class in fullscreen mode.
01:11 I'll place the cursor after said content view, and I'll call the method register
01:15 for context menu. Then, I'll pass in the list view.
01:21 Using another method called get list view. So now when the user touches and holds on
01:26 an item for a moment, then releases it, it'll be seen as that context menu
01:30 request. And it'll result in calling a method
01:34 called on create context menu. Each time the method is called You can
01:39 either load a menu that you define in XML, or, if your menu is going to be variable
01:43 depending on the circumstance, or, you're only adding an item or two, you can do it
01:48 all in Java code. I'm going to use the pure Java code
01:54 approach, because my context menu will only contain a single item.
01:58 Before I create the context menu I'm going to set up a couple of more declarations at
02:03 the top of the class. First, I'm going to declare a field
02:08 that'll be used as the ID of my context menu item.
02:14 I'll place the curser after my existing constant.
02:17 I'll create another private static final integer and I'll name this menu delete ID
02:22 and I'll give it a value of 1002. It can be any integer value you like.
02:30 Just make sure you're not using a value that's used elsewhere.
02:32 Next I'll also create a field that I'll call current note ID.
02:38 Data typed as an integer. There are going to be two methods.
02:43 One to construct the context menu and one to handle the event that's fired when the
02:48 user selects a menu item. You'll be able to detect which item in the
02:53 list the user has selected when the context menu is constructed but not when
02:57 the menu item is selected. So you have to save it persistently
03:01 between the two operations. And that's what this new field is for.
03:07 I'll go down to the bottom of my existing code.
03:10 And I'll add a new method. This is an overwrite, and it's named on
03:15 create context menu. I'll create the method signature and
03:20 remove its default implementation. You receive 3 arguments in this method, a
03:26 context menu, which is the menu that will be displayed.
03:30 A view and something called ContextMenuInfo.
03:36 My first task is to figure out which task in the list, that is which note, that the
03:39 user wants to delete. I can get that information from the
03:44 ContextMenuInfo object but only if I recast it to one of its sub-classes.
03:51 So I'm going to create a variable that I'll call adapter context menu info.
03:56 And I'll name it info. And I'll get that reference by simply
04:00 casting menu info. I'll type in that existing argument name.
04:06 Then, I'll press command one, and I'll add the casting.
04:11 So now the menu info object has been cast as info, and that object can tell me which
04:16 item of the list I'm talking about. On the next one, I'll get that information
04:23 and save it to my current note ID field. I use this code.
04:29 currentNoteId equals info.id. I have a problem with this code.
04:34 The Id field of the info object is a long value and current node Id needs to be an
04:39 integer. I'll explain why in a moment.
04:45 So I'm just going to use casting syntax here, and down cast from the long to the
04:50 int. So now, I've saved the information about
04:54 which item I want to delete, and I'm ready to add an item to the menu, and here's how
04:59 I'll do it. I'll use the menu argument that was passed
05:03 into this method, and I'll call it add method, and I'll pass in four arguments.
05:09 The first argument is called a group id. You only need a value there if you're
05:15 going to have groups of menu items. I'm not.
05:18 I'm just going to have a single menu item. So I'll pass in a dummy value of zero.
05:24 Next, I'll pass in the ID constant that I created earlier.
05:28 Menu delete I.D. and I'm saying that the menu item I'm
05:33 adding will have this I.D. next I'll pass in another integer which is
05:40 the order in which I want the menu items to be listed.
05:44 Once again I only have one so I'll pass in zero and finally I'll pass in a string.
05:49 I'm asked for a character sequence but a string will be automatically transformed
05:53 as needed. And this is the label that the user will
05:57 see. So now when the context menu appears,
06:00 it'll have a single menu item, it'll say delete, but it'll have this ID that I
06:05 passed in. Now when the user selects this menu item
06:10 That'll trigger another method. This one is called on context item
06:15 selected. Once again, it's an override.
06:19 So I'll type in the beginning of the method name and fill in the method
06:23 signature. I'll leave this return statement in.
06:26 I'll need it in a moment. And then, when the method is called, I'll
06:30 compare the item ID of the item argument that's being passed in here.
06:37 To my menu delete ID constant that I use to construct the menu item.
06:41 I'll use an if clause, and I'll set the condition as follows.
06:47 Item dot get item ID, and I'll compare that value to my constant.
06:54 Menu to lead id. If those two values match, I'll delete the
06:58 item from persistent storage. I'll get a reference to the selected note.
07:05 I'll create a new note item reference, and I'll get its value by calling my notes
07:09 list's object's get method, and passing the current note id.
07:14 Then, I'll use my data source class's remove method.
07:19 I created this in the last chapter. And I'll pass in the note object.
07:27 And then just as I did when I updated notes and saved them to persistent
07:30 storage, I'll call refreshDisplay. And that's all the code I need.
07:36 And I'm ready to test. I'll run the application in the emulator,
07:41 and when it opens, I'll click and hold on an item.
07:46 The contents menu appears with the delete menu item, I click it and the note is
07:50 removed and the list is updated. And so now all of the functionality of my
07:55 note apps is in place. I can add, update and delete notes and
07:59 save and remove them in persistent storage.
08:03 In the next chapter, I'll show you how to make some changes to the app that will
08:07 make it run and look just as good on older versions of Android, as on the newer ones.
08:13
Collapse this transcript
6. Supporting Older Versions of Android
Getting and integrating ActionBarSherlock
00:00 The application now works well on the newer versions of Android, starting with
00:04 Android 3 or Honeycomb. But before deploying the application, I'd
00:09 like to make it compatible with older versions, starting with Froyo, in
00:13 developer terms that's API version 8. So, I've opened a version of my eclipse
00:19 project called older versions. In this version of the project, I've done
00:24 a little bit of code clean up. I've removed unused imports, and I've also
00:28 tuned my code a little bit using constants instead of literal strings whenever I've
00:33 referring to the key and the text values. And also using string resources instead of
00:40 literal strings. Such as this one, r.string.delete in the
00:45 context menu. The only change I'll make directly to this
00:49 project right now, is to make it usable on the older versions of Android.
00:54 I'll go to the application manifest. If it opens in the visual interface, click
01:00 on the XML view, and change the minimum SDK version from 13 to 8.
01:07 Save your changes. And then, assuming that you have a virtual
01:11 machine created with 2.3 or Gingerbread, you can now test it.
01:17 I'll run the application, and I'll choose my Gingerbread emulator, and here it is.
01:23 And when the application launches, the Action bar isn't displayed.
01:28 It does run, but because the Action bar isn't a part of the older operating
01:32 system, all you see is the app name. Some of the functionality is still
01:38 available. For example, the plus icon that appears on
01:42 the action bar on Jelly Bean is available in the menu.
01:47 But when I click it, the app crashes. I'll go over to log cat and see what
01:52 happened, and I'll see that it's looking for the method Get Action Bar, which is
01:57 not a part of Gingerbread. So, you could write a whole bunch of
02:02 custom code, and create alternate layouts to solve this, but it turns out there's a
02:07 much easier solution. An Android developer named Jake Wharton
02:12 has created a library called ActionBarSherlock.
02:17 It's available from this website, actionbarsherlock.com.
02:22 It's an extension of the Android support library that lets you implement the action
02:26 bar across all version of Android. Before you continue with the coding,
02:32 download this library in one of these archive formats, and extract it.
02:38 I've extracted it to my Desktop, but you can place it anywhere on your hard disk.
02:44 This is the folder that I extracted. The critical sub-folder is this one,
02:49 actionbarsherlock. It's an Android project that you'll be
02:54 able to import and link to your application.
02:58 I'll go back to Eclipse, and I'll go to the package explorer.
03:03 And now I'm going to import action actionbarsherlock into my workspace.
03:09 I'll choose File > Import, and then under the android category, I'll choose existing
03:14 android code into workspace. I'll click Next and then Browse.
03:23 I'll go to my Desktop where I extracted the Action Bar Sherlock files.
03:27 I'll double-click, and I'll select the ActionBarSherlock sub-folder, and click
03:35 open. Then to make sure that you have a copy of
03:39 this project that's part of your project, select Copy Project into Work Space and
03:43 click Finish. Here's the ActionBarSherlock folder, it's
03:51 now in Eclipse project. Working Jelly Bean, you'll get an error
03:56 showing up in the consolel. It says, unable to resolve target android
04:01 14. The issue here has to do with support
04:04 library that's included in your project and ActionBarSherlock project.
04:11 It's part of your Libs folders, and it's named android support V4.jar.
04:18 There's a version of this jar file also in ActionBarSherlock, but they don't match
04:22 each other. To fix this, take the version that's in
04:26 your Libs folder, and copy and paste it into the Libs folder of ActionBarSherlock,
04:31 and overwrite the version that's included in that library.
04:37 That will clean up that error. The two projects are now using the same
04:42 version of the library, and that's critical.
04:46 And here's one thing you can do to make it easier to work with your project in the
04:49 future. Go to the project and go to its
04:52 Properties, and go to the Project References category, and select the
04:58 project ActionBarSherlock. Now, I'll close both projects, and then
05:06 I'll double-click Older Versions to open it.
05:11 Because this project now references the ActionBarSherlock project, I'm prompted to
05:17 open it. I'll click Yes, and now I can open my code
05:21 and start using the ActionBarSherlock library to implement the action bar on the
05:25 older versions of Android. And I'll show you the code you need to
05:31 change in the next movie.
05:32
Collapse this transcript
Enabling the action bar on all versions of Android
00:00 I'm about half way through the process of implementing the action bar for older
00:03 versions of Android. This is the state of the application right
00:07 now. Showing the action bar on Jelly Bean.
00:10 But only the app name on Gingerbread. I'll go back to Eclipse where I've
00:16 imported and linked the action bar short lock library.
00:19 And now I'm ready to start making some code changes.
00:22 I'll start in the main activity class. ActionbarSherlock does its work by
00:27 providing alternative versions of many of the common Android classes.
00:33 For example, if you want to use Actionbarsherlock on a list activitiy.
00:38 Instead, use a class called Sherlock ListActivity.
00:43 I'll get rid of this super class declaration, and I'll type sher and press
00:47 Control + Space, and there's a list of all of the alternative classes.
00:53 And I'll choose this one, SherlockListActivity.
00:55 That adds an import for that class, and I no longer need the import for
01:00 ListActivity. So I'll delete it.
01:05 You could also use the Organize Imports feature from the Source menu.
01:09 I'll save my changes, and then go and look at my Problems View.
01:14 I have two new errors in the Problems view.
01:18 And they're the first clue to something you need to do in you classes that use
01:21 Sherlock. I'm getting this error in 2 places, in
01:26 method that use the menu and the menu item class.
01:30 Here's what's going on. Action by Sherlock provides versions of
01:35 these classes as well. And you need to make sure you're using
01:39 those, and not the versions of the classes that are a part of the Android SDK.
01:45 To make this happen, I'll go back up to my import statements, and I'm going to change
01:49 the imports for menu and menu item, to use the Action Bar Sherlock versions.
01:55 I'll change the menu class first. I'll get rid of Android.view as the
02:01 classes package and replace it with com.actionbarsherlock.view.
02:08 Now, I'll copy that and I'll paste it in place with the menu item.
02:13 I'll save those changes and now I have new errors.
02:19 The next issue is in the onCreate options menu method.
02:23 The problem here is that I'm using a method called get menu inflator that's a
02:27 part of the activity but, instead I need to use a get menu inflator method that's a
02:32 part of sure luck. The solution for this is to place the
02:38 cursor before the call to get menu inflator And call a method called get
02:42 sherlock. I'll type get S and press control, space
02:48 and choose getSherlock and it returns the action bar sherlock object.
02:55 I'll separate those with a period, save my changes and that error goes away.
03:02 The next error is in the onContextItemSelected method.
03:06 This error appeared, when I replaced the menu item Import up above.
03:12 And that's because, onContextItemSelected, expects the Android version of Menu Item,
03:17 and not the Action Bar Sherlock version. So to fix that, I'll add the package of
03:23 the menu item class as an explicit declaration with android.view.
03:29 I'll save those changes. Now I'll make the same sorts of changes to
03:34 the not editor activity class. The note editor activity currently extends
03:39 the activity class and I'll change that to Sherlock activity.
03:44 Just as I did with the list activity, I'll correct the imports.
03:48 I pressed control space to add the Sherlock activity class and then command
03:53 shift O to organize the imports. Or on Windows, Control + Shift + O.
03:59 Next I'll make the same sort of changes to the imports that I did before.
04:05 I'll go back to main activity I'll scroll to the top to my imports.
04:11 I'll grab the import com.actionbarsherlock.view, copy it, go
04:16 back to the note editor, and replace the menu item here.
04:24 And that corrects the item here that's looking for the menu item.
04:29 Finally I need to change this call, getActionBar.
04:33 This is actually a method that doesn't even exist in older versions of Android.
04:37 And you might get away with compiling the application with it But when it runs it
04:42 would crash. Instead of Get Action bar, you can correct
04:47 this issue with a method called Get Support Action Bar.
04:53 That's a method that's a part of the Action Bar Sherlock Libary.
04:57 I'll Save those changes. I'll go back to my problems view, and see
05:02 that all of the fatal error are gone. I still have these warnings, but I can
05:06 ignore those. I have one more step to follow before I
05:10 can test the application. I'll go to the Android Manifest file.
05:17 In this file, I'm declaring the theme right here.
05:20 And I'm using something called app theme. When you use action bar sherlock you must
05:26 themes that are provided as part of that library.
05:30 I'll get rid of app theme and press Control + Space type theme and there's a
05:35 list of all the Sherlock theme's. I'll use this one.
05:40 Theme.sherlock.like.dark action bar. These are declared in files in the
05:46 Resources folder of the action bar Sherlock Library.
05:49 I'm ready to test the application. I'll go back to my main activity and click
05:55 the Run button. And I'll choose the ginger bread emulator.
05:59 When it opens it now looks exactly the same as the version in jelly bean.
06:07 I can click the plus icon, type in a note and I see that the action bar appears here
06:12 and because I've made the call to turn the launcher icon into an up button I see the
06:18 little back arrow graphic and I can click and go back.
06:26 And the application now works exactly the same on all versions of Android.
06:31 When you package your application for deployment, be sure that ActionBarSherlock
06:36 is included. It's open source and completely free.
06:40 And it makes it possible to make your applications look the same Across all
06:43 versions of Android.
06:45
Collapse this transcript
Conclusion
Next steps
00:00 Thanks for watching this course, Building a Note-Taking App for Android.
00:05 To learn more about Android App Development, if you're getting started
00:08 with Android for the first time, I recommend watching Android App Development
00:12 with Java Essential Training. It's a comprehensive course that teaches
00:18 you about the basic architecture of Android apps and about many of the
00:22 features of the Android API's. To learn more about working with data on
00:27 android devices, watch Android SDK: Local Data Storage.
00:32 In addition to more information about shared preferences, this course teaches
00:36 how to work with XML and JSON data files and also how to work with SQL Lite.
00:43 And we'll get building and monetizing game apps for Android.
00:46 To learn how to build a completely type of app for Android devices, and at developing
00:50 applications for Amazon Kindle devices, for information about the API's that are
00:54 specific to Kindle. If you want to learn more about the Java
00:59 programming language, you can get started with Java with Java Essential Training or
01:03 learn about advanced techniques with Java Advanced Training.
01:08 And to learn about other ways of putting Java to work, you can watch Up and Running
01:13 with Java Applications. These courses, taken altogether, can help
01:18 you learn more about working with the Android SDK and programming with Java.
01:23
Collapse this transcript


Suggested courses to watch next:

Responsive Design Fundamentals (2h 15m)
James Williamson

Responsive Design Workflows (1h 20m)
Justin Putney


Building a Note-Taking App for iOS (57m 32s)
Todd Perkins


Are you sure you want to delete this bookmark?

cancel

Bookmark this Tutorial

Name

Description

{0} characters left

Tags

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

bookmark this course

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

Error:

go to playlists »

Create new playlist

name:
description:
save cancel

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

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

get started learn more

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

Get access to all lynda.com videos

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

Get access to all lynda.com videos

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

Access to lynda.com videos

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

You don't have access to this video.

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

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

How to access this video.

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

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

learn more upgrade

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

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

You don't have access to this video.

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

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

Need help accessing this video?

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

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

preview image of new course page

Try our new course pages

Explore our redesigned course pages, and tell us about your experience.

If you want to switch back to the old view, change your site preferences from the my account menu.

Try the new pages No, thanks

site feedback

Thanks for signing up.

We’ll send you a confirmation email shortly.


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

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

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

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

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

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

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

   
submit Lightbox submit clicked