DuiLib : 使用CListUI显示海量数据
最近遇到要在一个DuiLib::CListUI中显示动态数据的子任务.
在使用我改版的DuiLib中发现如下问题, 真杯具.
* 如果反复添加删除CListContainerElementUI, 会引起CListUI所在的Dialog退出时挂掉的问题.
e.g. 在CListUI中增加2000条数据, 在CListUI中删掉2000条数据, 如此反复20次. 再退出该CListUI所在的Dialog, UI就挂掉了.
现象是WM_PAINT陷入了一个循环(这个正常), 但是UI显示不出来了.
这个问题我回避了, 搞不定. 采用妥协的方法, 使CListUI只固定一个行数(e.g. 20行), 根据要显示的内容计算List的UI可见部分应该写什么数据.
这样, 只在建立ListUI时, 插入了新的行. 以后都是更新行上的内容. 就不存在退出时UI挂掉的问题.
* 当CListUI一次添加太多数据时(e.g. 一次添加2000行), 当滚动时, List反应特别的迟钝, 有时还会导致UI卡死.
这个问题我同样回避了, 搞不定. 采用妥协的方法, 使CListUI只固定一个行数(e.g. 20行), 根据要显示的内容计算List的UI可见部分应该写什么数据.
这样, 只在建立ListUI时, 插入了新的行. 以后都是更新行上的内容. 就不存在滚动List自带竖向滚动条时, 引起的机率性UI卡死.
这个问题让我做了5天实验, 才想到折中的解决方法.
我采用的方法是:
* 隐藏CListUI实例自带的竖向滚动条控件, 每次只显示一页的数据
* 在CListUI实例右边的Container中自己摆一个 CScrollBarUI, 用户点击滚动条时, 记录点击的位置, 发送自定义消息, 去刷新CListUI中的显示.
实验过了, 准备20W条数据, 在CListUI中显示, 也是蛮快的, 和数据多少无关, 花费的操作和显示时间都是常量.
这个折中的方法, 让我感到很欣慰.
备注:
数据的容器使用std::vector, 而不能是std::deque, 防止数据释放时, 时间太长. 20W条数据时, std::deque释放的不是一般的慢, 和构造数据的速度比较, 慢了100倍.
使用std::vector时, 构造数据和释放数据的时间是基本相同的. 在20W条数据的条件下做过实验了.
运行效果图:
- 版权申明:此文如未标注转载均为本站原创,自由转载请表明出处《博瑞博客》。
- 本文网址:http://blog.neacn.com/C/95.html
- 上篇文章:duilib DirectUI库里面的一个简单的例子RichListDemo
- 下篇文章:动态加载CListUI