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. Pycharm 输出中文或打印中文乱码现象的解决办法

    1. 确保文件开头加上以下代码: # -*- coding:utf-8 -*- 还可以加上 import sys reload(sys) sys.setdefaultencoding('utf-8') ...

  2. Jsoup提取文本时保留标签

    使用Jsoup来对html进行处理比较方便,你可能会用它来提取文本或清理html标签.如果你想提取文本时保留标签,可以使用Jsoup.clean方法,参数为html及标签白名单: Jsoup.clea ...

  3. tyvj1202 数数食物链

    描述 TsyD学习了生物的生态环境那一张后,老师留了一项作业,就是给一张食物网,求所有食物链的总数.(从最低营养级生物(它不能吃任何其他的生物)开始到最高营养级(它不能被任何其他生物吃) 叫做一条食物 ...

  4. avl树的操作证明

    以下用大O表示节点,ABC表示三个集合. 仅分析左子树的情况,因为对称,右子树的情况一样. 插入节点前 O /     \ O        A   /    \ B       C 插入节点后: O ...

  5. [Scala] 快学Scala A1L1

    基础 1.1 声明值和变量 在Scala中,鼓励使用val; 不需要给出值或变量的类型,这个信息可以从初始化表达式推断出来.在必要的时候,可以指定类型. 在Scala中,仅当同一行代码中存在多条语句时 ...

  6. UI第八节——UISegmentedControl

    - (void)viewDidLoad {    [super viewDidLoad];    NSArray *items = @[@"消息", @"电话" ...

  7. JS自动缩放页面图片

    /** * 缩略图 * * @param bool isScaling 是否缩放 * @param int width 宽度 * @param int height 高度 * @param strin ...

  8. Linux C 字符串输出函数 puts()、fputs()、printf() 详解

    一.puts() 函数详解 puts()函数用来向 标准输出设备 (屏幕)写字符串并换行,调用格式为: puts(s); 其中s为字符串变量(字符串数组名或字符串指针). puts()函数的作用与语 ...

  9. [转]hql 语法与详细解释

    HQL查询:Criteria查询对查询条件进行了面向对象封装,符合编程人员的思维方式,不过HQL(Hibernate Query Lanaguage)查询提供了更加丰富的和灵活的查询特性,因此 Hib ...

  10. mysql sql优化实例

    mysql sql优化实例 优化前: pt-query-degist分析结果: # Query 3: 0.00 QPS, 0.00x concurrency, ID 0xDC6E62FA021C85B ...