滚动ListView时图像顺序混乱

本文选自StackOverflow(简称:SOF)精选问答汇总系列文章之一,本系列文章将为读者分享国外最优质的精彩问与答,供读者学习和了解国外最新技术。本文将为读者讲解滚动ListView时图像顺序混乱的解决方法。


问题:

zeitgeist

ListView有两个TextViews 和一个ImageView。图片是从网上下载的,缓存在LruCache。当在ListView滚动时,图片会出现几秒钟的混乱。直到正确的图片完全加载之前是不应该有任何图片出现的。我发现了几个同样的问题,但是没人能帮助我。

这是我的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
public class NewsAdapter extends BaseAdapter {
     private static LayoutInflater inflater;
     private List items = new LinkedList();
     private LruCache mMemoryCache;
 
     public NewsAdapter(Context context) {
         inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
 
         // Bitmap Cache
         final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
         final int cacheSize = maxMemory / 8;
         mMemoryCache = new LruCache(cacheSize) {
             @Override
             protected int sizeOf(String key, Bitmap bitmap) {
                 return getSizeInBytes(bitmap) / 1024;
             }
         };
     }
 
     public void add(Item item) {
         items.add(item);
     }
 
     @Override
     public View getView(int position, View convertView, ViewGroup parent) {
         ViewHolder viewHolder = new ViewHolder();
         if (convertView == null ) {
             convertView = inflater.inflate(R.layout.list_item_item, null );
             viewHolder.ivPic = (ImageView) convertView.findViewById(R.id.ivPic);
             viewHolder.tvTitle = (TextView) convertView.findViewById(R.id.tvTitle);
             viewHolder.tvShortDesc = (TextView) convertView.findViewById(R.id.tvShortDesc);
             convertView.setTag(viewHolder);
         } else {
             viewHolder = (ViewHolder) convertView.getTag();
         }
 
         final Item item = items.get(position);
         viewHolder.tvTitle.setText(item.getTitle());
         viewHolder.tvShortDesc.setText(Html.fromHtml(item.getShortDesc()));
 
         Bitmap bitmap = mMemoryCache.get(item.getPicUrl());
         if (bitmap != null ) {
             viewHolder.ivPic.setImageBitmap(bitmap);
         } else {
             GetBitmap gb = new GetBitmap(item.getPicUrl(), viewHolder.ivPic);
             gb.execute();
         }
 
         return convertView;
     }
 
     static class ViewHolder {
         ImageView ivPic;
         TextView tvTitle;
         TextView tvShortDesc;
     }
 
     @Override
     public int getCount() {
         return items.size();
     }
 
     @Override
     public Item getItem(int position) {
         return items.get(position);
     }
 
     @Override
     public long getItemId(int position) {
         return 0;
     }
 
     @SuppressLint( "NewApi" )
     public static int getSizeInBytes(Bitmap bitmap) {
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
             return bitmap.getByteCount();
         } else {
             return bitmap.getRowBytes() * bitmap.getHeight();
         }
     }
 
     private class GetBitmap extends AsyncTask {
         private String url;
         private ImageView ivPic;
 
         public GetBitmap(String url, ImageView ivPic) {
             this .url = url;
             this .ivPic = ivPic;
         }
 
         @Override
         protected Bitmap doInBackground(Void... params) {
             Bitmap bitmap = null ;
             try {
                 URL url = new URL( this .url);
                 bitmap = BitmapFactory.decodeStream(url.openConnection().getInputStream());
             } catch (Exception e) {
                 e.printStackTrace();
             }
 
             return bitmap;
         }
 
         @Override
         protected void onPostExecute(Bitmap bitmap) {
             super .onPostExecute(bitmap);
             if (bitmap != null ) ivPic.setImageBitmap(bitmap);
         }
 
     }
 
}

如果谁能帮助我那就太好了!先谢过!

PS:我忘记了一些东西,请不要建议任何库,我想在不使用外部库的情况下完成它。

答案:

Rajesh CP

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public GetBitmap(String url, ImageView ivPic, int position) {
     this .url = url;
     this .ivPic = ivPic;
     this .position = position;
     ivPic.setTag(position);
     ivPic.setImageBitmap( null );
}
 
@Override
protected void onPostExecute(Bitmap bitmap) {
      super .onPostExecute(bitmap);
      if (bitmap != null && ((Integer)getTag) == this .position)
          ivPic.setImageBitmap(bitmap);
}

问题在于你没有检查图像是否在同一位置。试试上面的代码,希望能帮到你。在代码中,我没有找到任何推动位图加载到缓存的代码。

user2365568

可能是这个代码片段:

1
ViewHolder viewHolder = new ViewHolder();

这个片段是在每次调用getView的时候,创建viewHolder的新实例。

试试用这个来代替:

1
final ViewHolder viewHolder;

然后在if结构中:

1
viewHolder = new ViewHolder();

执行你的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
@Override
public View getView(int position, View convertView, ViewGroup parent) {
    final ViewHolder viewHolder;
 
     if (convertView == null ) {
         convertView = inflater.inflate(R.layout.list_item_item, null );
         viewHolder = new ViewHolder();
         viewHolder.ivPic = (ImageView) convertView.findViewById(R.id.ivPic);
         viewHolder.tvTitle = (TextView) convertView.findViewById(R.id.tvTitle);
         viewHolder.tvShortDesc = (TextView) convertView.findViewById(R.id.tvShortDesc);
         convertView.setTag(viewHolder);
     } else {
         viewHolder = (ViewHolder) convertView.getTag();
     }
 
     final Item item = items.get(position);
     viewHolder.tvTitle.setText(item.getTitle());
     viewHolder.tvShortDesc.setText(Html.fromHtml(item.getShortDesc()));
 
     Bitmap bitmap = mMemoryCache.get(item.getPicUrl());
     if (bitmap != null ) {
         viewHolder.ivPic.setImageBitmap(bitmap);
     } else {
         GetBitmap gb = new GetBitmap(item.getPicUrl(), viewHolder.ivPic);
         gb.execute();
     }
 
     return convertView;
}

原文链接:ListView - Images shuffle while scrolling

文章选自StackOverFlow社区,鉴于其内容对于开发者有所帮助,现将文章翻译于此,供大家参考及学习。9Tech将每日持续更新,读者可点击StackOverflow(简称:SOF)精选问答汇总,查看全部译文内容。同时,我们也招募志同道合的技术朋友共同翻译,造福大家!报名请发邮件至zhangqi_wj#cyou-inc.com。(#换成@)


转载于:https://www.cnblogs.com/aikongmeng/p/3697328.html

你可能感兴趣的:(滚动ListView时图像顺序混乱)