Wednesday, December 26, 2012

Implement OnItemClickListener for GridView

My previous post describe how to implement "GridView loading photos from SD Card". Now we implement OnItemClickListener for the GridView, to display the clicked image path.

OnItemClickListener for GridView


Implement OnItemClickListener, to override onItemClick() method. To retrieve the clicked item  in onItemClick() method, call parent.getItemAtPosition(position).

We also have to modify getItem() method of ImageAdapter class, to return the item in our expected format. In this exercise, string of the file path is return.

package com.example.androidgridview;

import java.io.File;
import java.util.ArrayList;

import android.os.Bundle;
import android.os.Environment;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.Toast;

public class MainActivity extends Activity {

    public class ImageAdapter extends BaseAdapter {
     
     private Context mContext;
     ArrayList<String> itemList = new ArrayList<String>();
     
     public ImageAdapter(Context c) {
      mContext = c; 
     }
     
     void add(String path){
      itemList.add(path); 
     }

  @Override
  public int getCount() {
   return itemList.size();
  }

  @Override
  public Object getItem(int position) {
   // TODO Auto-generated method stub
   return itemList.get(position);
  }

  @Override
  public long getItemId(int position) {
   // TODO Auto-generated method stub
   return 0;
  }

  @Override
  public View getView(int position, View convertView, ViewGroup parent) {
   ImageView imageView;
         if (convertView == null) {  // if it's not recycled, initialize some attributes
             imageView = new ImageView(mContext);
             imageView.setLayoutParams(new GridView.LayoutParams(220, 220));
             imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
             imageView.setPadding(8, 8, 8, 8);
         } else {
             imageView = (ImageView) convertView;
         }

         Bitmap bm = decodeSampledBitmapFromUri(itemList.get(position), 220, 220);

         imageView.setImageBitmap(bm);
         return imageView;
  }
  
  public Bitmap decodeSampledBitmapFromUri(String path, int reqWidth, int reqHeight) {
   
   Bitmap bm = null;
   // First decode with inJustDecodeBounds=true to check dimensions
   final BitmapFactory.Options options = new BitmapFactory.Options();
   options.inJustDecodeBounds = true;
   BitmapFactory.decodeFile(path, options);
       
   // Calculate inSampleSize
   options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
       
   // Decode bitmap with inSampleSize set
   options.inJustDecodeBounds = false;
   bm = BitmapFactory.decodeFile(path, options); 
       
   return bm;   
  }
  
  public int calculateInSampleSize(
    
   BitmapFactory.Options options, int reqWidth, int reqHeight) {
   // Raw height and width of image
   final int height = options.outHeight;
   final int width = options.outWidth;
   int inSampleSize = 1;
   
   if (height > reqHeight || width > reqWidth) {
    if (width > height) {
     inSampleSize = Math.round((float)height / (float)reqHeight);    
    } else {
     inSampleSize = Math.round((float)width / (float)reqWidth);    
    }   
   }
   
   return inSampleSize;    
  }
  
 }
    
    ImageAdapter myImageAdapter;

 @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        GridView gridview = (GridView) findViewById(R.id.gridview);
        myImageAdapter = new ImageAdapter(this);
        gridview.setAdapter(myImageAdapter);
        
        String ExternalStorageDirectoryPath = Environment
          .getExternalStorageDirectory()
          .getAbsolutePath();
        
        String targetPath = ExternalStorageDirectoryPath + "/test/";
        
        Toast.makeText(getApplicationContext(), targetPath, Toast.LENGTH_LONG).show();
        File targetDirector = new File(targetPath);
        
        File[] files = targetDirector.listFiles();
        for (File file : files){
         myImageAdapter.add(file.getAbsolutePath()); 
        }
        
        gridview.setOnItemClickListener(myOnItemClickListener);
        
    }
 
 OnItemClickListener myOnItemClickListener
 = new OnItemClickListener(){

  @Override
  public void onItemClick(AdapterView<?> parent, View view, int position,
    long id) {
   String prompt = (String)parent.getItemAtPosition(position);
   Toast.makeText(getApplicationContext(), 
     prompt, 
     Toast.LENGTH_LONG).show();
   
  }};

}


download filesDownload the files.

Next: GridView example: load images to GridView from SD Card

17 comments:

Unknown said...

i have 2 question..

First:
how to get the path of a selected image along with the name of the picture?
for example:
/mnt/sdcard/DCIM/test/myimage.jpg

Second:
when I use the cursor, I can sort the photos to be displayed into the gridview.
for example:
OrderBy=MediaStore.Images.Media.DATE_TAKEN;
cursor = managedQuery (MediaStore.Images.Media.EXTERNAL_CONTENT_URI,projection,MediaStore.Images.Media.DATA + "like?"
new String [] {"%test%"},
OrderBy);

i hope u will answer me..
Thank you very much.. :)

Erik said...

hello Welly Pamungkas,

- parent.getItemAtPosition(position) is what you want.

- For the second, I don't understand your question. Sorry.

Unknown said...

hi can you tell that in what API is the code compatible because i cannot run it in my emulator of API 8
Secondly im storeing some images in my emulator SDCARD (on run time)so what and where shall i give the path in your code so that it can fetch those images once im able to run your code
Thanks in advance

Erik said...

In this exercise, minSdkVersion="12" and targetSdkVersion="15".

I'm not sure when is the SDCARD mounted on emulator.

Unknown said...

Thnkx for the reply
When using Eclipse there is a DBMS icon when we click there come and android icon mostly on the left lower bottom of the screen when we click it File explorer opens above it and by clicking on the sdcard folder we can push files and images over the emulator
I want to set the path of that folder
Kindly can u help

Erik said...

hello Omer Cheema,

I haven't test on Emulator for a long time, my PC run it super slow!!!

Do the Gallery App installed in Android Emulator? If yes, I guess you can open it to view your images, and details, so you can know where it save.

Hope can help.

Unknown said...

How would you clear the GridView? Everything I try throws an array out of bounds when I clear the Array List

Erik said...

hello Sean Turtle,

are u run in background thread?

Please read GridView example: load images to GridView from SD Card in background.

Anonymous said...

Hi Eric, need some advise here.
There was a print in the Logcat when i run in actual Samsung device.

- Not a DRM file, opening normally
- buffer returned

Any ideal to solve it?

Erik said...

hello,

Is it Info? I think you can simple ignore it. "Not a DRM file, opening normally" means normal, ok...

DRM (Digital Rights Management) is a technology that enables content providers to distribute digital contents in a secure way.

To know more about DRM, read:
android.drm
DRM in Android from Samsung

Anonymous said...

I have a Question:
How to enlarge a selected image ?
Pls explain in simple language or paste the code as i am new to android coding.

Erik said...

what you means enlarge the image? enlarge the resized image? or load the original un-resized image?

Anonymous said...

Hello Eric,
Thank you for the code.
It works, so it's excellent
I recommend to change "/test" string to "/",
otherwise crash occurs. And you old code without onClickListner does not make sense now. You can unpublish it. But this code very valuable.
Thanks again.
Niaz

Sachindra N. Pandey said...

Excellent *****..
I was really fed up...u did good job bro...Thanks a ton

Anonymous said...

Excellent Job Dude

Anonymous said...

Nice work. In newer versions of Android (>=5.0 I believe) you need to add



to the manifest, otherwise you won't see anything.

Anonymous said...

i have problem with code the app will not run