diff --git a/.idea/uiDesigner.xml b/.idea/uiDesigner.xml
new file mode 100644
index 0000000..3b00020
--- /dev/null
+++ b/.idea/uiDesigner.xml
@@ -0,0 +1,125 @@
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+ -
+
+
+
+
+ -
+
+
+ -
+
+
+
+
+
+
diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index 73bd0e1..f571f65 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -1,12 +1,24 @@
+
+
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
@@ -70,10 +82,24 @@
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -91,6 +117,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
@@ -140,6 +178,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -164,6 +220,7 @@
+
@@ -172,6 +229,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -311,6 +388,26 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -318,6 +415,7 @@
+
@@ -329,7 +427,7 @@
-
+
@@ -358,9 +456,109 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/out/production/GlassShare/GlassShare.apk b/out/production/GlassShare/GlassShare.apk
index 603168a..c9f94fd 100644
Binary files a/out/production/GlassShare/GlassShare.apk and b/out/production/GlassShare/GlassShare.apk differ
diff --git a/out/production/GlassShare/GlassShare.unaligned.apk b/out/production/GlassShare/GlassShare.unaligned.apk
index 2520974..2413d3b 100644
Binary files a/out/production/GlassShare/GlassShare.unaligned.apk and b/out/production/GlassShare/GlassShare.unaligned.apk differ
diff --git a/out/production/GlassShare/com/w9jds/glassshare/Adapters/csaAdapter$AsyncDrawable.class b/out/production/GlassShare/com/w9jds/glassshare/Adapters/csaAdapter$AsyncDrawable.class
new file mode 100644
index 0000000..1ade224
Binary files /dev/null and b/out/production/GlassShare/com/w9jds/glassshare/Adapters/csaAdapter$AsyncDrawable.class differ
diff --git a/out/production/GlassShare/com/w9jds/glassshare/Adapters/csaAdapter$BitmapWorkerTask.class b/out/production/GlassShare/com/w9jds/glassshare/Adapters/csaAdapter$BitmapWorkerTask.class
new file mode 100644
index 0000000..62b373c
Binary files /dev/null and b/out/production/GlassShare/com/w9jds/glassshare/Adapters/csaAdapter$BitmapWorkerTask.class differ
diff --git a/out/production/GlassShare/com/w9jds/glassshare/Adapters/csaAdapter.class b/out/production/GlassShare/com/w9jds/glassshare/Adapters/csaAdapter.class
index 22d6088..e59d854 100644
Binary files a/out/production/GlassShare/com/w9jds/glassshare/Adapters/csaAdapter.class and b/out/production/GlassShare/com/w9jds/glassshare/Adapters/csaAdapter.class differ
diff --git a/res/layout/card_layout.xml b/res/layout/card_layout.xml
index d101470..3a63e0b 100644
--- a/res/layout/card_layout.xml
+++ b/res/layout/card_layout.xml
@@ -9,6 +9,5 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="centerCrop"/>
-
-
+
diff --git a/src/com/w9jds/glassshare/Adapters/csaAdapter.java b/src/com/w9jds/glassshare/Adapters/csaAdapter.java
index 367979a..be91044 100644
--- a/src/com/w9jds/glassshare/Adapters/csaAdapter.java
+++ b/src/com/w9jds/glassshare/Adapters/csaAdapter.java
@@ -1,10 +1,15 @@
package com.w9jds.glassshare.Adapters;
+import java.lang.ref.WeakReference;
import java.util.ArrayList;
import android.content.Context;
+import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.os.AsyncTask;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@@ -17,11 +22,13 @@ public class csaAdapter extends CardScrollAdapter
{
private Context mcContext;
private ArrayList mlsPaths;
+ private Bitmap mPlaceHolderBitmap;
public csaAdapter(Context cContext, ArrayList alsPaths)
{
mcContext = cContext;
mlsPaths = alsPaths;
+ mPlaceHolderBitmap = BitmapFactory.decodeResource(mcContext.getResources(), R.drawable.ic_placeholder_photo_150);
}
@Override
@@ -54,27 +61,162 @@ public View getView(int position, View convertView, ViewGroup parent)
LayoutInflater inflater = (LayoutInflater) mcContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View vCard = inflater.inflate(R.layout.card_layout, parent, false);
-// BitmapFactory.Options bfoOptions = new BitmapFactory.Options();
-// bfoOptions.inJustDecodeBounds = true;
-// BitmapFactory.decodeFile(mlsPaths.get(position), bfoOptions);
-//
-// bfoOptions.inSampleSize = (bfoOptions.outWidth / 2) - (640 / 2);
-
- Bitmap bImage = BitmapFactory.decodeFile(mlsPaths.get(position));
-
+ //get the imageview we are going to populate
ImageView ivPic = (ImageView) vCard.findViewById(R.id.cardImage);
-
- if (bImage != null)
+
+
+ if (cancelPotentialWork(position, ivPic))
{
- if (bImage.getWidth() > 640)
- {
- double dRatio = ((double)bImage.getWidth()) / 640;
- ivPic.setImageBitmap(Bitmap.createScaledBitmap(bImage, 640, (int) Math.round(bImage.getHeight() / dRatio) , true));
- }
- else
- ivPic.setImageBitmap(bImage);
+ final BitmapWorkerTask task = new BitmapWorkerTask(ivPic, mlsPaths, position);
+
+ final AsyncDrawable asyncDrawable = new AsyncDrawable(mcContext.getResources(), mPlaceHolderBitmap, task);
+ ivPic.setImageDrawable(asyncDrawable);
+
+ task.execute();
}
return vCard;
}
+
+ public static boolean cancelPotentialWork(int iPosition, ImageView ivCard)
+ {
+ final BitmapWorkerTask bwtTask = getBitmapWorkerTask(ivCard);
+
+ if (bwtTask != null)
+ {
+ final int position = bwtTask.miPosition;
+ if (position != iPosition)
+ // Cancel previous task
+ bwtTask.cancel(true);
+ else
+ // The same work is already in progress
+ return false;
+ }
+ // No task associated with the ImageView, or an existing task was cancelled
+ return true;
+ }
+
+ static class AsyncDrawable extends BitmapDrawable
+ {
+ private final WeakReference bitmapWorkerTaskReference;
+
+ public AsyncDrawable(Resources res, Bitmap bitmap, BitmapWorkerTask bitmapWorkerTask)
+ {
+ super(res, bitmap);
+ bitmapWorkerTaskReference = new WeakReference(bitmapWorkerTask);
+ }
+
+ public BitmapWorkerTask getBitmapWorkerTask()
+ {
+ return bitmapWorkerTaskReference.get();
+ }
+ }
+
+
+ private static BitmapWorkerTask getBitmapWorkerTask(ImageView ivCard)
+ {
+ if (ivCard != null)
+ {
+ final Drawable drawable = ivCard.getDrawable();
+ if (drawable instanceof AsyncDrawable)
+ {
+ final AsyncDrawable asyncDrawable = (AsyncDrawable) drawable;
+ return asyncDrawable.getBitmapWorkerTask();
+ }
+ }
+ return null;
+ }
+
+ public class BitmapWorkerTask extends AsyncTask
+ {
+ private final ArrayList mlsPaths;
+ private final WeakReference mivCard;
+ private final int miPosition;
+
+ public BitmapWorkerTask(ImageView ivCard, ArrayList lsPaths, int iPosition)
+ {
+ // Use a WeakReference to ensure the ImageView can be garbage collected
+ mivCard = new WeakReference(ivCard);
+ miPosition = iPosition;
+ mlsPaths = lsPaths;
+
+ }
+
+ // Decode image in background.
+ @Override
+ protected Bitmap doInBackground(Integer... params)
+ {
+ //create new options for bitmap import
+ BitmapFactory.Options bfoOptions = new BitmapFactory.Options();
+ //set it so you only get bounds (no pixels)
+ bfoOptions.inJustDecodeBounds = true;
+ //pull the info from the file
+ BitmapFactory.decodeFile(mlsPaths.get(miPosition), bfoOptions);
+
+ if (bfoOptions.outWidth > 640)
+ {
+ //turn off the bounds only so you get the pixels this time
+ bfoOptions.inJustDecodeBounds = false;
+ //calculate the sample size and set it in the options
+ bfoOptions.inSampleSize = calculateInSampleSize(bfoOptions, 640, 360);
+
+ Bitmap bImage = BitmapFactory.decodeFile(mlsPaths.get(miPosition), bfoOptions);
+
+ double dRatio = ((double)bImage.getWidth()) / 640;
+ return Bitmap.createScaledBitmap(bImage, 640, (int) Math.round(bImage.getHeight() / dRatio), true);
+
+// mivCard.setImageBitmap(BitmapFactory.decodeFile(mlsPaths.get(position), bfoOptions));
+ }
+ else
+ return BitmapFactory.decodeFile(mlsPaths.get(miPosition));
+
+// return decodeSampledBitmapFromResource(getResources(), data, 100, 100));
+ }
+
+ public int calculateInSampleSize( BitmapFactory.Options bfoOptions, int iReqWidth, int iReqHeight)
+ {
+ //pull out the images height
+ final int height = bfoOptions.outHeight;
+ //pull out the images width
+ final int width = bfoOptions.outWidth;
+ //set the samle size to 1 for initialization
+ int inSampleSize = 1;
+
+ //if te height or the width of the image is greater than the requested sizes
+ if (height > iReqHeight || width > iReqWidth)
+ {
+ //set the half dimensions for the image
+ final int halfHeight = height / 2;
+ final int halfWidth = width / 2;
+
+ //white both half dimensions divided by the sample size are still greater than the requested dimensions
+ while ((halfHeight / inSampleSize) > iReqHeight && (halfWidth / inSampleSize) > iReqWidth)
+ {
+ //multiply the sample size by 2
+ inSampleSize *= 2;
+ }
+ }
+
+ //once the loop is done return the sample size
+ return inSampleSize;
+ }
+
+ // Once complete, see if ImageView is still around and set bitmap.
+ @Override
+ protected void onPostExecute(Bitmap bPic)
+ {
+ if (isCancelled())
+ bPic = null;
+
+ if (mivCard != null && bPic != null)
+ {
+ final ImageView ivCard = mivCard.get();
+ final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(ivCard);
+ if (this == bitmapWorkerTask && ivCard != null)
+ {
+ ivCard.setImageBitmap(bPic);
+ }
+ }
+ }
+ }
}
diff --git a/src/com/w9jds/glassshare/MainActivity.java b/src/com/w9jds/glassshare/MainActivity.java
index 0716477..62a9e80 100644
--- a/src/com/w9jds/glassshare/MainActivity.java
+++ b/src/com/w9jds/glassshare/MainActivity.java
@@ -60,7 +60,7 @@ public void onItemClick(AdapterView> parent, View view, int position, long id)
//open the menu
openOptionsMenu();
}
- });
+ });
//set the view of this activity
setContentView(csvCardsView);