Beginning Android: Getting Started with Fortune Crunch

Beginning Android: Getting Started with Fortune Crunch

Tutorial Details
  • Technology: Eclipse + Android SDK
  • Difficulty: Beginner
  • Estimated Completion Time: 45 minutes

You’ve learned how to create Fortune Crunch on iPhone and Appcelerator here on Mobiletuts+. Now learn how to create it on Android!

If you’re not familiar with Fortune Crunch, it’s an app created by Mark Hammonds to show how to get started with iPhone development on this site. It was later picked up by John Schulz to show how to do cross platform development with Appcelerator. And now, we’re going to use it to show the creation of a complete Android application from start to finish. Fortune Crunch displays a fortune cookie and allows the user to tap it to crack it open and display a fortune!


Android 101 Tutorials:


Getting Started

We’re assuming that you have all of the tools necessary for Android development already installed. If not, make sure you download and install Eclipse and the Android SDK. To complete the image steps on your own, you’ll also need an image editor that can, at minimum, resize images. This tutorial is specific to Eclipse, but you can comfortably use it on Linux, Mac, or Windows operating systems. You do not need an Android device to complete this tutorial.

If you want to follow along without writing the code yourself, it’s available for download.

Step 1: Creating Your Eclipse Project

Start by creating a project named FortuneCrunch in Eclipse. Do this by choosing File->New…->Android Project. The resulting screen has a number of fields and options you need to fill out.

  • Enter “FortuneCrunch” for the project name
  • Keep “Create new project in workspace” selected
  • You may want to use a different location than the default; your choice
  • Choose your Build Target to be Google APIs Level 8 (Android 2.2)
  • Enter “Fortune Crunch” as the application name
  • Choose an appropriate package name, such as “com.yourname.tutorial.fortunecrunch”
  • Check the box for “Create Activity” and name it “FortuneCrunch”
  • Finally, set the Min SDK Version to 3 (Android 1.5)

If you’ve done all of this the dialog should look something like this:

Eclipse Project

Step 2: Creating Your Resources

Next, you need to create the images the application will work with. The application uses a pair of images: a whole fortune cookie and a cracked fortune cookie.

You should consider creating three different pairs of images for low, medium, and high pixel density screens. The original images are provided for you to edit, or you can use the images included in the source code download.

The resource directories for the specific images were created with the project: lpdi, mdpi, and hdpi. Inside the directory for each screen resolution, the two image resources must be named the same. We’ve named them fortune_cracked.jpg and fortune_uncracked.jpg. Once you’ve done this, the project explorer view will show them:

Creating Resources

Tip: If you edited them and saved them to these directories outside Eclipse, right-click on the project and choose refresh. They should then show up.

Step 3: Defining the Fortune String

When the fortune cookie is opened, it displays the user’s fortune. Now let’s define the fortune string as a resource. Do this by opening the /res/values/strings.xml resource file. Create a new string called “fortune” with the text “Happy Android Hacking!”

It should now look like:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="fortune">Happy Android Hacking!</string>
    <string name="app_name">Fortune Crunch</string>
</resources>

Step 4: Creating Your Layout

Next you need to design your layout resource file. This file will dictate how the one screen of the Fortune Crunch application is displayed. The project wizard creates a default file for you called /res/layout/main.xml. Edit this file and remove all the controls.

The Fortune Crunch user interface has two different states. The first is an image of a complete fortune cookie. The second is an image of a cracked fortune cookie with text displaying over the fortune inside. The second of these two is the more complex ones, so let’s design that first as the design of the easier one will come out of it with almost no extra effort.

To do this, use a RelativeLayout to contain an ImageView and a TextView. The ImageView should be centered horizontally. You’ll want to give it appropriate height and width numbers to constrain the View size. The TextView should be set to layout_alignBottom for the ImageView. Then, using layout_marginBottom you can move it up to overlay the fortune. This sounds complex, so let’s take a look at the resulting XML:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <ImageView
        android:id="@+id/fortune_view"
        android:layout_height="240dp"
        android:layout_width="360dp"
        android:layout_centerHorizontal="true"
        android:src="@drawable/fortune_cracked"></ImageView>
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:text="@string/fortune"
        android:textColor="#A00"
        android:textSize="16dp"
        android:id="@+id/fortune_text"
        android:layout_alignBottom="@+id/fortune_view"
        android:minLines="2"
        android:maxWidth="120dp"
        android:layout_marginBottom="105dp"></TextView>
