Android Gridview Example- Building Image Gallery in android

1. Introduction

GridView is a ViewGroup that displays items in a two-dimensional, scrollable grid. In this tutorial, we will build an image gallery using Android GridView. Each grid in our example will display an image and a text tile.

When user clicks on any grid item, it will navigate user to the details page. The output of the example we will build is depicted in following image.

Android GridView Example

 

2. Adding GridView layout

To begin with, let us create a layout for activity that contains a GridView. Let us create a new file named activity_main.xml in your application layout folder.

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#f0f0f0">

    <GridView
        android:id="@+id/gridView"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_margin="5dp"
        android:columnWidth="100dp"
        android:drawSelectorOnTop="true"
        android:gravity="center"
        android:numColumns="auto_fit"
        android:stretchMode="columnWidth"
        android:verticalSpacing="5dp"
        android:focusable="true"
        android:clickable="true"/>

</RelativeLayout>

Notice that in the above code, we have added a GridView with id gridView, and used some of the attributes such as numColumns, stretchMode, verticalSpacing, etc. Most of the android attributes are self explanatory.

3. Define grid item layout

As you can notice from the above screenshot, each of the grid item contains an ImageView and an TextView. The following listing will show you the layout for each grid cell item. This layout will be used by the GridView adapter to render the items. Create a new layout inside your project layout directory and name it as grid_item_layout.xml.

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginTop="5dp"
    android:background="@drawable/grid_color_selector"
    android:orientation="vertical"
    android:padding="5dp">

    <ImageView
        android:id="@+id/image"
        android:layout_width="100dp"
        android:layout_height="100dp" />

    <TextView
        android:id="@+id/text"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="5dp"
        android:gravity="center"
        android:textSize="12sp" />

</LinearLayout>

4. Creating GridView adapter

Adapter is acts as a bridge between data source and adapter views such as ListView, GridView. Adapter iterates through the data set from beginning till the end and generate Views for each item in the list.

Android SDK provides three different Adapter implementation, that includes ArrayAdapter, CursorAdapterand SimpleAdapter. An ArrayAdapter expects an Array or an List as input, while CursorAdapter accepts the instance of Cursor and SimpleAdapter maps the static data defined in the resources. The type of adapter that suits your app need is purely based on the input data type.

The BaseAdapter is the generic implementation for all of the three adapter types and can be used for ListView, GridView or for Spinners. You may directly use ArrayAdapter by passing array as input or create your own customized class by extending BaseAdapter.

Let us not proceed with creating a custom adapter for grid view by extending ArrayAdapter. Create a new class GridViewAdapter.java in in your application src directory.

public class GridViewAdapter extends ArrayAdapter {
	private Context context;
	private int layoutResourceId;
	private ArrayList data = new ArrayList();

	public GridViewAdapter(Context context, int layoutResourceId, ArrayList data) {
		super(context, layoutResourceId, data);
		this.layoutResourceId = layoutResourceId;
		this.context = context;
		this.data = data;
	}

	@Override
	public View getView(int position, View convertView, ViewGroup parent) {
		View row = convertView;
		ViewHolder holder = null;

		if (row == null) {
			LayoutInflater inflater = ((Activity) context).getLayoutInflater();
			row = inflater.inflate(layoutResourceId, parent, false);
			holder = new ViewHolder();
			holder.imageTitle = (TextView) row.findViewById(R.id.text);
			holder.image = (ImageView) row.findViewById(R.id.image);
			row.setTag(holder);
		} else {
			holder = (ViewHolder) row.getTag();
		}

		ImageItem item = data.get(position);
		holder.imageTitle.setText(item.getTitle());
		holder.image.setImageBitmap(item.getImage());
		return row;
	}

	static class ViewHolder {
		TextView imageTitle;
		ImageView image;
	}
}

The getView() method implementation is necessary, it is responsible for creating a new View for each grid item. When this is called, a View is passed in, which is normally a recycled object, so there’s a check to see if the object is null. If it is null, an ViewHolder is instantiated and configured for holding an ImageView and a TextView. ViewHolder design patterns are efficient while using composite layouts.

Notice that the above adapter is working on a ImageItem pojo Class. Create a new class for ImageItem and add the following code snippets.

public class ImageItem {
	private Bitmap image;
	private String title;

	public ImageItem(Bitmap image, String title) {
		super();
		this.image = image;
		this.title = title;
	}

	public Bitmap getImage() {
		return image;
	}

	public void setImage(Bitmap image) {
		this.image = image;
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}
}

5. Setting adapter to GridView

Now we are almost ready to hook up grid view on activity. In our activity we will initialize the GridView by calling findViewById(int) method. This method takes the same id as provided in the layout xml file. The setAdapter() method then sets a custom adapter (GridViewAdapter) as the source for all items to be displayed in the grid.

