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:

  1. 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.. :)

    ReplyDelete
  2. hello Welly Pamungkas,

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

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

    ReplyDelete
  3. 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

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

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

    ReplyDelete
  5. 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

    ReplyDelete
  6. 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.

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

    ReplyDelete
  8. 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?

    ReplyDelete
  9. 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

    ReplyDelete
  10. 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.

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

    ReplyDelete
  12. 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

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

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



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

    ReplyDelete
  15. i have problem with code the app will not run

    ReplyDelete