2014-10-18 71 views
1

我有一个ListView,我从服务器上填充。一切工作正常,但唯一的问题是,滚动时下载的图像显示在错误的项目位置。只有几秒钟后,它才能在正确的位置显示正确的图像。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)); 

    } 
} 

能有人请指引我正确的方向?我已经工作了好几天来解决这个问题。谢谢!!!

回答

6

这是因为在滚动listviewImageView被重新使用。在listviewonPreExecute中显示加载图片。它会更好,如果你使用这样的一些库如picasso。因为它为您完成所有包括保存图像中捕捉

+1

非常感谢你。我现在使用毕加索,它的作品很棒! – Sini 2014-10-18 18:01:03

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(); 
     } 
1

你应该使用另一个类牵着你的对象,它可以帮助你保持一个很好的参考一旦设定。

最好你稍微改变一下你的适配器。

最好你得到一次layoutInflater的引用,因为getView是为listview中的每一项调用的。

所以,声明你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; 

    } 
1

您也可以尝试UniversalImageLoader库加载图片..试试这个

ImageLoader.getInstance().displayImage(url, holder.imgView, options); 

将图像加载到适配器内部。

使用D isplayImageOptions内部适配器

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 contaning列表

+0

毕加索和universalimageloader lib之间有巨大差异吗? – Sini 2015-03-08 20:05:25

+1

@Sini没有太大的区别..UniversalImageLoader是高度可定制的,并且在文档中更好,并提供了灵活的方式来加载位图或图像.....要了解详细的差异,请检查此链接..http://stackoverflow.com/问题/ 19995007/local-image-caching-solution-for-android-square-picasso-vs-universal-image-load ..你可以+我的答案之一,如果你觉得它有用..谢谢.. – 2015-03-09 03:07:04

相关问题