博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
滚动ListView时图像顺序混乱
阅读量:6479 次
发布时间:2019-06-23

本文共 5124 字,大约阅读时间需要 17 分钟。

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

问题:

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<Item> items =
new
LinkedList<Item>();
    
private LruCache<String, Bitmap> 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<String, Bitmap>(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<Void, Bitmap, Bitmap> {
        
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:我忘记了一些东西,请不要建议任何库,我想在不使用外部库的情况下完成它。

答案:

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

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

可能是这个代码片段:

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;
}

原文链接:

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

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

你可能感兴趣的文章
第一部分:基础知识(第一章)第一个 Silverlight 手机程序
查看>>
Silverlight与Flash区别之一
查看>>
删除恢复Hadoop集群中的DataNode
查看>>
Silverlight 2动态创建矩形对象(附完整源代码)
查看>>
PowerShell中对属性设置别名
查看>>
弹出的ViewController半透明效果
查看>>
OpenCV 3.1.0编译与添加扩展模块
查看>>
从京东技术演进看互联网企业的成长历程
查看>>
MFC ado+mysql+odbc技术分享
查看>>
路由基本命令(含中文解释)
查看>>
js中让字符串中特定字符红色显示
查看>>
HttpClient4.5教程-第二章-连接管理
查看>>
Yeslab 马老师 V2V环境下vCenter Server Heartbeat v6.4实现vCenter5.0的双机备份
查看>>
linux下定时任务
查看>>
redhat Nginx 安装
查看>>
利用START命令入侵
查看>>
oracle 配置监听
查看>>
上海访微软 详解Azure和S+S
查看>>
getAttribute()和getParameter()的区别
查看>>
跨国巨头猛攻语音识别技术 让电脑听懂人们说话
查看>>