Android Tutorial for Beginners: Part 3

An Android Tutorial that shows you how to make your first app app step-by-step, using Android Studio! By Darryl Bayliss.

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

Updating the List Data

To update the list, you need to add an update method to your adapter and then call it from your activity.

First, add the following method to JSONAdapter.java:

public void updateData(JSONArray jsonArray) {
    // update the adapter's dataset
    mJsonArray = jsonArray;
    notifyDataSetChanged();
}

This method accepts a JSONArray input, sets it as the adapter’s datasource, and calls notifyDataSetChanged to refresh the list. The adapter is already set up to know what to do with the data, so that’s all you need!

Now go back to MainActivity.java. You’re going to use your new method to update the list when the network call comes back. Find the following code in onSuccess, which is embedded within queryBooks:

// 8. For now, just log results
Log.d("omg android", jsonObject.toString());

Replace it with this instead:

// update the data in your custom method.
mJSONAdapter.updateData(jsonObject.optJSONArray("docs"));

This is simply a call to updateData with the newly-returned query response. As soon as the data comes back, you don’t waste any time — you send it straight to the adapter, which whips it into shape for the ListView!

It’s finally time — run your app, and search away!

first_query_w_list

Now you can type a search string into your EditText, tap the Search button and let the ListView (somewhat) magically populate from your web search. Not only that — you can scroll through all the results and look at book titles, author names, and thumbnails of the cover images. This is already a pretty cool app!

Showing Progress

One nice feature you may notice missing is some kind of progress bar or spinner to let the user know your app is “thinking.” Lets solve that now.

Add the following line to the list of variables at the top of MainActivity.java:

ProgressDialog mDialog;

ProgressDialog is an Android class that provides a convienent solution for times when you want to provide feedback that your App is performing some sort of intensive task. That could be fetching large files and reading their contents, setting up basic values for the first time the App run or fetching online content like your current App does.

Lets set some initial values, go to your onCreate Method and add these lines at the end:

mDialog = new ProgressDialog(this);
mDialog.setMessage("Searching for Book");
mDialog.setCancelable(false);

Good. You’ve told your Activity you want a ProgressDialog to be created with a particular message and that you don’t want the user to have the ability to cancel it. Lets put this to work, add this line to queryBooks, immediately after creating your AsyncHttpClient:

// Show ProgressDialog to inform user that a task in the background is occurring
mDialog.show();

You want the Dialog to disappear when the request is over, which could actually be in one of two spots – onSuccess or onFailure. Add the following line at the very beginning of onSuccess:

// 11. Dismiss the ProgressDialog
mDialog.dismiss();

Then add the same line to the beginning of onFailure:

// 11. Dismiss the ProgressDialog
mDialog.dismiss();

Run the app again and do another search.

This time, your Dialog will appear in the middle of your screen and will spin as your networking call is happening. Much better! Your App users now know when something is happening behind the scenes thanks to you.

The Detail Activity

Seeing the list of all the books is exciting! The next logical step is to let the user select a book from the list to see more details or a larger version of the cover.

For this app, you’ll only show a larger version of the cover. But the techniques you use will pave the way for the additional challenge of displaying any further details that may interest you. Let’s get started!

First, add the following line to res/values/strings.xml:

<string name="activity_details">Book Details</string>

This is simply to provide a title for the activity. As mentioned before, it’s good to keep all the strings in one file!

Next is the layout XML. It won’t be complicated. Right-click on res/layout and select New > Layout Resource File.

new_layout_resource_file

Name it activity_detail.xml, with a Root Element of ImageView.

activity_detail

That’s almost it right there. All you need to do now is give the ImageView an id, a default image, and a bit of margin space for good measure. Edit activity_detail.xml in Text mode to look like this:

<?xml version="1.0" encoding="utf-8"?>
<ImageView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/img_cover"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_margin="25dp"
    android:src="@drawable/img_books_large"/>

That’s simple enough. This screen will now show a single ImageView with a 25dp margin all around, and the default image is img_books_large.

Next, you need to make a new Activity. Right-click on the com.example.omgandroid package (or the package name you set originally) and select New > Java Class, as before.

Name the class DetailActivity.

making_detail_activity

This creates a simple, empty class for you. Next, modify the class definition so that your new class extends Activity, like this:

public class DetailActivity extends ActionBarActivity {

You already know you need to access the ImageView from your layout, so add the following method to your activity:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // Tell the activity which XML layout is right
    setContentView(R.layout.activity_detail);

    // Enable the "Up" button for more navigation options
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);

    // Access the imageview from XML
    ImageView imageView = (ImageView) findViewById(R.id.img_cover);
}

The above code simply tells the Activity to use the simple XML layout you made earlier, and then grabs the ImageView you need from it. But wait: what is that getSupportActionBar stuff doing in there?

The Up and Back Buttons

You may have noticed, or simply used it without really thinking about it, the Up button in many Android apps. The proper Android design of the Up and Back buttons is well-documented here and is worth a read, but it all begins with enabling the button as you just did.

The other steps for enabling the Up button take place in your manifest. Open AndroidManifest.xml and add the launchMode attribute to MainActivity so that it looks something like this:

<activity
    android:name=".MainActivity"
    android:label="@string/app_name"
    android:launchMode="singleTop">

Note: Depending on your Android Studio version, the package name you selected when you created the project, and a few other factors, the above might not match what you see in your own AndroidManifest.xml file exactly. The only thing you need to really worry about is adding the new launchMode attribute as shown above. You can leave the rest as is.

So, do you recall from earlier in this tutorial about how the manifest is “the boss” who takes in “jobs” in the form of Intents and checks if there is a team member right for the task? Normally, the manifest would arrange for the system to start a brand-new instance of that Activity every time.

But, by setting the launchMode attribute to singleTop, you’re telling the manifest to use an already-existing instance of that Activity, if possible. That way, when you use either the Back or Up button to return to the main screen, your most recent search results will still be there and you won’t have to start from scratch!

Next, add a definition for the DetailActivity to the manifest, immediately after the one for MainActivity:

<activity
    android:name=".DetailActivity"
    android:label="@string/activity_details"
    android:parentActivityName=".MainActivity">
    <meta-data
        android:name="android.support.PARENT_ACTIVITY"
        android:value=".MainActivity"/>
</activity>

This looks pretty similar to the definition for MainActivity, except for the stuff about “parent activity.” Setting the parent activity tells the manifest which activity should be displayed when there’s a request to go up from DetailActivity.