Monday, January 24, 2011

OnClickListener for ListActivity

I want to be able to show some detailed information about each Dodad. I want to allow the user to click on a Dodad from the ListActivity and have the app display a screen which contains detailed Dodad information. I can use the OnClickListener to capture the user's click on the ListActivity and I can use Intent and a new Activity to display a new screen.

Let's start by defining our new Activity that will display Dodad detail information. Simply create a new class that extends Activity and override the onCreate method. You should have something like this.

DodadDetails.java

package com.mydemo;

import android.app.Activity;
import android.os.Bundle;
import android.util.Log;

public class DodadDetails extends Activity {

private static final String TAG = "MyDemo";

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
Log.d(TAG, "DodadDetails onCreate() started");

super.onCreate(savedInstanceState);
setContentView(R.layout.dodad_details);

Log.d(TAG, "DodadDetails onCreate() done");
}
}

For now let's just make a simple layout called dodad_details. It can simply be a TextView as a placeholder.

Since we created a new Activity in our Android app let's not forget to add it to the AndroidManifest.

Now let's go back to our ListActivity implementation and construct a new private class that implements OnClickListener. Within the constructor for this new class pass in an integer value that will hold the index of the ListActivity item that the user clicked. We also want to override the onClick method so we can create our Intent and start our new DodadDetails Activity.

The new OnClickListener class should look like this.

private class OnItemClickListener implements OnClickListener
{
private int mPosition;

OnItemClickListener(int position)
{
mPosition = position;
}

@Override
public void onClick(View arg0)
{
Log.v(TAG, "Dodad onItemClick at position" + mPosition);
Intent intent = new Intent(Welcome.this, DodadDetails.class);
Welcome.this.startActivity(intent);
}
}

We now simply need to add this class as the listener for our ListActivity items (views). We can do this back in the ArrayAdapter class we previously created for the ListActivity. Specifically in the getView method that we have overrode at the end just before it returns. The single line of code that gets this done looks like :

v.setOnClickListener(new OnItemClickListener(position));

Notice that the position is being passed into the constructor. This will be important later so we can determine what data to display on the DodadDetail Activity.

The application can now be run and the user should be able to click on an item from the ListActivity and the DodadDetail Activity should appear. Like...






















The entire Welcome.java source is here.

package com.mydemo;

import java.util.ArrayList;

import com.mydemo.dodad.Dodad;

import android.app.ListActivity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.TextView;

public class Welcome extends ListActivity {

private static final String TAG = "MyDemo";

private ProgressDialog m_ProgressDialog = null;
private Runnable runGetDodads;
private ArrayList m_dodads = null;
private DodadAdapter m_adapter;

public void onCreate(Bundle savedInstanceState) {
Log.d(TAG, "Welcome onCreate() start");
super.onCreate(savedInstanceState);

setContentView(R.layout.main);

m_dodads = new ArrayList();
this.m_adapter = new DodadAdapter(this, R.layout.dodad_row, m_dodads);
setListAdapter(this.m_adapter);

runGetDodads = new Runnable()
{
@Override
public void run() {
getDodads();
}
};

Thread thread = new Thread(null, runGetDodads, "getDodads");
thread.start();

m_ProgressDialog = ProgressDialog.show(Welcome.this, "One second...", "Fetching Dodads...", true);

Log.d(TAG, "Welcome onCreate() done");
}

private Runnable returnRes = new Runnable()
{
@Override
public void run()
{
if(m_dodads != null && m_dodads.size() > 0)
{
for(int i=0; i < m_dodads.size(); i++) { m_adapter.add(m_dodads.get(i)); } m_adapter.notifyDataSetChanged(); } m_ProgressDialog.dismiss(); } }; private void getDodads() { Log.d(TAG, "Welcome getDodads() start"); try { // Just some dummy data for the purpose of the sample // This code could easily fetch data from a server/database. m_dodads = new ArrayList();
Dodad dodad1 = new Dodad();
dodad1.setName("Dodad Number 1");
dodad1.setDescription("Cool little Dodad");
Dodad dodad2 = new Dodad();
dodad2.setName("Dodad Number 2");
dodad2.setDescription("The everyday Dodad");
Dodad dodad3 = new Dodad();
dodad3.setName("Dodad Number 3");
dodad3.setDescription("Essential do everything Dodad");
m_dodads.add(dodad1);
m_dodads.add(dodad2);
m_dodads.add(dodad3);

// This simulates the time it would take to load the Dodads
Thread.sleep(3000);

Log.d(TAG, "Welcome getDodads() returned (" + m_dodads.size() + ") dodads");
}
catch (Exception e)
{
Log.e(TAG, e.getMessage());
}

runOnUiThread(returnRes);
Log.d(TAG, "Welcome getDodads() done");
}

private class DodadAdapter extends ArrayAdapter
{

private ArrayList dodads;

public DodadAdapter(Context context, int textViewResourceId, ArrayList dodads)
{
super(context, textViewResourceId, dodads);
this.dodads = dodads;
}

@Override
public View getView(int position, View convertView, ViewGroup parent)
{
View v = convertView;

if (v == null)
{
LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.dodad_row, null);
}

Dodad dodad = dodads.get(position);
if (dodad != null)
{
TextView line1 = (TextView) v.findViewById(R.id.textDodadLine1);
if (line1 != null)
{
line1.setText(dodad.getName());
}

TextView line2 = (TextView) v.findViewById(R.id.textDodadLine2);
if(line2 != null)
{
line2.setText(dodad.getDescription());
}
}

v.setOnClickListener(new OnItemClickListener(position));

return v;
}
}

private class OnItemClickListener implements OnClickListener
{
private int mPosition;

OnItemClickListener(int position)
{
mPosition = position;
}

@Override
public void onClick(View arg0)
{
Log.v(TAG, "Dodad onItemClick at position" + mPosition);
Intent intent = new Intent(Welcome.this, DodadDetails.class);
Welcome.this.startActivity(intent);
}
}
}

1 comment:

  1. Thank you for this, the onClick function was easy to implement!

    ReplyDelete