</RelativeLayout>

This layout works well in portrait mode. We use dp for all measurements so it scales appropriately with the screen size. We also use dp for the text size, so it also scales with the screen size. You wouldn’t want to use sp for the text, because that will scale with the user’s font size – not what you want for a layout like this. The layout view will look something like this:

Creating Your Layout

However, if you switch the landscape mode, you’ll see that this doesn’t work!

Step 5: Creating An Alternate Landscape Layout

Let’s provide a separate landscape layout file, too. It’s a very similar design, except that the image size is swapped so it uses the vertical space. The following xml file must be named main.xml and placed in the /res/layout-land folder, which you must create first.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <ImageView
        android:id="@+id/fortune_view"
        android:layout_height="360dp"
        android:layout_centerHorizontal="true"
        android:layout_width="480dp"
        android:src="@drawable/fortune_cracked"></ImageView>
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:text="@string/fortune"
        android:textColor="#A00"
        android:id="@+id/fortune_text"
        android:layout_alignBottom="@+id/fortune_view"
        android:layout_marginBottom="115dp"
        android:minLines="2"
        android:maxWidth="150dp"
        android:textSize="18dp"></TextView>
</RelativeLayout>

When both files layout folders are present, the explorer view will look something like this:

Layout Folders

The layout view for the landscape layout will look like this:

Landscape Layout

Step 6: Configuring the Layout’s Initial View

Now that you have proper layout files for both portrait and landscape modes for the cracked cookie state, you need to revert it back to the not-yet-cracked version for the initial view. Do this by switching the src attribute of the ImageView to @drawable/fortune_uncracked and add a visibility attribute to the TextView and set it to “gone.”

Step 7: Adding Click Handler

When the user clicks or taps on the fortune cookie, it switches state to the cracked cookie with the fortune text. To enable this function, add the click handler to the appropriate control the user clicks on. A quick way watch for clicks on the whole screen is to register the click handler with the parent control of all child views, in this case, the RelativeLayout you organized all the screen controls in. Make sure that the RelativeLayout control has its clickable attribute set to true. Then add the onClick attribute and set it to toggleFortune.

Your portrait layout file should now look like this:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:clickable="true"
    android:onClick="toggleFortune">
    <ImageView
        android:id="@+id/fortune_view"
        android:layout_height="360dp"
        android:layout_centerHorizontal="true"
        android:layout_width="480dp"
        android:src="@drawable/fortune_uncracked"></ImageView>
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:text="@string/fortune"
        android:textColor="#A00"
        android:id="@+id/fortune_text"
        android:layout_alignBottom="@+id/fortune_view"
        android:minLines="2"
        android:maxWidth="120dp"
        android:layout_marginBottom="105dp"
        android:textSize="18dp"
        android:visibility="gone"></TextView>
</RelativeLayout>

You will need to make similar changes to the landscape layout file.

Step 8: Implementing the Click Handler

Your layout files are complete. Now you need to implement the click handler in Java within your application’s only Activity class. Open the FortuneCrunch.java file and add the following method to it:

    public void toggleFortune(View view) {
        TextView fortune = (TextView) findViewById(R.id.fortune_text);
        ImageView cookie = (ImageView) findViewById(R.id.fortune_view);
        // use the text visibility to determine mode
        if (fortune.getVisibility() == View.GONE) {
            fortune.setVisibility(View.VISIBLE);
            cookie.setImageResource(R.drawable.fortune_cracked);
        } else {
            fortune.setVisibility(View.GONE);
            cookie.setImageResource(R.drawable.fortune_uncracked);
        }
    }

