Populate activities based on ListView selection

In this tutorial I show you how you can populate your activity based on a previous selection in your Listview. This way you don’t need to create tons of different activities for each item selected in your ListView. This is a nice tutorial when your working on a recipe or tourist kind of app where you need to populate your activity only with different content but in the same activity layout.

As an example we will use the Dutch Provinces, where each activity explains a bit of the history of the province. What will we do I in the tutorial
- Create ArrayAdapters for the ListView
- Pass Strings and Images to your next activity based on the item selected in your ListView
- Set the text of a button based on your item selected in your ListView
- Create a AlertDialog window in the next activity and populate content based on your ListView selection.
- Set a header image above the ListView

First I created the strings which we use as the content in our app example. In total I have two String Arrays. The first one containing the content which is populated in the different activities and the second String Array which is used to populate the dialog window.

I put them both in strings.xml as two separate Arrays. As the first array contains a lot of content I have put in this post some dummy content as otherwise the blog would blew up :)

<?xml version="1.0" encoding="utf-8"?>
<resources>
    
<string-array name="provincedescription">
   <item>North Holland is a broad peninsula.</item>
   <item>South Holland (Dutch: Zuid-Holland).</item>
   <item>Flevoland is a province of the Netherlands.</item>
   <item>Utrecht city and municipality </item>
   <item>Zeeland, also called Zealand in English</item>
   <item>North Brabant (Dutch: Noord-Brabant), since 2001 </item>
   <item>Gelderland English also</item>
   <item>Overijssel (Oaveriessel) is a province .</item>
   <item>Groningen  is the main </item>
   <item>Friesland or Frisia is a province in</item>
   <item>Limburg is the southernmost of the twelve.</item>
   <item>Drenthe is a province of the Netherlands.</item>
</string-array> 


<string-array name="dialogmessage">
    <item>North Holland is located in the North West of Holland</item>
    <item>South Holland is located in the South West of Holland</item>
    <item>Flevoland is located in the North - middle of Holland</item>
    <item>Utrecht is located in the middle of the Netherlands</item>
    <item>Zeeland is located in the South West of Holland</item>
    <item>North Brabant is located in the South middle of the Netherlands</item>
    <item>Gelderland is located in the East of Holland</item>
    <item>Overrijsel is located in the East of Holland</item>
    <item>Groningen is located in the North East of the Netherlands</item>
    <item>Friesland is located in the North of the Netherlands</item>
    <item>Limburg is located in the East South of the Netherlands</item>
    <item>Drenth is located a bit above the middel of the Netherlands</item>
</string-array>   
   
</resources>

Now open your activity_main.xml. In this activity layout we set a ListView widget.

Activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >
   
    <ListView
        android:id="@+id/lvProvinceNames"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true" >

    </ListView>

</RelativeLayout>

Now we have to create the activity layout when an item is selected in the ListView. What do we need?
- We want a title, to make things less complicated than needed we will use the item selected as the title in the activity
- We need an imageview which shows the flag of the province which is selected by the user
- We need a TextView which populates the String Array which we have defined in the Strings.xml
- We need a Button which will initiate the dialog or pop-up.
- Finally, we set our layout in a ScrollView as some of the content is quite large.

Note that I set a default Image in the ImageView (called Drenthe) but this as well as the Button text we will override programmatically later on with the Item selected in the ListView. This just helps a bit how the final design in XML looks like.

The detailActivity.xml should look like this:

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="400dp" >

    <TextView
        android:id="@+id/tvTitleLabel"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:padding="@dimen/padding10"
        android:text="Medium Text"
        android:textAppearance="?android:attr/textAppearanceMedium" />
    
     <ImageView
        android:id="@+id/ivPrvImage"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/tvTitleLabel"
        android:layout_alignParentLeft="true"
        android:layout_marginBottom="22dp"
        android:paddingLeft="@dimen/padding10"
        android:src="@drawable/drenthe" />

    <TextView
        android:id="@+id/tvDescLabel"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_below="@+id/ivPrvImage"
        android:paddingLeft="@dimen/padding10"
       	android:layout_gravity="fill_horizontal"
        android:text="TextView" />

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentLeft="true"
        android:paddingLeft="@dimen/padding10"
        android:layout_below="@+id/tvDescLabel"
        android:text="Button" />

</RelativeLayout>

</ScrollView>

We have one small thing we need to set in our layout work. As you can see there is a header on top of the ListView. This I have defined in the XML called listheader.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <ImageView
        android:id="@+id/imageView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/banner" 
        android:adjustViewBounds="true"/>

</LinearLayout>

