Reputation: 406
I have a ListView which I am filling from server. Everything works fine but the single problem is that the downloaded images are shown in wrong item positions when scroll. Only after a few seconds then it shows the correct image on the right position.
Here is my ArrayAdapter class, which includes the AsynchTask:
public class ApplicationAdapter extends ArrayAdapter<Application> {
private List<Application> items;
public ApplicationAdapter(Context context, List<Application> items) {
super(context, R.layout.app_custom_list, items);
this.items = items;
}
@Override
public int getCount() {
return items.size();
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater li = LayoutInflater.from(getContext());
v = li.inflate(R.layout.app_custom_list, null);
}
Application app = items.get(position);
if (app != null) {
ImageView imageView = (ImageView) v.findViewById(R.id.appIcon);
TextView titleText = (TextView) v.findViewById(R.id.titleTxt);
if (imageView != null) {
String path_image = app.getImagePath();
// Call AsynchTask to load image into ImageView from path
DownloadImageTask1 d = new DownloadImageTask(imageView);
d.execute(path_image);
}
if (titleText != null) {
titleText.setText(app.getTitle());
}
}
return v;
}
private class DownloadImageTask1 extends AsyncTask<String, Void, Bitmap> {
ImageView bmImage;
public DownloadImageTask1(ImageView bmImage) {
this.bmImage = bmImage;
}
protected Bitmap doInBackground(String... urls) {
String urldisplay = urls[0];
Bitmap mIcon11 = null;
try {
InputStream in = new java.net.URL(urldisplay).openStream();
mIcon11 = BitmapFactory.decodeStream(in);
} catch (Exception e) {
Log.e("Error", e.getMessage());
e.printStackTrace();
}
return mIcon11;
}
protected void onPostExecute(Bitmap result) {
bmImage.setImageBitmap(getRoundedCornerBitmap(result));
}
}
Can somebody please guide me to the right direction? I am already working for days to solve this issue. Thanks!!!
Upvotes: 1
Views: 2861
Reputation: 9653
You can also try UniversalImageLoader library to load images.. Try this
ImageLoader.getInstance().displayImage(url, holder.imgView, options);
to load images inside adapter..
Use DisplayImageOptions as follows inside constructor of adapter
options = new DisplayImageOptions.Builder()
.showImageOnLoading(android.R.color.transparent)
.showImageForEmptyUri(android.R.color.transparent)
.showImageOnFail(android.R.color.transparent)
.cacheInMemory(true)
.cacheOnDisk(true)
.considerExifParams(true)
.bitmapConfig(Bitmap.Config.RGB_565)
.build();
and add
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
inside onCreateView/onCreate of fragment/activity contaning the list
Upvotes: 1
Reputation: 486
You should use another class for holding your objects, it helps you keep a good reference once set.
And it's best you change your adapter a little bit.
It's best you get a reference to your layoutInflater once , since getView is called for every item in the listview.
So declare your layoutInflater for the whole class and get a reference only once
For example :
private LayoutInflater inflater;
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ImageHolder holder = new ImageHolder();
if (inflater == null)
inflater = (LayoutInflater) activity
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if(convertView == null){
convertView = inflater.inflate(R.layout.fragment_list_item_transition, null);
ImageView imageView = (ImageView) convertView.findViewById(R.id.appIcon);
TextView titleText = (TextView) convertView.findViewById(R.id.titleTxt);
holder.image = imageView;
holder.title = titleText;
convertView.setTag(holder);
}else{
holder = (ImageHolder) convertView.getTag(position);
}
Application app = items.get(position);
if (app != null) {
holder.title.seText(app.getTitle());
String path_image = app.getImagePath();
// Call AsynchTask to load image into ImageView from path
DownloadImageTask1 d = new DownloadImageTask1(holder.imageView);
d.execute(path_image);
}
return convertView;
}
private static class ImageHolder{
ImageView image;
TextView title;
}
Upvotes: 1
Reputation: 3344
Try something like this...
replace
if (v == null) {
LayoutInflater li = LayoutInflater.from(getContext());
v = li.inflate(R.layout.app_custom_list, null);
}
with
if (v == null) {
LayoutInflater li = LayoutInflater.from(getContext());
v = li.inflate(R.layout.app_custom_list, null);
convertView.setTag(v);
} else {
v = (View) convertView.getTag();
}
Upvotes: 0
Reputation: 5914
This is because the ImageView
is reused when the listview
is scrolled. show a loading image in the listview
onPreExecute
. it woluld be better if you use some library like picasso for this. as it does all the work for you including saving the image in the catch
Upvotes: 6