Upward Mobility: Android for iOS Developers, Part 4

Sensors indicate activity on the planet's surface, captain!

Our mini-Encyclopedia Galactica can do a few things now, but it’s hardly ready to offer up the recipe for a Pan-Galactic Gargle Blaster yet. If we want to take things to the next level (or at least the next screen), we need to learn how to move between Activities.

Moving between Activities is the Android equivalent of switching between view controllers, but more formalized. In some ways, it’s very similar to the storyboard and segue metaphor introduced in iOS6. To begin with, we need to create a new Activity in ADT, using the File->New->Other menu pick, and then choosing Android Activity from the choices under Android. I chose to name mine DetailActivity, and place it hierarchically under the MainActivity. By doing this, the back button will return me to the original Activity when I hit it.

Screen Shot 2013-07-01 at 10.51.56 PM

Using the blank template, I then added a large TextView at the top, an ImageView, and another TextView set to 10 lines of smaller text at the bottom.

Screen Shot 2013-07-02 at 12.33.29 AMNow we need to teach the MainActivity to navigate to this new page. I added a Button to the MainActivity layout, and then wired a listener up to it in the code in the onCreate method:

final Button button = (Button) findViewById(R.id.moreInfo);
     button.setOnClickListener(new View.OnClickListener() {
         public void onClick(View v) {
        	 Intent a = 
                     new Intent(getApplicationContext(),DetailActivity.class);
        	 a.putExtra("PLANET_NAME", (String) spinner.getSelectedItem());
             a.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
             startActivity(a);
         }
     });

The mechanism that you use to transition between Activities is called an Intent. You create an Intent with the application context and the class of the Activity you wish to navigate to. Notice that unlike iOS, you don’t actually instantiate the new view you’re going to, so there’s no way to pre-populate values in the next view. So how do you pass in values? You stick them on the Intent, using the putExtra method. In this case, we put the planet name into the Intent, so that the detail page will know which planet to display.

One of the big gotchas with passing data via Intents is that you can’t just throw any old object onto it. Because of the Android architecture, it either has to be a simple object like a String, a primitive, or something that implements Serializable. You can also put Bundles or Parcels onto it.

Now we’re ready to code the detail page. Here’s the onCreate:

protected void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   setContentView(R.layout.activity_detail);
   Bundle extras = getIntent().getExtras();
   TextView description = (TextView)findViewById(R.id.planetDescription);
   Bitmap bm = null;
   if (extras != null) {
       String planetName = extras.getString("PLANET_NAME");
       TextView title = (TextView)findViewById(R.id.planetName);
       ImageView imageView = (ImageView) findViewById(R.id.planetImage);
       title.setText(planetName);
       if (planetName.equalsIgnoreCase("pern")) {
          description.setText("Pern is a violent place, due to the wildly eccentric orbit of ...
          bm = BitmapFactory.decodeResource(getResources(), R.drawable.venus);
       }
       if (planetName.equalsIgnoreCase("barsoom")) {
          description.setText("Barsoom (AKA Mars), in spite of being our ...
          bm = BitmapFactory.decodeResource(getResources(), R.drawable.marte);
       }
       if (planetName.equalsIgnoreCase("ringworld")) {
          description.setText("The Ringworld is a massive artificial ...
          bm = BitmapFactory.decodeResource(getResources(), R.drawable.ringworld);
       }
       if (planetName.equalsIgnoreCase("equestria")) {
          description.setText("Actually, we're not sure if Equestria is a country, ...
          bm = BitmapFactory.decodeResource(getResources(), R.drawable.equestria);
       }
       if (bm != null) {
          imageView.setImageBitmap(Bitmap.createScaledBitmap(bm, 400, 400, false));
       }
   }
   // Show the Up button in the action bar.
   setupActionBar();
}

After setting the Activity’s layout, we get our hands on the Bundle that contains all the extras that were added to the Intent. We can then use the planet name to determine what content to drop into the title, image, and description text.

There’s one new thing to look at here, which is the image manipulation. The first part of the process involves turning the PNG files we dropped into our project to Bitmaps. Because the files were dropped into the drawable-mdpi folder, they were automatically added to the R file as ids. Because of that, we can access them using the BitmapFactory.decodeResource method. Once we have the bitmap, we have to make it fit properly, because our images are different sizes. By using the Bitmap.createScaledBitmap method, we can make the images a uniform size on the screen.

Now, when we select a planet and hit “More Info” on the main screen, we get taken to our new screen, with a wealth of information!

Screen Shot 2013-07-02 at 12.33.14 AM

Now that we’ve gotten beyond our first screen, we’re ready to brave the Interwebs! Next time, we’ll take a stab at accessing web resources!

 

tags: , , ,