I use your two-way-gridview (congrats on the simplicity of it by the way) to show a horizontal list of photos my user has taken. The gridview is backed by a simple cursor adapter, and it updates every time the user takes a picture (the photos are in reverse order of creation date). I do use a viewbinder because the picture loading is really slow on the default cursor adapter class.
The problem is that when the photos update, they listview will appear to run the cursor backa nd forth and update the imageviews multiple times. It's very confusing to the user as the imageviews update onces, then again, before re-updating a final time.
Here's the link of what that looks like: http://youtu.be/PZvKeKsQBUE
I'm guessing this is due to some confusion in the manipulation of columns to get the gridview to scroll horizontally - but hopefully there's a way around it? Here are the methods that update the gridview:
String[] from = {MediaStore.Images.ImageColumns.DATA};
int[] to = {R.id.imageContent};
TwoWayGridView imageListView = (TwoWayGridView) view.findViewById(R.id.imagelist);
getLoaderManager().initLoader(CURSOR_LOADER_ID, null, this);
mMediaAdapter = new SimpleCursorAdapter(getActivity(), R.layout.imagelistview, null, from, to, CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
mMediaAdapter.setViewBinder(new SimpleCursorAdapter.ViewBinder() {
@Override
public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
if(view.getId() == R.id.imageContent){
BitmapWorkerTask task = new BitmapWorkerTask((ImageView) view, TwitterFragment.this);
task.execute(cursor.getString(columnIndex));
return true;
}
return false;
}
});
imageListView.setAdapter(mMediaAdapter);
}
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
switch(id){
case CURSOR_LOADER_ID:
if (args!= null){
String filePath = (String) args.get("uri");
File temp = new File(filePath);
getActivity().sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(temp)) );
}
Uri imageUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
Uri queryUri = imageUri.buildUpon().appendQueryParameter("limit", "10").build();
Log.i("THE IMAGE PATH", String.valueOf(MediaStore.Images.Media.EXTERNAL_CONTENT_URI));
String queryFolder = "%streem%";
String[] where = new String[]{queryFolder};
return new CursorLoader(getActivity(), queryUri, null, MediaStore.Images.Media.DATA + " LIKE ? ", new String[]{queryFolder}, MediaStore.Images.ImageColumns.DISPLAY_NAME + " DESC");
default:
return null;
}
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
mMediaAdapter.changeCursor(cursor);
}
@Override
public void onLoaderReset(Loader<Cursor> loader) {
mMediaAdapter.changeCursor(null);
}
///This gets called after a photo is successfully taken, so that the gridview can get updated.
public void updatePhoto(ScreenShot screenShot){
if (screenShot != null){
Bundle bundle = new Bundle();
bundle.putString("uri", screenShot.getFilePath());
getLoaderManager().restartLoader(CURSOR_LOADER_ID, bundle, this);
}
}
private static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight){
final int height = options.outHeight;
final int width = options.outWidth;
int inSampleSize = 1;
if (height > reqHeight || width > reqWidth){
final int halfHeight = height /2;
final int halfWidth = width / 2;
while ((halfHeight/inSampleSize) > reqHeight
&& (halfWidth / inSampleSize > reqWidth)) {
inSampleSize *=2;
}
}
return inSampleSize;
}
private static Bitmap decodeSampledBitmapFromResource(String filePath, int reqWidth, int reqHeight){
final BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
Bitmap file = BitmapFactory.decodeFile(filePath, options);
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
options.inJustDecodeBounds = false;
return BitmapFactory.decodeFile(filePath, options);
}
class BitmapWorkerTask extends AsyncTask<String, Void, Bitmap> {
private final WeakReference<ImageView> imageViewReference;
private int data = 0;
private String filePath;
private TwitterFragment activity;
public BitmapWorkerTask(ImageView imageView, TwitterFragment activity){
imageViewReference = new WeakReference<ImageView>(imageView);
this.activity = activity;
}
@Override
protected Bitmap doInBackground(String... params) {
this.filePath = params[0];
Bitmap bmp = decodeSampledBitmapFromResource(filePath, THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT);
return bmp;
}
@Override
protected void onPostExecute(Bitmap bitmap){
if (imageViewReference != null && bitmap != null){
final ImageView imageView = imageViewReference.get();
if (imageView != null){
imageView.setImageBitmap(bitmap);
}
}
}
}