So my Listview has been lagging, because I am loading too many Pictures into it. So I searched the web and found two particular ideas to solve the problem:
So since I am new to Developing with Android I gave the AsyncTask a shot and failed. The examples I have seen, were mostly using URLs to download pictures, and since I am using a sqlite DB I just couldn't get the examples to work for me.
So here is my try:
static class ViewHolder {
TextView imageTextView;
ImageView favImageView;
int position;
}
//Constructor for List Items
private class favImagesListAdapter extends ArrayAdapter<FavImages>{
private LayoutInflater mInflater = LayoutInflater.from(context);
public favImagesListAdapter(){
super (MainActivity.this, R.layout.listview_item, FavImages);
}
@Override
public View getView (final int position, View convertView, ViewGroup parent){
ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.listview_item, parent, false);
holder = new ViewHolder();
holder.imageTextView = (TextView) convertView.findViewById(R.id.favName);
holder.favImageView = (ImageView) convertView.findViewById(R.id.favImage);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
FavImages currentFav = FavImages.get(position);
holder.imageTextView.setText(currentFav.getImageName());
new AsyncTask<ViewHolder, Void, Bitmap>() {
private ViewHolder v;
@Override
protected Bitmap doInBackground(ViewHolder... params) {
v = params[0];
return mFakeImageLoader.getImage();
}
@Override
protected void onPostExecute(Bitmap result) {
super.onPostExecute(result);
if (v.position == position) {
// If this item hasn't been recycled already, hide the
// progress and set and show the image
//v.progress.setVisibility(View.GONE);
v.favImageView.setVisibility(View.VISIBLE);
v.favImageView.setImageBitmap(result);
}
}
}.execute(holder);
//old Version that causes lags
ContentResolver cr = getContentResolver();
try {
holder.favImageView.setImageBitmap(MediaStore.Images.Media.getBitmap(cr, currentFav.getImagePath()));
} catch (IOException e) {
e.printStackTrace();
}
return convertView;
}
}
Since I didn't have a reference what the FakeImageLoader does, I tried to reduce the size of the Images in there, but it didn't work, so I took a reference Code I found on a google Site like so:
public class FakeImageLoader {
private Bitmap mBmp;
public FakeImageLoader(Context cxt)
{
mBmp= BitmapFactory.decodeResource(cxt.getResources(), R.drawable.ic_launcher);
}
public Bitmap getImage()
{
try {
Thread.sleep(new Random().nextInt(5000));
} catch (InterruptedException e) {
e.printStackTrace();
}
return mBmp;
}
}
But using that class just caused errors (because used for something totally different?).
So I am asking, what do I need the FakeImageLoader (maybe not that good of a name) to do, to load the images best (guessing just have to scale the images down) and mostly how do I do it.
I have also read about Picasso, but I want to keep the App small and learn by doing (or asking). If more code helps I will do so if asked.
Edit:
Using the FakeImageLoader class did not work (actually pretty obvious), so I changed my whole ListAdapter with the Asynctask to this:
static class ViewHolder {
TextView imageTextView;
ImageView favImageView;
int position;
}
//Constructor for List Items
private class favImagesListAdapter extends ArrayAdapter<FavImages>{
private LayoutInflater mInflater = LayoutInflater.from(context);
public favImagesListAdapter(){
super (MainActivity.this, R.layout.listview_item, FavImages);
}
@Override
public View getView (final int position, View convertView, ViewGroup parent){
ViewHolder holder;
if (convertView == null) {
convertView = mInflater.inflate(R.layout.listview_item, parent, false);
holder = new ViewHolder();
holder.imageTextView = (TextView) convertView.findViewById(R.id.favName);
holder.favImageView = (ImageView) convertView.findViewById(R.id.favImage);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
final FavImages currentFav = FavImages.get(position);
holder.imageTextView.setText(currentFav.getImageName());
class MyAsyncTask extends AsyncTask<ViewHolder, Void, Bitmap> {
private ViewHolder v;
@Override
protected Bitmap doInBackground(ViewHolder... params) {
v = params[0];
return getImage();
}
private Bitmap getImage() {
Bitmap mBmp;
ContentResolver cr = getContentResolver();
MainActivity.ViewHolder holder = null;
com.adrianopaulus.favoriten.FavImages currentFav1 = FavImages.get(position);
try {
mBmp = holder.favImageView.setImageBitmap(MediaStore.Images.Media.getBitmap(cr, currentFav1.getImagePath()));
return mBmp;
} catch (FileNotFoundException e) {
e.printStackTrace();
return null;
} catch (IOException e) {
e.printStackTrace();
return null;
}
//return mBmp;
}
@Override
protected void onPostExecute(Bitmap result) {
super.onPostExecute(result);
if (v.position == position) {
// If this item hasn't been recycled already, hide the
// progress and set and show the image
//v.progress.setVisibility(View.GONE);
v.favImageView.setVisibility(View.VISIBLE);
v.favImageView.setImageBitmap(result);
}
}
}MyAsyncTask.execute((Runnable) holder);
return convertView;
}
}
But it some has a Problem with following line:
mBmp = holder.favImageView.setImageBitmap(MediaStore.Images.Media.getBitmap(cr, currentFav1.getImagePath()));
and I don't know what I am doing wrong.