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.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
Android Tutorial for Beginners: Part 3
55 mins
- Getting Started
- Networking Considerations
- A Glance at Gradle
- JSON Basics
- Creating a Query
- Making the API Call
- Creating the List Rows
- Adapting JSON for a ListView
- Putting Together the Insta-Row
- Connecting the List to the Adapter
- Updating the List Data
- Showing Progress
- The Detail Activity
- The Up and Back Buttons
- An Intent to Show the Detail Activity
- Sharing the Image
- Where to Go From Here?
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!
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.
Name it activity_detail.xml, with a Root Element of ImageView
.
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.
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.
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
.