public class MainActivity extends ActionBarActivity {
    private GridView gridView;
    private GridViewAdapter gridAdapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        gridView = (GridView) findViewById(R.id.gridView);
        gridAdapter = new GridViewAdapter(this, R.layout.grid_item_layout, getData());
        gridView.setAdapter(gridAdapter);
    }

    // Prepare some dummy data for gridview
    private ArrayList<ImageItem> getData() {
        final ArrayList<ImageItem> imageItems = new ArrayList<>();
        TypedArray imgs = getResources().obtainTypedArray(R.array.image_ids);
        for (int i = 0; i < imgs.length(); i++) {
            Bitmap bitmap = BitmapFactory.decodeResource(getResources(), imgs.getResourceId(i, -1));
            imageItems.add(new ImageItem(bitmap, "Image#" + i));
        }
        return imageItems;
    }
}

Note that in this example, we are using the static data and image defined in strings.xml file. All the images used in this example is available for download. Visit download section to get the complete project source code.

At this point we can run the application and and can see the grid view in action.

6. Handling GridView click action

When user click on any grid item, we have to take user to details activity by passing the image and title of the grid item clicked. To do this we can call setOnItemClickListener() method by passing the instance of OnItemClickListener.

gridView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
	ImageItem item = (ImageItem) parent.getItemAtPosition(position);
	//Create intent
	Intent intent = new Intent(MainActivity.this, DetailsActivity.class);
	intent.putExtra("title", item.getTitle());
	intent.putExtra("image", item.getImage());

	//Start details activity
	startActivity(intent);
}

Learn  more about passing data from one activity to another here.

7. Customizing GridView style

We are pretty much good with the GridView gallery, let us do some customization such as changing the background color of a grid item while user is clicks.

For this, let us define a color selector grid_color_selector.xml and place it inside drawable folder. We can use a selector with grid_row.xml layout file by using android:background attribute.

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@color/blue" android:state_pressed="true"/>
    <item android:drawable="@color/blue" android:state_selected="true"/>
    <item android:drawable="@color/white"/>
</selector>

8. Creating details activity

Create a new layout file named details_activity.xml. This will be used for the layout for my DetailsActivity.

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

    <ImageView
        android:id="@+id/image"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_gravity="center"
        android:scaleType="fitCenter" />

    <TextView
        android:id="@+id/title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom"
        android:background="#00000c"
        android:padding="10dp"
        android:textColor="#fff"
        android:textSize="20dp" />
</FrameLayout>

The above layout is quite simple with an ImageView for displaying full sized image and TextView for displaying the title. Now let us crete DetailsActivity and use the above layout to display the selected image.

public class DetailsActivity extends ActionBarActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.details_activity);

        String title = getIntent().getStringExtra("title");
        Bitmap bitmap = getIntent().getParcelableExtra("image");

        TextView titleTextView = (TextView) findViewById(R.id.title);
        titleTextView.setText(title);

        ImageView imageView = (ImageView) findViewById(R.id.image);
        imageView.setImageBitmap(bitmap);
    }
}

Well, we have now completed the whole exercise to build image gallery using Android GridView. If you find any problem, or something is missing, you can download code and compare your code with mine.

9. Download Complete Example

Download complete example source code Download Code