This method retrieves Java objects representing both the TextView and the ImageView. First, the visibility of the TextView is determined. This information can be used to toggle the screen state between the cracked and whole cookie. Based on the fortune text state, the TextView visibility and source image to display are determined. The source image in the ImageView is changed by calling the setImageViewResource() method with the identifier of the correct image to display.

Step 9: Examining the onCreate() Method

While you were editing FortuneCrunch.java, you probably noticed the Activity’s onCreate() method. It looks like this and is created when the project is created:

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
    }

The only method call here you care about right now is the setContentView() method. It references the layout file you created: main.xml. This is why the landscape and portrait mode layout files must share the same file name. If you had named them both “crunch.xml” the call would have to be changed to:

setContentView(R.layout.crunch);

Now the Android platform will load the appropriate main.xml layout file based upon whether the device is in landscape or portrait mode. If the files were named differently, the system would either not find the layout resource or not load it properly.

Step 10: Creating a Debug Configuration

Now that you’re done coding, you probably want to run and test your application. The first thing you should do is create an Eclipse Debug Configuration. Do this by clicking on Run->Debug Configurations… On the Android tab, set the project to FortuneCrunch. You can name your configuration as you like. I like naming my configurations exactly the same as the project.

Debug Configuration

In the Target tab, I prefer to manually choose the target each time. You can also use the debug configuration toconfigure network speeds for the emulator, and many other options. These don’t apply for Fortune Crunch.

Set Target Tab

Step 11: Running Fortune Crunch in the Emulator and on the Device

You can run Fortune Crunch by selecting the Debug Configuration and choosing Debug. Choose either a connected Android device, a running emulator, or launch a new emulator. This screen handles how to launch your app:

And there you have it!

Here is Fortune Crunch running in the HVGA emulator in landscape mode:

Fortune Crunch Preview

Here is Fortune Crunch running on the Nexus One in portrait mode, using the DDMS perspective of Eclipse to capture it:

Fortune Crunch Portrait

Conclusion

In this tutorial, you’ve learned how to implement the Fortune Crunch application on the Android platform. You did this by creating appropriately sized graphics. Then you created layout files for both landscape and portrait modes. Finally, you brought everything together by handling clicks on the screen to crunch that cookie. You’ve only scratched the surface of Android development. Check out all the other great tutorials on Mobiletuts+ to dive deeper into Android development.

We hope you liked this and look forward to your feedback.

Happy Android Hacking!

About the Authors

Mobile developers Lauren Darcey and Shane Conder have coauthored several books on Android development: an in-depth programming book entitled Android Wireless Application Development and Sams TeachYourself Android Application Development in 24 Hours. When not writing, they spend their time developing mobile software at their company and providing consulting services. They can be reached at via email to androidwirelessdev+mt@gmail.com, via their blog at androidbook.blogspot.com, and on Twitter @androidwireless.

Need More Help Writing Android Apps? Check out our Latest Books and Resources!

Buy Android Wireless Application Development, 2nd Edition  Buy Sam's Teach Yourself Android Application Development in 24 Hours  Mamlambo code at Code Canyon


Related Tutorials:


