我有一个ListView,我从服务器填充。一切正常但单个问题是滚动时下载的图像显示在错误的项目位置。只有几秒钟后,它才能在正确的位置显示正确的图像。
这是我的ArrayAdapter类,其中包含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));
}
}
有人可以指导我走向正确的方向吗?我已经工作了几天来解决这个问题。感谢!!!
答案 0 :(得分:6)
这是因为滚动ImageView
时会重复使用listview
。在listview
onPreExecute
中显示加载图片。如果你使用像picasso这样的库,那么wolul会更好。因为它可以为您完成所有工作,包括将图像保存在捕获中
答案 1 :(得分:1)
您应该使用另一个类来保存您的对象,它可以帮助您在设置后保持良好的引用。
最好稍微更换适配器。
您最好获得一次layoutInflater的引用,因为为列表视图中的每个项都调用了getView。
因此,为整个类声明layoutInflater并仅获取一次引用
例如:
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;
}
答案 2 :(得分:1)
您还可以尝试使用UniversalImageLoader库来加载图片。试试这个
ImageLoader.getInstance().displayImage(url, holder.imgView, options);
在适配器中加载图片..
在适配器
的构造函数中使用DisplayImageOptions,如下所示 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();
并添加
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
在片段/活动的onCreateView / onCreate中包含列表
答案 3 :(得分:0)
尝试这样的事情......
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();
}