Jun 14, 2012

Display photos from SD in android.widget.Gallery

Last example demonstrate how to "Implement custom dialog to open folder". The photos in the selected folder will be loaded in a custom adapter to display in Gallery widget.

Display photos from SD in Gallery widget


The layout of the dialog is same as previous example, refer dialoglayout.xml in "Implement custom dialog to open folder".

Modify main.xml, to add <Gallery>.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="@string/hello" />
    
    <Gallery
        android:id="@+id/photobar"
        android:layout_width="fill_parent"
        android:layout_height="200px" />
 
    <Button
        android:id="@+id/opendialog"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Load Folder" />
    <TextView
        android:id="@+id/jpglist"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"/>

</LinearLayout>


Modify AndroidGalleryActivity.java.

In order to reduce the resource need to keep the bitmaps, we have to implement a new class PhotoItem hold the path of individual jpg file, and the re-sized bitmap. And a custom BaseAdapter, PhotoBarAdapter, for PhotoItem is implemented for the Gallery.

package com.AndroidGallery;

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

import android.R.color;
import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.webkit.MimeTypeMap;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.Gallery;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

public class AndroidGalleryActivity extends Activity {
 
 Gallery photoBar;
 
 Button buttonOpenDialog;
 Button buttonUp, buttonSelectFolder;
 TextView jpgList;
   
 String KEY_TEXTPSS = "TEXTPSS";
 static final int CUSTOM_DIALOG_ID = 0;
 
 ListView dialog_ListView;
 
 File root;
 File curFolder;
 
 private List<String> fileList = new ArrayList<String>();
 
 class PhotoItem{
  
  String bitmapImageSrc;
  Bitmap bitmapImage = null;
  
  final static int itemWidth = 150;
  final static int itemHeight = 150;
  
  public PhotoItem(String src){
   bitmapImageSrc = src;
   bitmapImage = resize();
  }
  
  public Bitmap getImage(){
   return bitmapImage; 
  }
  
  private Bitmap resize(){
   BitmapFactory.Options bmpFactoryOptions = new BitmapFactory.Options();
   bmpFactoryOptions.inJustDecodeBounds = true;

   Bitmap bitmap = BitmapFactory.decodeFile(bitmapImageSrc, bmpFactoryOptions);
   
   int heightRatio = (int)Math.ceil(bmpFactoryOptions.outHeight/(float)itemHeight);
   int widthRatio = (int)Math.ceil(bmpFactoryOptions.outWidth/(float)itemWidth);
   
   if (heightRatio > 1 || widthRatio > 1)
   {
    if (heightRatio > widthRatio){
     bmpFactoryOptions.inSampleSize = heightRatio; 
    } else {
     bmpFactoryOptions.inSampleSize = widthRatio;  
    }  
   }
             
   bmpFactoryOptions.inJustDecodeBounds = false;
   
   bitmap = BitmapFactory.decodeFile(bitmapImageSrc, bmpFactoryOptions);
   
   return bitmap; 
  }
 }
 
 PhotoBarAdapter myPhotoBarAdapter;
 
 public class PhotoBarAdapter extends BaseAdapter {
  
  Context context;
  ArrayList<PhotoItem> arrayPhotoItem;

  
  PhotoBarAdapter(Context c){
      context = c;
      arrayPhotoItem = new ArrayList<PhotoItem>();    
  }
  
  public void clear(){
   arrayPhotoItem.clear();
  }
  
  public void addPhotoItem(PhotoItem item){
   arrayPhotoItem.add(item);    
  }
  
  @Override
  public int getCount() {
   return arrayPhotoItem.size();
  }

  @Override
  public Object getItem(int position) {
   return arrayPhotoItem.get(position);
  }

  @Override
  public long getItemId(int position) {
   return position;
  }

  @Override
  public View getView(int position, View convertView, ViewGroup parent) {
   
   LinearLayout viewLayout = new LinearLayout(context);
   viewLayout.setLayoutParams(new Gallery.LayoutParams(200, 200));
   viewLayout.setBackgroundColor(color.background_light);
   
   ImageView imageView;
   imageView = new ImageView(context);
   imageView.setLayoutParams(new Gallery.LayoutParams(150, 150));
   imageView.setScaleType(ImageView.ScaleType.CENTER_CROP);
   imageView.setImageBitmap(arrayPhotoItem.get(position).getImage());
   //return imageView;
   
   viewLayout.addView(imageView);
   return viewLayout;
  }
  
 }
 
