package net.jimblackler.yourphotoswatch;
import android.animation.AnimatorInflater;
import android.animation.AnimatorSet;
import android.content.ContentResolver;
import android.graphics.Bitmap;
import android.os.AsyncTask;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.ImageView;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class PhotoRecyclerAdapter extends RecyclerView.Adapter<PhotoRecyclerAdapter.ViewHolder> {
private final Map<String, Bitmap> bitmapCache;
private final PhotoListEntryObserver observer;
private final Set<String> enabled;
private List<? extends PhotoListEntry> items;
private ContentResolver contentResolver;
public PhotoRecyclerAdapter(List<? extends PhotoListEntry> items, Set<String> enabled,
PhotoListEntryObserver observer) {
this.items = items;
this.observer = observer;
this.enabled = enabled;
final int maximumSize = 80;
bitmapCache = new LinkedHashMap<String, Bitmap>(maximumSize, 0.75f, true) {
protected boolean removeEldestEntry(Map.Entry<String, Bitmap> eldest) {
return size() > maximumSize;
}
};
}
@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
contentResolver = parent.getContext().getContentResolver();
View view =
LayoutInflater.from(parent.getContext()).inflate(R.layout.photo_list_entry, parent, false);
return new ViewHolder(view, bitmapCache, enabled, observer);
}
@Override
public void onBindViewHolder(final ViewHolder holder, int position) {
final PhotoListEntry item = items.get(position);
holder.update(contentResolver, item);
}
@Override
public int getItemCount() {
return items.size();
}
public interface PhotoListEntryObserver {
void modified(PhotoListEntry listEntry);
}
static class ViewHolder extends RecyclerView.ViewHolder {
private final Map<String, Bitmap> bitmapCache;
private final PhotoListEntryObserver observer;
private final CheckBox checkBox;
private final AnimatorSet selectionAnimation;
private final CompoundButton.OnCheckedChangeListener changeListener;
private final Set<String> enabled;
private ImageView imageView;
private PhotoListEntry listEntry;
private AsyncTask<PhotoListEntry, Void, Bitmap> fetcher;
public ViewHolder(final View view, Map<String, Bitmap> bitmapCache,
final Set<String> enabled,
final PhotoListEntryObserver observer) {
super(view);
imageView = (ImageView) view.findViewById(R.id.imageView);
this.bitmapCache = bitmapCache;
this.observer = observer;
this.enabled = enabled;
checkBox = (CheckBox) view.findViewById(R.id.checkBox);
selectionAnimation =
(AnimatorSet) AnimatorInflater.loadAnimator(view.getContext(), R.animator.select_photo);
selectionAnimation.setTarget(view);
view.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
checkBox.toggle();
}
});
changeListener = new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
selectionAnimation.start();
if (isChecked)
enabled.add(listEntry.getId());
else
enabled.remove(listEntry.getId());
update(view.getContext().getContentResolver(), listEntry);
observer.modified(listEntry);
}
};
}
public void update(final ContentResolver contentResolver, final PhotoListEntry listEntry) {
checkBox.setOnCheckedChangeListener(null);
this.listEntry = listEntry;
try {
imageView.setImageBitmap(Bitmap.createBitmap(listEntry.getWidth(),
listEntry.getHeight(), Bitmap.Config.ARGB_8888));
} catch (OutOfMemoryError e) {
bitmapCache.clear();
imageView.setImageBitmap(null);
}
if (fetcher != null)
fetcher.cancel(false);
checkBox.setOnCheckedChangeListener(null);
checkBox.setChecked(enabled.contains(listEntry.getId()));
Bitmap bitmap = bitmapCache.get(listEntry.getId());
if (bitmap == null) {
fetcher = new AsyncTask<PhotoListEntry, Void, Bitmap>() {
@Override
protected Bitmap doInBackground(PhotoListEntry... params) {
try {
Bitmap bitmap = params[0].getBitmap(contentResolver);
bitmapCache.put(listEntry.getId(), bitmap);
return bitmap;
} catch (OutOfMemoryError e) {
bitmapCache.clear();
return null;
}
}
@Override
protected void onPostExecute(Bitmap bitmap) {
imageView.setImageBitmap(bitmap);
}
};
fetcher.execute(listEntry);
} else {
imageView.setImageBitmap(bitmap);
}
checkBox.setOnCheckedChangeListener(changeListener);
}
}
}