Make Your First Android App: Part 2/3

Learn to enhance the app you created in the first part on how to make your first Android app and to add new UI controls to add new functionality. By Matt Luedke.

Leave a rating/review
Save for later
Share
You are currently viewing page 5 of 7 of this article. Click here to view the first page.

Detecting List Selections

Looking at the items in a list is cool, but this is an app, and interactivity is even better! So next you’re going to set up a way to detect user selections from the list.

First, modify the class definition in MainActivity.java to add support for another interface. To do this, modify this line:

public class MainActivity extends Activity implements View.OnClickListener {

To look like this:

public class MainActivity extends Activity implements View.OnClickListener, AdapterView.OnItemClickListener {

All you’ve really done is add support for a new interface – AdapterView.OnItemClickListener, which, as the name suggests, listens for item selections from a ListView. MainActivity is really stacking up the credentials!

Next, add the following code to the end of onCreate:

		// 5. Set this activity to react to list items being pressed
		mainListView.setOnItemClickListener(this);

The above code sets MainActivity as the listener for any item clicks on mainListView.

Finally, add the following method to the end of the MainActivity class (but before the final closing curly brace):

	@Override 
	public void onItemClick(AdapterView parent, View view, int position, long id) {
		// Log the item's position and contents
		// to the console in Debug
		Log.d("omg android", position + ": " + mNameList.get(position));
	}

This implements onItemClick, thus setting up MainActivity to live up to the title of being a card-carrying OnItemClickListener.

activity_business_card

But what’s happening inside onItemClick? There’s a weird Log.d in there, and then something with a get(position)

Take a look at what you’re passing along to onItemClick. In particular, look at int position, which is an integer equal to the index of the item the user pressed on the list (counting up from 0).

You take that position, as well as the item at that index in your list of names, and log them. Logging is a very basic, but very useful debugging technique.

Run your app, enter a few values and add them to the list, just as before. Then select an item. There’s no visible effect for the moment.

With the app still running, click the 6: Android button in Studio, as shown below:

open_logcat

When you click this button, a console called logcat pops up. It will read off tons of stuff from your emulator or device, the majority of which is not of much interest to you at this point. The log statements you generated with your selections are here, but there’s too much noise to see them.

Here are some useful ways to filter out the noise and see only what you want:

Notice the option for Log level. When you put your Log command into code, it specifically was the Log.d command. The d is for “debug” level. The levels are:

