package uni.projecte.ui; import java.io.File; import java.io.FilenameFilter; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import uni.projecte.R; import uni.projecte.dataLayer.dataStructures.ImageCache; import uni.projecte.dataLayer.utils.PhotoUtils; import uni.projecte.dataTypes.Utilities; import uni.projecte.ui.ImageLoader.ImageLoadListener; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.net.Uri; import android.os.Handler; import android.os.storage.StorageManager; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.ProgressBar; import android.widget.ViewSwitcher; public class LazyImageAdapter extends BaseAdapter implements ImageLoadListener { private static final int PROGRESSBARINDEX = 0; private static final int IMAGEVIEWINDEX = 1; private Context mContext = null; private OnClickListener mItemClickListener; private Handler mHandler; private ImageLoader mImageLoader = null; private String projName; private File imageGalleryDir; private String storagePath; private ArrayList<String> availableImageList; private int thMaxSize; private HashMap<String, Long> selectedPhotos; private ImageCache imageCache; private boolean mBusy; /** * Lazy loading image adapter * @param aContext * @param lClickListener click listener to attach to each item * @param lPath the path where the images are located * @param selectedPhotos * @param mBusy * @throws Exception when path can't be read from or is not a valid directory */ public LazyImageAdapter( Context aContext, OnClickListener lClickListener, String storagePath, String projName, HashMap<String, Long> selectedPhotos, int thMaxSize ) throws Exception { mContext = aContext; mItemClickListener = lClickListener; imageGalleryDir = new File(storagePath); this.storagePath=storagePath; this.projName=projName; this.thMaxSize=thMaxSize; this.selectedPhotos=selectedPhotos; this.imageCache = new ImageCache(aContext); // Do some error checking if(!imageGalleryDir.canRead()){ throw new Exception("Can't read this path"); } else if(!imageGalleryDir.isDirectory()){ throw new Exception("Path is a not a directory"); } createImageList(selectedPhotos!=null); mImageLoader = new ImageLoader(this,imageCache,thMaxSize); mImageLoader.start(); mHandler = new Handler(); } @Override public void finalize() throws Throwable { super.finalize(); // stop the thread we started mImageLoader.stopThread(); } public void clearHandler() throws Throwable { mImageLoader.interrupt(); mImageLoader.start(); mHandler = new Handler(); } public int getCount() { return availableImageList.size(); } public Object getItem(int aPosition) { return availableImageList.get(aPosition).toString(); } public long getItemId(int arg0) { return 0; } /* * * * */ private void createImageList(boolean filtered) { File images = new File(storagePath); File thumbs=new File(storagePath+"thumbs/"); if(!thumbs.exists()) thumbs.mkdirs(); //List of images at lPath File[] imagelist = images.listFiles(new FilenameFilter(){ public boolean accept(File dir, String name){ return ((name.endsWith(".jpg")) || (name.endsWith(".png"))) && (name.startsWith(projName)) ; } } ); availableImageList= new ArrayList<String>(); for(int i= 0 ; i< imagelist.length; i++){ String fileName = imagelist[i].getName(); if(!filtered || (filtered && selectedPhotos.get(fileName)!=null)){ availableImageList.add(storagePath+fileName); } } if(availableImageList.size()==0){ Utilities.showToast(mContext.getString(R.string.noPhotoInProject),mContext); } } public View getView(final int aPosition, View aConvertView, ViewGroup parent) { final ViewSwitcher lViewSwitcher; String lPath = (String)getItem(aPosition); lViewSwitcher = new ViewSwitcher(mContext); lViewSwitcher.setPadding(4, 4, 4, 4); ProgressBar lProgress = new ProgressBar(mContext); lProgress.setLayoutParams(new ViewSwitcher.LayoutParams(thMaxSize/2, thMaxSize/2)); lViewSwitcher.addView(lProgress); ImageView lImage = new ImageView(mContext); lImage.setLayoutParams(new ViewSwitcher.LayoutParams(thMaxSize, thMaxSize)); lViewSwitcher.addView(lImage); // attach the onclick listener lViewSwitcher.setOnClickListener(mItemClickListener); ViewTagInformation lTagHolder = (ViewTagInformation) lViewSwitcher .getTag(); if (lTagHolder == null || !lTagHolder.aImagePath.equals(lPath)) { // The Tagholder is null meaning this is a first time load // or this view is being recycled with a different image // Create a ViewTag to store information for later ViewTagInformation lNewTag = new ViewTagInformation(); lNewTag.aImagePath = lPath; lNewTag.position=aPosition; lViewSwitcher.setTag(lNewTag); // Grab the image view // Have the progress bar display // Then queue the image loading ImageView lImageView = (ImageView) lViewSwitcher.getChildAt(1); lViewSwitcher.setDisplayedChild(PROGRESSBARINDEX); if(!mBusy){ Bitmap bitmap=imageCache.getBitmapFromMemCache(lPath); String cacheInfo=" ("+imageCache.getSize()+"/"+imageCache.getMaxSize()+") --- "+(imageCache.getSize()*100)/imageCache.getMaxSize()+"%"; if(bitmap!=null){ mImageLoader.signalUI(lViewSwitcher, lImageView, bitmap); Log.i("Images"," OK - HIT cache ("+PhotoUtils.getFileName(lPath)+") : "+cacheInfo); } else{ Log.i("Images"," KO - MISS cache("+PhotoUtils.getFileName(lPath)+") : "+cacheInfo); if(!mImageLoader.isAlive()) mImageLoader.start(); mImageLoader.queueImageLoad(lPath, lImageView, lViewSwitcher); } } else{ } } return lViewSwitcher; } public int size(){ return availableImageList.size(); } public void handleImageLoaded( final ViewSwitcher aViewSwitcher, final ImageView aImageView, final Bitmap aBitmap) { // The enqueue the following in the UI thread mHandler.post(new Runnable() { public void run() { // set the bitmap in the ImageView aImageView.setImageBitmap(aBitmap); // explicitly tell the view switcher to show the second view aViewSwitcher.setDisplayedChild(IMAGEVIEWINDEX); } }); } public boolean isBusy() { return mBusy; } public void setBusy(boolean mBusy) { this.mBusy = mBusy; } public ArrayList<String> getAvailableImageList() { return availableImageList; } public void setAvailableImageList(ArrayList<String> availableImageList) { this.availableImageList = availableImageList; } }