Now we have done all the layout and content side of this demo app. Let’s get started with the Java classes.

In total we need to classes the ListView activity which is called MainActivity.java and the activity which loads the information based on the item selected in the ListView, we call that activity DetailActivity.java.

Lets start with the MainActivity.java.
- First we need to define an String Array which holds the items of our ListView. These are all 12 provinces of the Netherlands
- Second we need to define an Int Array holding all the 12 flags of each provinces.

—————-
Important to know is that the order in the Array is of great importance. The String Array we defined earlier has the exact same order as the order of our String and Integer Array. What do I mean with order? The text in the string, the flag and the name of the province should all belong to each other so we make sure that we see later one the correct flag and correct content which the correct selected province.
—————-

With findViewById you can set your ListView. Next you can use LayoutInflater to inflate the header image which we place on top of the ListView. We set as part of the ViewGroep and make the reference to the Layout. Finally we use AddHeaderView to set it. It passes 3 parameters. The first is the view (the variable we created called header), second, it can pass the object which we dont have in our case. And lastly, we set a clickable boolean at False.

We use ArrayAdapter to bind our provinces String list to the ListView and implement the OnClickListener.

We make two variables which get the position of the the item clicked

String province = provinces[position-1];
final int prvImg = myImageList[position-1];

So these two variables hold the position of the selected item in the ListView and get the position in the ArrayList. We dont need any ArrayList from our Strings.xml as we will re-use these in our next activity as the Title and Image.

—————-
Important note: as you can see we subtract 1 from the position. This is because the header is position 0. In case you dont have a header in place but just a plain simple ListView, than dont subtract 1.
—————-

We need to retrieve the content from the Strings.xml for the content in the activity and then also get the position which was selected by the user. This is the content for the dialog window and the TextView

//we retrieve the description of the juices from an array defined in arrays.xml
		String[] provincedescription = getResources().getStringArray(R.array.provincedescription);
        final String provincedesclabel = provincedescription[position-1];
        
        //retrieve content for the dialog
        String[] dialogmessage = getResources().getStringArray(R.array.dialogmessage);
        final String dialogmsg = dialogmessage[position-1];

So now we have everything, but still need to create an Intent to pass the content to the next activity. For each item we create an intent.putExtra passing a name (just pick one which you like, I kept things simply the same) and the bundle value, which are the variables we have just defined. Finally we start the Intent.

The complete MainActivity.java should look like this:

package com.christianpeeters.listview;



import android.os.Bundle;
import android.app.Activity;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.TextView;

public class MainActivity extends 	Activity {
	
	// ListView items
	 String[] provinces = new String[]{
	    		 "Noord-Holland",
	    		 "Zuid-Holland",
	    		 "Flevoland",
	    		 "Utrecht",
	    		 "Zeeland",
	    		 "Noord-Brabant",
	    		 "Gelderland",
	    		 "Overijssel",
	    		 "Groningen",
	    		 "Friesland",
	    		 "Limburg",
	    		 "Drente" 
	     };
	 // Images belonging to the ListView items
	 int[] myImageList = new int[]{
			 R.drawable.nordholland,
			 R.drawable.zuidholland,
			 R.drawable.flevoland,
			 R.drawable.utrecht,
			 R.drawable.zeeland,
			 R.drawable.nordbrabant,
			 R.drawable.gelderland,
			 R.drawable.overijssel,
			 R.drawable.groningen,
			 R.drawable.friesland,
			 R.drawable.limburg,
			 R.drawable.drenthe			 
	 };


	 
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    
       
     ListView provincelist = (ListView)findViewById(R.id.lvProvinceNames);

     //add header to listview
    LayoutInflater inflater = getLayoutInflater();
    ViewGroup header = (ViewGroup)inflater.inflate(R.layout.listheader, provincelist, false);
    provincelist.addHeaderView(header, null, false);
     
     	
     ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, provinces);
     provincelist.setAdapter(adapter);
     provincelist.setOnItemClickListener(new OnItemClickListener(){

	@Override
	public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
		// TODO Auto-generated method stub
		
		//we use the items of the listview as title of the next activity
		 String province = provinces[position-1];
		final int prvImg = myImageList[position-1];
		
			//we retrieve the description of the juices from an array defined in arrays.xml
			String[] provincedescription = getResources().getStringArray(R.array.provincedescription);
	        final String provincedesclabel = provincedescription[position-1];
	        
	        //retrieve content for the dialog
	        String[] dialogmessage = getResources().getStringArray(R.array.dialogmessage);
	        final String dialogmsg = dialogmessage[position-1];
        
        
        
        Intent intent = new Intent(getApplicationContext(), DetailActivity.class);
        intent.putExtra("province", province);
        intent.putExtra("provincedesclabel", provincedesclabel);
        intent.putExtra("prvImg", prvImg);
        intent.putExtra("dialogmsg", dialogmsg);

        startActivity(intent);
        
        
	}
	   
	   
   });
    
}
}

