Contents
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.
Checkout the advance version of this tutorial, that downloads the data from server and displays it on GridView.
Download and Display Image in Android GridView
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.
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
, CursorAdapter
and 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.
Anything you see in the logs? or any crashes?
I have the same problem and i don’t solve yet…
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
Hello,
can i use this tutorial for loading image from my site? How?
Thanks.
You may look at the below post. which very much explains the same as your need.
http://stacktips.com/android/json-feed-reader-in-android/
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 ??????
Same probleme here. Nothing in the logs. Please give some help.
Solution for me ……just add these in row_grid.xml.
android:clickable=”false”
android:focusable=”false”
android:focusableInTouchMode=”false”>
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
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();
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
can u guys please help , how to make image bigger when touched
You probably extend this example for your requirement.
Have you found how to do this?! could you please help me with it?
Many thanks
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”
Thanks for sharing the solution Justin.
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
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.
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
How to set image to another activity’s imageview when any clicked from GridView
just pass the url from Activity1 to Activity2. And use some image download/cache lib like PIcasso to download the image. This will prevent you to download again from internet. Checkout the example below
http://stacktips.com/android/how-to-use-picasso-library-in-android
how i remove the errors ?
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;
Download the code and compare to see if you missing something
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);
thanks a lot, very useful
Nice Example Thank you.
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
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
how do I put a name instead of Imaga # 1 Image # 2 ….?
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.
how to open a new activity on clicking an image item in the grid view? Can you give me the explanation?
Checkout the example. Updated exactly what you looking for.
Will fix it soon. for now checkout the link
https://github.com/javatechig/Android-GridView-Example
https://github.com/javatechig/Android-GridView-Example
Checkout the tutorial. Updated with details activity.
Checkout this example,
http://stacktips.com/android/listing-all-sdcard-filenames-with-extensions-in-android
Thank you so much!
Currently it takes the length of the array as defined in strings.xml. You may change this logic to either display data from db or form server, depanding on your app requirements.
@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
You may use Universal Image Loader or Picasa library.. Checkout following examples
http://stacktips.com/android/universal-image-loader-library-in-android
http://stacktips.com/android/how-to-use-picasso-library-in-android
It works perfectly fine when i compile the code. Can you share the error log?
The error he was talking about would probably be:
E/JavaBinder﹕ !!! FAILED BINDER TRANSACTION !!!
And the solution for that could probably be with how changes are serialized. What I mean to say is the bitmap that you are passing is probably overflowing the (incredibly small) bundle. Compress the bitmap and that might just solve it.
Checkout another example, that downloads the data from server and displays the details on a GridView. It is the extension of this tutorial.
Download and Display Image in Android GridView
how can i get out from this???
Just put a null check condition in your Adapter getCount() method.
Sorry my above reply won’t help..
The above error can be due to passing null object into ArrayList. Please check you initialize the list.
use getActivity() as you are using fragment you need to access the rootView
I need this for another activity, how can i do without having duplicated errors?
hi, did you find out how to change the names of image# 1 image# 2…
The following link will help you
http://stacktips.com/android/download-and-display-image-in-android-gridview
how to fix this, I only tried to replace with my image??
Where should I put grid_row.xml file?
should I put it in drawable folder?
put it inside res/layout folder.
It didn’t help..:(
Can you give me the code of grid_row.xml file?
Bcoz it is not there in that download..
Complete project source code is here
Where???
Thank you for this very useful tutorial. But I have a problem when pressing on image, i get error: E/JavaBinder﹕ !!! FAILED BINDER TRANSACTION !!! Could you say me how to fix it?
i had the same issue..!!!but now i got cleared by reduce the image size.
Thank you for this very useful tutorial. But I have a problem when pressing on image, i get error: E/JavaBinder﹕ !!! FAILED BINDER TRANSACTION !!! Could you say me how to fix it?
how to display images from phone gallery.? can you show a tutorial on this.?
Intent i = new Intent(
Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
I THINK THIS SHOULD BE LILL DEMO FOR IT!!
Thank you..its works fine. if any one get error to another activity from grid view then try to reduce the image size.
Hello, I download your code on github and I install the app on my phone. I have a litlle problem : when I click on an image, either it does nothing, either it closes the app. Do you know why ? It should launch the detailactivity…
I changed the images to smaller ones and it works fine…
Nilanchala – Thanks for the tutorial.
Happy that it helped you.
I don’t get what is your question. If you want to use fragment instead of activity, youre free to go.
It is little effort to do so.
i created the GridViewAdapter class in scr directory. then why its again and again giving comments for create class.??
i created the GridViewAdapter class in scr directory. then why its again and again giving comments for create class.??please help
when i click on image in gridview the app will become closed
Yeah I got it very simple but I face the real problem here in performance.
Skipped 431 frames! The application may be doing too much work on its main thread.
Skipped 160 frames! The application may be doing too much work on its main thread.
Could you please edit your code so that the performance will be optimized. I tried it but I cannot figure out where I am wrong. Please fix this.
without this gridview my app is skipping frames but I am doing AsyncTask in background still don’t know why
after image_3 app gonna crashed ? why
FAILED BINDER TRANSACTION!!
help me
help me
Hi, I’m trying to prepare gridview photos but what I need,
in on click display layout 3 line text with image;
1-name
2-ingredient
3-prep.
is this possible. I’m new on android and really I got lost in titles, getter, setter, holders.
Please help. 🙁