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 @@ + + + @@ -172,6 +229,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);