  • v: Verbose
  • d: Debug
  • i: Info
  • w: Warning
  • e: Error

When you select a log level for logcat, it will only show messages at that level or higher. And the levels start at verbose and go up to error, in the same order as listed above. So, if you select the log level as Warning, then you’ll see all warnings and errors but nothing else.

Meanwhile, you can use the text box to the right of the log level drop-down to apply a filter and show only those messages that contain the text you typed in.

Now that you know this, set the log level to Debug and type omg android into the filter text box.

logging_item_clicks_arrow

Great! You now have a clean feed of log statements and you can detect when a certain item gets selected in your list. The ability to log will come in handy as you create more complicated apps and want to stay informed of the inner workings of your code.

The Action Bar

Your app has several different views now, and it’s time to think about other ways to add functionality. Older Android devices used to have a Menu device button that would display a bunch of options depending on the situation, but since Honeycomb in early 2011, Android has used the Action Bar to display any options for the current view.

action_bar

The Action Bar provides a familiar base for your users. Since it’s present across apps, making good use of the Action Bar means a significant part of your app’s functionality will be immediately intuitive to an Android user. Conversely, neglecting the Action Bar would confuse all your users who expect it to work — and that would be weird!

Note: Since you are only targeting Ice Cream Sandwich and later for this tutorial, you don’t have to worry about bending over backwards to get the Action Bar into your app. If for some reason your project needs to be compatible with really old versions of Android, you’ve got two good options: a compatibility library from Google and a well-regarded third-party solution called Action Bar Sherlock.

The Action Bar is already in your app — it just has no options attached to it yet. That will be your first order of business next!

Sharing

Soon you’ll have a chance to show off the fact that you’re learning Android, from within your own app! You’ll do this using an intersection of the Android concept of the Intent and the Action Bar, known as a ShareActionProvider.

One of the advantages of an Intent is that you can construct it in either a specific (explicit) or generic (implicit) manner. You used an example of the explicit type when you specifically defined the Intent that launches your app, which the manifest then identifies as MainActivity. Now you’ll see an example of the implicit type.

A generic Intention really helps in this case. After all, some of us prefer to share things with the entire world, and others with just a few friends. Rather than wondering what a potential user’s favorite social network might be and integrating them one by one, you can politely tell the Android device that you’d very much like to share a bit of content (thus expressing an Intent), and Android will graciously take it from there!

Navigate to src/main/res/menu/main.xml and open it.

menu_main

You’ll note that there’s some auto-generated XML in there, but you don’t need it. Replace the whole thing with this:

<!-- Defines the menu item that will appear on the Action Bar in MainActivity -->
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <!-- Share item -->
    <item
        android:id="@+id/menu_item_share"
        android:showAsAction="ifRoom"
        android:title="Share"
        android:actionProviderClass= "android.widget.ShareActionProvider" />
</menu>

The ShareActionProvider is built-in (hence the android.widget prefix) and ready-to-use. So, when a user selects your menu item, the necessary functionality is already in place for you to make use of.

Now head over to MainActivity.java and add the following variable at the top of the file (where the previous variables are):

ShareActionProvider mShareActionProvider;
Note: Studio may be confused about which ShareActionProvider you mean, so if it asks, use android.widget.ShareActionProvider.

Next, you need to add the following two methods to the class – the first one, onCreateOptionsMenu, might already be implemented in the class. If it is, simply replace the existing implementation with the new one.

@Override
public boolean onCreateOptionsMenu(Menu menu) {

	// Inflate the menu.
	// Adds items to the action bar if it is present.
	getMenuInflater().inflate(R.menu.main, menu);

	// Access the Share Item defined in menu XML
	MenuItem shareItem = menu.findItem(R.id.menu_item_share);

	// Access the object responsible for
	// putting together the sharing submenu
	if (shareItem != null) {
		mShareActionProvider = (ShareActionProvider)shareItem.getActionProvider();
	}

	// Create an Intent to share your content
	setShareIntent();

	return true;
}

private void setShareIntent() {

	if (mShareActionProvider != null) {

		// create an Intent with the contents of the TextView
		Intent shareIntent = new Intent(Intent.ACTION_SEND);
		shareIntent.setType("text/plain");
		shareIntent.putExtra(Intent.EXTRA_SUBJECT, "Android Development");
		shareIntent.putExtra(Intent.EXTRA_TEXT, mainTextView.getText());

		// Make sure the provider knows
		// it should work with that Intent
		mShareActionProvider.setShareIntent(shareIntent);
	}
}
Important: If there’s an implementation of onOptionsItemSelected in the class, remove it.

onCreateOptionsMenu gets called once, when the activity first starts. Similar to how you specified which layout XML file you wanted to use for the activity in onCreate, you now direct the menu inflater to look at main.xml for the menu items that go on the Action Bar.

From there, you can access the menu item you defined in XML by its id, menu_item_share, and then you can access its action provider. Previously, you specified that this item’s action provider was a ShareActionProvider. So, you can safely cast to that type in your code and hang onto a reference to it via the mShareActionProvider variable.

Then, you call setShareIntent. This method creates an Intent, but not just any Intent. It creates an Intent whose action you’ve set to ACTION_SEND. It’s truly as generic as it looks: you’re going to tell Android you want to take the action of sending something.

From there, you set the Intent‘s content type, subject — used by email programs and the like, as the subject header of the message —, and text. The text matches whatever is currently in your TextView. After you’ve packed up everything the Intent needs to know, you pair it with mShareActionProvider.

This code will work, but only “kind of.” As-is, you only call setShareIntent once, at the creation of the menu. It would be much better to update the Intent whenever the TextView changes — otherwise you’re stuck with the initial message forever!

Add the following code to the end of onClick:

	// 6. The text you'd like to share has changed,
	// and you need to update
	setShareIntent();

Here, you simply make sure that the share intent is always up-to-date.

Run the app, and try out the new sharing feature – tapping the share icon on the Action Bar should reveal a lot of choices!

Tapping the share icon on the Action Bar reveals a lot of choices!

The ShareActionProvider automatically puts together an array of possible avenues for sharing content based on the apps you have installed on a given device. This array of options will differ from device to device. The emulator will most likely have far fewer options for sharing, whereas you may have apps like Twitter and Facebook on an actual device and could share through those networks, too.

Matt Luedke

Contributors

Matt Luedke

Author

Over 300 content creators. Join our team.