We have created the Intent, now we need to wat to actually receive the data in the new activity, without create 12 separate activities. Create a second java class in your project and call it DetailActivity.java. In this activity we will do a few things
- Create our reference to our android widgets (TextViews, images and Button)
- Create a bundle to receive the content belonging to the item selected and set them to the android widgets.
- Create on OnClickListener for the button which launch the dialog window.

package com.christianpeeters.listview;



import android.app.Activity;
import android.app.AlertDialog;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;

public class DetailActivity extends Activity {
	
	String title;
    String description;
    String dialoginformation;
    int image;
    	
	@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.detailactivity);
        
        TextView tvTitleLabel = (TextView)findViewById(R.id.tvTitleLabel);
        TextView tvDescLabel = (TextView)findViewById(R.id.tvDescLabel);
        ImageView ivPrImage = (ImageView)findViewById(R.id.ivPrvImage);
        Button btn = (Button)findViewById(R.id.button1);
        
        
        Bundle extras = getIntent().getExtras(); 
    
        if (extras != null) {
           
        	title = extras.getString("province");
            tvTitleLabel.setText(title);
            btn.setText("More about "+ title);
            dialoginformation = extras.getString("dialogmsg");
            
            image = extras.getInt("prvImg");
            ivPrImage.setImageResource(image);
        	
        	description = extras.getString("provincedesclabel");
            tvDescLabel.setText(description);
          
        }
        
        btn.setOnClickListener(new View.OnClickListener() {
			
			@Override
			public void onClick(View v) {
			
				
				AlertDialog.Builder dlgAlert = new AlertDialog.Builder(DetailActivity.this);
				dlgAlert.setMessage(dialoginformation);
                dlgAlert.setTitle(title);
                dlgAlert.setNegativeButton("close", null);
                dlgAlert.create().show();
			}
		});
        
}

}

That’s all, with the tutorial is showed how you pass data throughout your Android application based on items selected by the user without create numerous activities . In the next tutorial I will make the dialog a bit more custom as now it a bit boring :)

15 Responses

  1. sunny June 11, 2013 / 12:12 pm

    excellent tutorials

  2. Joe January 11, 2014 / 7:56 pm

    Nice tutorial. I’m a beginner in android
    Can you send me a download to the source code?

  3. MAURO JOSE CONTE January 28, 2014 / 1:04 pm

    Hello, Congratulations by content. I would like to receive the files for these examples, I am a graduate student and and have to learn fast and sobrer android. thank you

  4. MAURO JOSE CONTE January 28, 2014 / 1:06 pm

    Hello, congratulation pelo content. I would like to receive the files for these examples, I am a graduate student and and have to learn fast and sobrer android. thank you

  5. happy person April 2, 2014 / 2:30 pm

    You’re the best! This is EXACTLY what I needed!!!

  6. happy person April 2, 2014 / 5:03 pm

    Oh, one thing, I think in your detailActivity.xml you repeat “xmlns:android=”http://schemas.android.com/apk/res/android” twice. Is that an error?

  7. Adam April 25, 2014 / 1:27 am

    I have spent days browsing the internet to find exactly how you bring content over from a clicked listview item into another activity and display the information! Thank you so much Christian! University deadline coming up! Exactly what I needed! Dank je!

  8. Tony June 8, 2014 / 7:53 pm

    Post source code,please.

  9. Sarah August 26, 2014 / 4:52 am

    Thank you for sharing this code Christian! I’m just having a little problem when I acquired your code. Whenever I run and click an Item in the Listview, I always get “Unfortunately, blablah has stopped working” instead of proceeding into a new Activity. What do you guys think is the problem? I’m new in developing an android app. Need this code working asap. Thanks in advance!

  10. Muhammad Hussain February 26, 2015 / 7:26 am

    I need the same tutorial but it should be from mysql db using json

  11. C Won March 30, 2015 / 3:02 pm

    thank you very much for the tutorial!

  12. hiro July 11, 2015 / 3:55 am

    Geat! I am new with android, looking for something like this. When clicking on one item in the lisview screen, it goes to another activity(e.g. a second activity) with a pic and some text. Also, you can recycle the second activity layout for other screens. So you don’t have to creat many activities. That is What I need although it looks a little complicating.
    Would you please send me the source code? I will appreciate you for your kindness forever!

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

*