SOUI原来实现的SListBoxEx的效率一直是我对SOUI不太满意的地方。包括后来网友实现的SListCtrlEx。

这类控件为每一个列表项创建一个SWindow来容纳数据,当数据量比较大(10000+)时,一方面内存消耗会很严重;另一方面列表数据初始化也需要大量的时间。

今年开始转型做Android开发。大家都知道Android开发APP和PC上开发APP相比要简单很多,其中我个人体会最深的就是Android的ListView控件。

在Android中,ListView中列表项的显示采用控件+适配器(Adapter)的模式,也就是所谓的MVC模式。一个表项在需要显示的时候才会把数据加载到View里去,当这个表项被隐藏起来以后,容纳该表项的容器(View)则自动被加入到ListView中保存的一个容器回收列表中。需要显示一个新表项时首先去回收站里查找是否存在指定类型的容器,存在则自动复用。

基本思想如上,当然实际实现还使用了很多技巧。通过上述机制,可以有效解决ListView显示大量数据的问题。

本来也一直想重写SOUI的ListBox, 这段时间正好项目需要,抽出时间模仿了一个,效果不错。

先看看效果:

第一张图是一个加载50000行的SListView控件,第二个图是演示使用SComboView来做用户登陆界面。

要在SOUI中使用SListView,我们首先需要自己实现一上数据填充的Adapter:

class CTestAdapter : public SAdapterBase
{
protected:
SListView * m_pOwenr;
public:
CTestAdapter(SListView *pOwner):m_pOwenr(pOwner)
{ }
virtual int getCount()
{
return ;
} virtual void getView(int position, SWindow * pItem)
{
if(pItem->GetChildrenCount()==)
{
pItem->InitFromXml(m_pOwenr->GetTemplate());
}
SAnimateImgWnd *pAni = pItem->FindChildByName2<SAnimateImgWnd>(L"ani_test"); SButton *pBtn = pItem->FindChildByName2<SButton>(L"btn_test");
pBtn->SetWindowText(SStringW().Format(L"button %d",position));
pBtn->SetUserData(position);
pBtn->GetEventSet()->subscribeEvent(EVT_CMD,Subscriber(&CTestAdapter::OnButtonClick,this));
} bool OnButtonClick(EventArgs *pEvt)
{
SButton *pBtn = sobj_cast<SButton>(pEvt->sender);
int iItem = pBtn->GetUserData();
SMessageBox(NULL,SStringT().Format(_T("button of %d item was clicked"),iItem),_T("haha"),MB_OK);
return true;
}
};

这里最关键的就是实现IAdapter中的getView方法。

和Android的ListView不同,SOUI中使用条件pItem->GetChildrenCount()==0来判断一个容器是否是被复用。

当pItem->GetChildrenCount()==0时代表该容器还没有被初始化,需要自己从XML模板中初始化容器。XML模板可以自己自己定义的任意符合SOUI布局语法的数据。

容器初始化完成后就可以向里面填充数据,也可以向控件连接响应函数了(subscribeEvent)。

在UI创建完成后需要在代码中把这个Adapter交给SListView:

LRESULT CMainDlg::OnInitDialog( HWND hWnd, LPARAM lParam )
{
//.... SListView *pLstView = FindChildByName2<SListView>("lv_test");
if(pLstView)
{
CTestAdapter *pAdapter = new CTestAdapter(pLstView);
pLstView->SetAdapter(pAdapter);
pAdapter->Release();
} return ;
}

第二个界面是演示SComboView的。SComboView的用户和SListView基本一样,具体看代码。

