Reputation: 360
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.
Upvotes: 0
Views: 1070
Reputation: 51
//Lazy Loading for image loading for Aquery.
//Try to use a query to load image in a listview
http://programmerguru.com/android-tutorial/introduction-to-aquery-android-query/
AQuery aq = aq = new AQuery(convertView);
// id means -> ImageView object or Imageview id
// path means-> Url of Image.
//Download a jar file, Copy and Past into a lib folder.
aq.id(imgDisplay).image(path,true, true, 0,R.drawable.default_image, null,AQuery.CACHE_DEFAULT,0.0f).visible();
Upvotes: 0
Reputation: 12358
Make use of Universal image loader library. This load images asynchronously and it doesn't lags your listview.
https://github.com/nostra13/Android-Universal-Image-Loader
It has an example in it.
Enjoy :)
Upvotes: 1