 /** Called when the activity is first created. */
 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);
  
  photoBar = (Gallery)findViewById(R.id.photobar);
  myPhotoBarAdapter = new PhotoBarAdapter(this);
  photoBar.setAdapter(myPhotoBarAdapter);
   
  jpgList = (TextView)findViewById(R.id.jpglist);
   
  buttonOpenDialog = (Button)findViewById(R.id.opendialog);
  buttonOpenDialog.setOnClickListener(new Button.OnClickListener(){
   @Override
   public void onClick(View arg0) {
    showDialog(CUSTOM_DIALOG_ID); 
   }});
   
  root = new File(Environment
    .getExternalStorageDirectory()
    .getAbsolutePath());
   
  curFolder = root;
  //ListJpgInFolder(curFolder);
  preparePhotoBarInFolder(curFolder);
   
 }
  
 @Override
 protected Dialog onCreateDialog(int id) {
   
  Dialog dialog = null;
   
  switch(id) {
  case CUSTOM_DIALOG_ID:
   dialog = new Dialog(AndroidGalleryActivity.this);
   dialog.setContentView(R.layout.dialoglayout);
   dialog.setTitle("Select JPG");
    
   dialog.setCancelable(true);
   dialog.setCanceledOnTouchOutside(true);
    
   buttonUp = (Button)dialog.findViewById(R.id.up);
   buttonUp.setOnClickListener(new OnClickListener(){
     
    @Override
    public void onClick(View v) {
     // TODO Auto-generated method stub
     ListDir(curFolder.getParentFile()); 
    }});
   
   buttonSelectFolder = (Button)dialog.findViewById(R.id.selectfolder);
   buttonSelectFolder.setOnClickListener(new OnClickListener(){
    
   @Override
   public void onClick(View v) {
    // TODO Auto-generated method stub
    Toast.makeText(AndroidGalleryActivity.this,
      curFolder + " selected",
      Toast.LENGTH_LONG).show();
    dismissDialog(CUSTOM_DIALOG_ID);
    
    //ListJpgInFolder(curFolder);
    preparePhotoBarInFolder(curFolder);

   }});
   
    
   //Prepare ListView in dialog
   dialog_ListView = (ListView)dialog.findViewById(R.id.dialoglist);
    
   dialog_ListView.setOnItemClickListener(new OnItemClickListener(){
     
    @Override
    public void onItemClick(AdapterView<?> parent, View view,
      int position, long id) {
     File selected = new File(fileList.get(position));
     if(selected.isDirectory()){
      ListDir(selected);  
     } 
    }});
        
   break;
  }
  return dialog; 
 }
  
 @Override
 protected void onPrepareDialog(int id, Dialog dialog, Bundle bundle) {
  // TODO Auto-generated method stub
  super.onPrepareDialog(id, dialog, bundle);
   
  switch(id) {
  case CUSTOM_DIALOG_ID:
   ListDir(curFolder);
   
   break; 
  } 
 }
  
 void ListDir(File f){
   
  if(f.equals(root)){
   buttonUp.setEnabled(false); 
  }else{
   buttonUp.setEnabled(true); 
  }
   
  curFolder = f;
  buttonSelectFolder.setText("Select Folder " + curFolder);
   
  File[] files = f.listFiles();
  fileList.clear();
  for (File file : files){
   if(file.isDirectory()){
    fileList.add(file.getPath()); 
   }else{
    Uri selectedUri = Uri.fromFile(file);
    String fileExtension
     = MimeTypeMap.getFileExtensionFromUrl(selectedUri.toString());
    if(fileExtension.equalsIgnoreCase("jpg")){
     fileList.add(file.getName()); 
    } 
   } 
  }
   
  ArrayAdapter<String> directoryList
   = new ArrayAdapter<String>(this,
     android.R.layout.simple_list_item_1, fileList);
  dialog_ListView.setAdapter(directoryList); 
 }
 
 private void preparePhotoBarInFolder(File folder){
  
  String jpgs = "JPG fiels in folder " + folder.getAbsolutePath() + "\n\n";
  
  File[] files = folder.listFiles();
  
  myPhotoBarAdapter.clear();
  
  for (File file : files){
   if(!file.isDirectory()){
    Uri selectedUri = Uri.fromFile(file);
    String fileExtension
     = MimeTypeMap.getFileExtensionFromUrl(selectedUri.toString());
    if(fileExtension.equalsIgnoreCase("jpg")){
     jpgs += file.getAbsolutePath() + "\n";
     
     PhotoItem pItem = new PhotoItem(file.getAbsolutePath());
     myPhotoBarAdapter.addPhotoItem(pItem);
     
     myPhotoBarAdapter.notifyDataSetChanged();
    }  
   }  
  }
  jpgList.setText(jpgs); 
 }
  
}


Next:
- Update Gallery photos in background thread


5 comments:

  1. Hey, nice code..

    I want to ask you something, if I wanna show the image in Gallery in to the ImageView (change the TextView with ImageView) where should I change the code?

    Give the onItemClickListener to the image in Gallery to show it on ImageView?

    ReplyDelete
  2. First of all, please notice that Gallery was deprecated!

    For onItemClickListener, please read Implement AdapterView.OnItemClickListener for Gallery.

    For the first point, I'm not understand. Sorry!

    ReplyDelete
    Replies
    1. Well, for the first point is..

      How to combine between this project and JPG File Chooser project (http://android-coding.blogspot.hk/2012/05/jpg-file-chooser.html).

      So that, if I choose the image from Gallery (in this case from photoBar) then the choosen image will showed up at ImageView.

      Delete
    2. In the example Implement AdapterView.OnItemClickListener for Gallery, it already implemented OnItemClickListener and get the clicked PhotoItem, and its itmapImageSrc, such that you can display on ImageView, depends on your ui.

      Delete

Infolinks In Text Ads