第二十六篇:两个SOUI新控件 ---- SListView和SComboView(借用Andorid的设计)的更多相关文章

  1. 第十篇:扩展SOUI的控件及绘图对象(ISkinObj)

    尽管SOUI已经内置了大部分常用的控件,很显然内置控件很难满足各种应用的形式各异的需求. 因此只有提供足够的扩展性才能满足真实应用场景. 除了将系统尽可能的组件化外,SOUI在控件自绘(SWindow ...

  2. 第二十九篇:使用SOUI的SMCListView控件

    列表控件是客户端应用最常用的控件之一.列表控件通常只负责显示数据,最多通知一下APP列表行的选中状态变化. 现在的UI经常要求程序猿在列表控件里不光显示内容,还要能和用户交互,显示动画等等,传统的列表 ...

  3. 第二十五篇:在SOUI中做事件分发处理

    不同的SOUI控件可以产生不同的事件.SOUI系统中提供了两种事件处理方式:事件订阅 + 事件处理映射表(参见第八篇:SOUI中控件事件的响应) 事件订阅由于直接将事件及事件处理函数连接,不存在事件分 ...

  4. 第二十二篇:在SOUI中使用代码向窗口中插入子窗口

    使用SOUI开发客户端UI程序,通常也推荐使用XML代码来创建窗口,这样创建的窗口使用方便,当窗口大小改变时,内部的子窗口也更容易协同变化. 但是最近不断有网友咨询如何使用代码来创建SOUI子窗口,特 ...

  5. 第二十六篇 jQuery 学习8 遍历-父亲兄弟子孙元素

    jQuery 学习8 遍历-父亲兄弟子孙元素   jQuery遍历,可以理解为“移动”,使用“移动”还获取其他的元素.   什么意思呢?老师举一个例子: 班上30位同学,我是新来负责教这个班学生的老师 ...

  6. 第二十六篇 -- wifi学习

    参考网址:https://blog.csdn.net/zwl1584671413/article/details/77936950 https://blog.csdn.net/Righthek/art ...

  7. 第二十四篇:导出SOUI对象到LUA脚本

    LUA是一种体积小,速度快的脚本语言.脚本语言虽然性能上和C++这样的Naitive语言相比差一点,但是开发速度快,可以方便的更新代码等,近年来受到了越来越多开发者的重视. 在SOUI框架中,我把脚本 ...

  8. Python之路(第二十六篇) 面向对象进阶:内置方法

    一.__getattribute__ object.__getattribute__(self, name) 无条件被调用,通过实例访问属性.如果class中定义了__getattr__(),则__g ...

  9. Python之路【第二十六篇】:HTTP协议

    HTTP协议 一.HTTP概述 HTTP(hypertext transport protocol),即超文本传输协议.这个协议详细规定了浏览器和万维网服务器之间互相通信的规则. HTTP就是通信规则 ...

随机推荐

  1. SpringBoot源码解析:tomcat启动分析

    >> spring与tomcat的启动分析:war包形式 tomcat:xml加载规范 1.contex-param: 初始化参数 2.listener-class: contextloa ...

  2. Spring 4支持的Java 8新特性一览

    有众多新特性和函数库的Java 8发布之后,Spring 4.x已经支持其中的大部分.有些Java 8的新特性对Spring无影响,可以直接使用,但另有些新特性需要Spring的支持.本文将带您浏览S ...

  3. DEDECMS标签调用汇总啊

    非常有用的标签调用的方法 关键描述调用标签: <meta name="keywords" content="{dede:field name='keywords'/ ...

  4. Debugging D Program on Windows

    http://x64dbg.com/ http://www.ollydbg.de/version2.html

  5. Python之路【第二十篇】Tornado框架

    Tornado Tornado是使用Python编写的一个强大的.可扩展的Web服务器.它在处理严峻的网络流量时表现得足够强健,但却在创建和编写时有着足够的轻量级,并能够被用在大量的应用和工具中. 我 ...

  6. Schema

    Schema约束 1.namespace 相当于schema文件的id 2.targetNamespace属性 用来指定schema文件的namespace的值 3.xmlns属性 引入一个约束,它的 ...

  7. 大熊君JavaScript插件化开发------(实战篇之DXJ UI ------ Tab)

    一,开篇分析 Hi,大家好!大熊君又和大家见面了,还记得前两篇文章吗.主要讲述了以“jQuery的方式如何开发插件”,以及过程化设计与面向对象思想设计相结合的方式是 如何设计一个插件的,两种方式各有利 ...

  8. JavaScript获取浏览器高度和宽度值(documentElement,clientHeight,offsetHeight,scrollHeight,scrollTop,offsetParent,offsetY,innerHeight)

    IE中: document.body.clientWidth ==> BODY对象宽度 document.body.clientHeight ==> BODY对象高度 document.d ...

  9. 使用git status快速commit

    提交之前使用git status可以看到将要提交的文件,如果想部分提交,需要单独commit.使用下面这句可以快速commit git commit `git status | grep 'mod' ...

  10. mrjob 使用 mongodb 作为数据源

    When using a mongoDB collection as input, add the arguments -jobconf mongo.input.uri=<input mongo ...