I know this is asked before and I have already searched a lot about this but could not get any proper answer on my issue.
I have created a list, the list gets filled with data that is coming from JSON. Now inside getView() method, I am inflating my custom row with data. Each row contains a Thumbnail, and I am creating each thumbnail from a different thread.
Now the problem is, everything is going well until I don’t scroll my list. When I scroll my list, my getView() method is called continuously , and all thumbnail images are getting recreated and its position is getting shuffled. Once thumbnails are created I don’t want to recreate them and also I want to maintain the order of my thumbnails.
Can you please guys help me on this?
Any help will greatly be appreciated.
My getView() method is:
@Override
public View getView(final int position, View convertView,
ViewGroup parent) {
ViewHolder viewHolder = new ViewHolder();
if (convertView == null) {
inflater = getLayoutInflater();
convertView = inflater.inflate(R.layout.list_item_row, parent,
false);
viewHolder.titleText = (TextView) convertView
.findViewById(R.id.titleText);
viewHolder.thumbImage = (ImageView) convertView
.findViewById(R.id.thumbnail);
convertView.setTag(viewHolder);
} else {
viewHolder = (ViewHolder) convertView.getTag();
}
final String thumbnailURLString = mPostsList.get(position).get(
"thumb");
createBitmapThread = (Thread) getLastNonConfigurationInstance();
createBitmapThread = new MyThread(thumbnailURLString,
viewHolder.thumbImage);
createBitmapThread.start();
viewHolder.titleText.setText(title);
return convertView;
}
And the Thread class:
public class MyThread extends Thread {
String mThumbURLString = null;
ImageView mImageView = null;
public MyThread(String thumbnailURLString, ImageView imageView) {
mThumbURLString = thumbnailURLString;
mImageView = imageView;
}
@Override
public void run() {
try {
URL newurl = null;
try {
newurl = new URL(mThumbURLString);
} catch (MalformedURLException e) {
e.printStackTrace();
}
try {
// Options opts = new Options();
/*
* opts.inDither = true; opts.inInputShareable = true;
* opts.inJustDecodeBounds = true; opts.inPurgeable =
* true;
*/
Log.e("", "INSIDE IMAGE DOINBG");
mBitmap = BitmapFactory
.decodeStream((InputStream) newurl.getContent());
} catch (IOException e) {
e.printStackTrace();
}
mHandler.post(new MyRunnable(mImageView));
} finally {
}
}
public class MyRunnable implements Runnable {
ImageView mImageView = null;
public MyRunnable(ImageView imageView) {
mImageView = imageView;
}
public void run() {
mImageView.setImageBitmap(mBitmap);
}
}
ok , here how i did a similar thing:
for each getView , create a new Fetching class and put it into a concurrent/synchronized stack . in the meanwhile , set the bitmap of the view to be empty (or anything else you wish) . you can also use caching instead.
the class will contain info of how to load the data (for example , the url of the bitmap) , the view to update , and the result of the fetching (for example , the bitmap itself) .
now , back to the getView, create&execute an asyncTask that will use a loop on the stack , each time it gets a Fetching class instance from the stack (once it’s empty,the asyncTask will break the loop and finish) , check that the view that needs to be updated still needs the data (using its viewHolder) load the bitmap , set the result into the Fetching class , and pass it through the publishProgress() function.
in the onProgressUpdate method , do the same check as before using the Fetching class instance and the viewHolder . if all went well , update the view to have the bitmap that was fetched .
a nice yet complicated example of how to handle the same problem can be found here .