Note: Want to add some source code? Type <pre><code> before it and </code></pre> after it. Find out more
  • http://none Lucy

    Hi Great tutorial,

    How would i make so the fortune text can be shown at random from a list is “fortunes” in either a txt file or xml file.

    Thanks again
    Lucy,

  • tibbi

    Hey,
    nice tutorial, just wanted to add that when you talk/write about uncracked version, on the layout preview you show the cracked one. Not a big deal, it just confused me a bit :P Or have I really done something wrong there?
    Good job anyway

    • http://mobile.tutsplus.com Mark Hammonds

      Thanks for pointing this out! I just updated the code listing.

  • http://dafeda.wordpress.com dafeda

    A very nice and easy to understand tutorial. Thanks for sharing. Not that it matters too much, but the following sentence has a few errors:

    “A quick way [to] watch for clicks on the whole screen is to register the click handler with the parent control of all child views, in this case, the RelativeLayout you organized all the screen controls in.”

    Again, thanks.

  • Matt

    Thanks for the tutorial and I’m glad you made it easy to follow. One thing though, and I will be the first to admit that I probably did something wrong.

    When I opened the FortuneCrunch.java file there was a line: import android.R; at the very top of my import list. When I went to run everything this line caused the app to spit back a bunch of errors. When I opened your source files that line wasn’t there and when I deleted it everything work out fine.

    Any idea where that line came from?

    Also how can I get the text to move up? When I ran the app the text was outside the box that we had made for it.

    Again thanks for putting this up and I look forward to seeing what else I can learn.

  • Rafael R.P

    Hello.!
    Great tutorial,

    i’m getting error on cookie.setImageResource(R.drawable.fortune_cracked);
    the eclipse solution is ‘change to setBackGroundResource’
    but doesn’t fix the error.

    Thx !

  • Shash

    Hey hi,

    I’m an android beginner.Its a wonderful tutuorial.

    But i have a problem with AVD. Whatever AVD i choose to debug dis is what comes at the console.

    [2011-08-24 02:13:34 - Fortune Crunch] Android Launch!
    [2011-08-24 02:13:34 - Fortune Crunch] adb is running normally.
    [2011-08-24 02:13:34 - Fortune Crunch] Performing com.shashank.tutorial.fortunecrunch.FortuneCrunchActivity activity launch
    [2011-08-24 02:13:34 - Fortune Crunch] Automatic Target Mode: Preferred AVD ‘SonyXperia’ is not available. Launching new emulator.
    [2011-08-24 02:13:34 - Fortune Crunch] Launching a new emulator with Virtual Device ‘SonyXperia’
    [2011-08-24 02:13:34 - Emulator] invalid command-line parameter: Files\Android\android-sdk\tools/emulator-arm.exe.
    [2011-08-24 02:13:34 - Emulator] Hint: use ‘@foo’ to launch a virtual device named ‘foo’.
    [2011-08-24 02:13:34 - Emulator] please use -help for more information

    Pls help !!!

    Thanks

  • http://www.kuawaroad.com kuawa_road

    If you get either of these errors in your FortuneCrunch.java file

    “View cannot be resolved to a type”
    “View cannot be resolved to a variable”

    Check your import statements to make sure the view is imported by adding…

    import android.view.View;

    For some reason widget.ImageView & widget.textView were both imported by the layout but the relative layout was left out.

    Also, the main.out.xml error is annoying but you can solve that here…i changed settings and still had a problem until restarting eclipse and refreshing things 50 times. Fun.

    http://stackoverflow.com/questions/2393103/android-sdk-main-out-xml-parsing-error

  • http://changesdone.com/ Riccardo

    Great tutorial guys. Easy to follow and with important tips for Android!

    I just bought “TeachYourself Android Application Development in 24 Hours” and I am waiting for it to be delivered. I hope the book is as easy and clear as this tutorial.

    Thanks

  • Amy

    Hi, when I try to display the result but mine is stated no AVD available. I dont have an android phone, should I click to install anything?

  • SP

    Hello,

    I’m really enjoying going through this tutorial, as I am knew to Java and Android developing. I have followed along all the way to the end, but I am getting two errors, both in the main.xml files for Portrait and Landscape. Here is the error:

    “No resource identifier found for the attribute ‘onClick’ in package ‘android’

    I have done quite a few searches about this error and haven’t been able to figure out what may be causing it. I have followed your code exactly, and triple checked everything just to make sure. Any help would be great!

    -Sean

  • Elvi

    Min SDK must be Version 4 (Android 1.6)

  • http://tommuseth.com Tom

    Nice tute, and a good intro to the SDK and working with Eclipse.

  • Mrrudy

    Very good tutorial. I had issues with the java file recognizing the ImageView and TextView classes:

    TextView fortune = (TextView) findViewById(R.id.fortune_text);

    ImageView cookie = (ImageView) findViewById(R.id.fortune_view);

    as it kept giving me the “TextView / ImageView cannot be resolved to a type” message and I couldn’t run the emulator.

    After hunting about, I found that ctrl+shif+O had Eclipse “import” the classes automatically so it could recognize them. Just a heads up for anyone coming across this who’s a noob like me.

    I’m loving this site.