A blogger, speaker, author, a bit of tech freak and a software developer. He is a thought leader in the fusion of design and mobile technologies. He has over 8 years of experience in developing rich mobile applications in Android, HTML5, Xamarin and PhoneGap.

  • Nilanchala Panigrahy

    Checkout the tutorial. Updated with details activity.

  • Nilanchala Panigrahy
  • Nilanchala Panigrahy

    Will fix it soon. for now checkout the link

    https://github.com/javatechig/Android-GridView-Example

  • anonymous

    how to open a new activity on clicking an image item in the grid view? Can you give me the explanation?

    • Nilanchala Panigrahy

      Checkout the example. Updated exactly what you looking for.

  • Nilanchala Panigrahy

    You have to create another activity and pass bitmap id to your details activity. In details activity get the bundle data and render on image view. Checkout similar example

    How to pass a data from one Activity to another in Android example

    • Fabio Cerutti

      how do I put a name instead of Imaga # 1 Image # 2 ….?

      • Nilanchala Panigrahy

        Define another string array in your arrays.xml or strings.xml. It should be same length as image_ids array.

        Item 1
        Item 2
        Item 3
        Item 4
        Item 5
        Item 6
        Item 7
        Item 8
        Item 9
        Item 1
        Item 2
        Item 3
        Item 4
        Item 5
        Item 6
        Item 7
        Item 8
        Item 9

        And do the following changes to getData() method.

        private ArrayList getData() {
        final ArrayList imageItems = new ArrayList();
        String[] itemsArray = getResources().getStringArray(R.array.testArray);

        TypedArray imgs = getResources().obtainTypedArray(R.array.image_ids);
        for (int i = 0; i < imgs.length(); i++) {
        Bitmap bitmap = BitmapFactory.decodeResource(this.getResources(), imgs.getResourceId(i, -1));
        imageItems.add(new ImageItem(bitmap, itemsArray[i]));
        }
        return imageItems;
        }

        Note: I have not tested this code. But should work fine.

  • Nilanchala Panigrahy

    Define this array in your strings.xml file or arrays.xml. Checkout my code here

    https://github.com/javatechig/Android-UI-Tutorials/blob/master/AndroidCustomGridView/res/values/arrays.xml

    @drawable/image_1
    @drawable/image_2
    @drawable/image_3
    @drawable/image_4
    @drawable/image_5
    @drawable/image_6
    @drawable/image_7
    @drawable/image_8
    @drawable/image_9
    @drawable/image_1
    @drawable/image_2
    @drawable/image_3
    @drawable/image_4
    @drawable/image_5
    @drawable/image_6
    @drawable/image_7
    @drawable/image_8
    @drawable/image_9

  • http://emergingandroidtech.blogspot.in Shriyanshu Jain

    Nice Example Thank you.

  • Ana Fernandez Ruiz

    thanks a lot, very useful

  • http://javatechig.com/ JavaTechig

    Check out the below code snippets to create array adapter and set it to listview. You can do the requirement adjustments.

    // context – The current context.
    // resource – The resource ID for a layout file containing a layout
    // to use when instantiating views.
    // From the third parameter, you plugged the data set to adapter
    arrayAdapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, monthsArray);

    // By using setAdapter method, you plugged the ListView with adapter
    monthsListView.setAdapter(arrayAdapter);

  • kads

    how i remove the errors ?

    • http://javatechig.com/ JavaTechig

      import the following packages. Put after package declaration.

      import java.util.ArrayList;
      import android.app.Activity;
      import android.content.Context;
      import android.view.LayoutInflater;
      import android.view.View;
      import android.view.ViewGroup;
      import android.widget.ArrayAdapter;
      import android.widget.ImageView;
      import android.widget.TextView;

    • Nilanchala Panigrahy

      Download the code and compare to see if you missing something

  • Manish

    How to set image to another activity’s imageview when any clicked from GridView

  • http://javatechig.com/ javatechig

    GridView doesn’t support header and footer by default. You have to make your own workaround.

    You may use below example

    https://github.com/munix/GridViewHeader

  • Junior Vansuita

    For highlight the item on selected inside the grid view.

    It’s do the magic:

    @Override
    public void onItemClick(AdapterView parent, View view, int position, long id) {
    view.setSelected(true);
    //mainFrag.getFittingViewFragment().addNewProductImage(adapter.getItem(position));
    }

    Set the item view selected programmatically in onItemClick event of grid view.

    No android:clickable=”true” and android:focusable=”true” is nedded.

  • abg macho

    i have question if i already put tab navigation so how put slide image on certain tab when user finger on it either left or right

  • Justin McMurray

    Great example, thank you! I downloaded the source from GitHub today and only had the one issue described below – onItemClick in MainActivity.java wasn’t working for me. When I clicked on an item, I would not get the floating window (Toast) on my android 4.4 device. Here is the fix that worked for me:

    in row_grid.xml change:
    android:clickable=”true”
    android:focusable=”true”
    to:
    android:clickable=”false”
    android:focusable=”false”

    • http://javatechig.com/ javatechig

      Thanks for sharing the solution Justin.

  • shivam

    can u guys please help , how to make image bigger when touched

    • http://javatechig.com/ javatechig

      You probably extend this example for your requirement.

    • Rokhsareh

      Have you found how to do this?! could you please help me with it?
      Many thanks

  • shivam

    hello , how to add more images , i have tried adding images in drawable folder, but the problem is only few images that i added can be seen , not all the images, plus when i click on images nothing happened how to make them big like as in our android phones, please help i am a beginner

  • Raviteja Nandula

    I used this inside onclick listener this might help

    Object o = gridView.getItemAtPosition(position);

    ImageItem i = (ImageItem)o;

    customGridAdapter.remove(i);

    i.setTitle(“selected”);

    customGridAdapter.insert(i, position);

    customGridAdapter.notifyDataSetChanged();

  • Raviteja Nandula

    Hi there

    I have tried every thing but i tried this for color

    But when i click the image i am able to see toast message but unable to set the value as selected

    How to make it as selected using onclicklistener

  • usman

    Solution for me ……just add these in row_grid.xml.
    android:clickable=”false”
    android:focusable=”false”
    android:focusableInTouchMode=”false”>

  • Mischa Brammer

    Same probleme here. Nothing in the logs. Please give some help.

  • Matrix Sourcing

    Hi .. onclicklistener is not working for me .. no error/warning .. have also tried using

    android:focusable=”false”
    android:focusableInTouchMode=”false”

    on grid view and true on grid row …

    any help ??????

  • atomnet

    Hello,
    can i use this tutorial for loading image from my site? How?

    Thanks.

  • Don Tharaka

    Thanks for the great tutorial, the solution for click is adding these two lines in the :

    android:focusable=”false”
    android:focusableInTouchMode=”false”

    in row_grid.xml

  • Sasa

    I have the same problem and i don’t solve yet…

  • Nilanchala Panigrahy

    Anything you see in the logs? or any crashes?