本文选自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<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:我忘记了一些东西,请不要建议任何库,我想在不使用外部库的情况下完成它。

答案:

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。(#换成@)


滚动ListView时图像顺序混乱的更多相关文章

  1. 用caffe给图像的混乱程度打分

    Caffe应该是目前深度学习领域应用最广泛的几大框架之一了,尤其是视觉领域.绝大多数用Caffe的人,应该用的都是基于分类的网络,但有的时候也许会有基于回归的视觉应用的需要,查了一下Caffe官网,还 ...

  2. Javascript动态加载Html元素到页面Dom文档结构时执行顺序的不同

    我们有时会通过ajax动态获取一段Html代码,并且将这段代码通过javascript放到页面的Dom结构中去. 而很多时候通过ajax动态获取的Html代码中也包含javascript代码,有一点需 ...

  3. 如何在滚动报表时保持标题可见 (Reporting Services)

    From: https://msdn.microsoft.com/zh-cn/library/bb934257.aspx 对于跨多页的表或矩阵数据区域,可以控制滚动报表时是否始终显示包含列标题的初始行 ...

  4. Winform 打印PDF顺序混乱,获取打印队列

    工作中PDF打印顺序混乱着实让我疼痛了好久,其实决绝方法非常简单,但没有想到这个点子的时候确实让我走了很多弯路 这里文章写出来并不是为了炫耀什么,只是觉得发现些好东西就分享出来而已,同时也做个记录,方 ...

  5. 使用ListView时遇到的问题

    这周练习ListView时遇到了一个问题,从数据库中查询出的数据绑定到LIstView上,长按某个item进行删除操作,每次点击item取得的id都不对,调了半天终于找到了原因,关键是自己对自定义的B ...

  6. 滚动页面时DIV到达顶部时固定在顶部

    本示例使用Javascript实现了滚动页面时,DIV到达顶部时固定在顶部.在IE下效果有点闪,效果网址:http://www.keleyi.com/keleyi/phtml/fixdiv.htm 下 ...

  7. java 访问后台方法顺序混乱

    今天遇到后台接值顺序混乱的问题. 环境:前台ajax请求后台方法.前台页面会频繁访问这个ajax. 现象:访问后台方法的顺序混乱. 怎么发现的问题:数量小访问没有问题,今天压力测试发现的问题. 解决办 ...

  8. C# 在RichTextBox中滚动鼠标时滚动的是父窗口的滚动条

    1. RichTextBox u2 = new RichTextBox(); 2. 先记住日RichTextBox没有显示滚动条时的总宽度和显示宽度 u2.Width - u2.ClientSize. ...

  9. html5 video使用autoplay属性时,声音混乱

    html5 video使用autoplay属性时,声音混乱 页面代码 Index.html <html xmlns="http://www.w3.org/1999/xhtml" ...

随机推荐

  1. 【转】Restful是什么

    REST的概念是什么 维基百科  表现层状态转换(REST,英文:Representational State Transfer)是Roy Thomas Fielding博士于2000年在他的博士论文 ...

  2. echarts使用笔记三:柱子对比

    app.title = '坐标轴刻度与标签对齐'; option = { title : { //标题 x : 'center', y : 5, text : '对比图' //换行用 \n }, le ...

  3. promise-笔记

    promise 封装Promise var fs = require('fs') function pReadFile(filePath) { return new Promise(function ...

  4. OpenStack 与 Rancher

    OpenStack 与 Rancher 融合的新玩法 - Rancher - SegmentFault 思否https://segmentfault.com/a/1190000007965378 Op ...

  5. MYSQL 创建数据库SQL

    CREATE DATABASE crm CHARACTER SET utf8 COLLATE utf8_general_ci; MySQL :: MySQL 5.7 Reference Manual ...

  6. JMeter中返回Json数据的处理方法(转)

    Json 作为一种数据交换格式在网络开发,特别是 Ajax 与 Restful 架构中应用的越来越广泛.而 Apache 的 JMeter 也是较受欢迎的压力测试工具之一,但是它本身没有提供对于 Js ...

  7. Laravel 5.2+ 使用url()全局函数返回前一个页面的地址

    注意:文章标题中5.2+表示该文章内容可向上兼容,适用于Laravel版本5.2及更高(目前最新为5.6),但不可向下兼容,即不适用于5.2版本以下.推荐大家花一点点时间,将自己的Laravel更新至 ...

  8. vue.js 添加 fastclick的支持

    fastclick:处理移动端click事件300毫秒延迟 1.兼容性 iOS 3及更高版本的移动Safari iOS 5及更高版本的Chrome Android上的Chrome(ICS) Opera ...

  9. 排查 Maxwell can not find database 并且使用 MySQL binlog 解决相关问题

    目前我们在使用 Maxwell 在读线上机器的 binlog 同步我们的离线数据库. 这次错误定位上,首先线要确定问题是发生在生产者 还是队列 还是消费者.经过查看各机器上任务的运行日志,定位到了问题 ...

  10. css & clearfix & clear-fixed

    css & clearfix & clear-fixed https://zzk.cnblogs.com/my/s/blogpost-p?Keywords=clearfix .grou ...