nim_duilib之virtualListbox用法(22)
概述
- 本文将介绍virtualListbox的用法。
- 更多请参考源码。
一个样式
样式丑了点,勿喷。

重写函数
使用virtualListbox, 需要一个派生类(继承自基类VirtualListInterface)重写父类的以下3个函数
class VirtualListInterface
{
public:
/**
* @brief 创建一个子项
* @return 返回创建后的子项指针
*/
virtual Control* CreateElement() = 0;
/**
* @brief 填充指定子项
* @param[in] control 子项控件指针
* @param[in] index 索引
* @return 返回创建后的子项指针
*/
virtual void FillElement(Control *control, int index) = 0;
/**
* @brief 获取子项总数
* @return 返回子项总数
*/
virtual int GetElementtCount() = 0;
};
session_list类
- 自己定义了一个类,并继承了VirtualListInterface类。
{
public:
explicit session_list(ui::VirtualListBox* pvlb) :plistbox_(pvlb) {}
session_list() {}
// 初始化参数
int init(ui::VirtualListBox* pvlb);
.......
}
- 重写下面3个函数后,virtualListbox(它的数据代理类型VirtualListInterface类型)会自动调用下面的函数。
CreateElement 函数
- 如其名,负责创建一个list_item,我们可以定制自己item的样式, 创建就需要写在这里。
- 我的重写如下:
ui::Control* session_list::CreateElement()
{
session_list_item* pitem = new(std::nothrow) session_list_item;
if (NULL == pitem)
return nullptr;
std::wstring session_item_xml(L"list_session/sersson_item.xml");
ui::GlobalManager::FillBoxWithCache(pitem, session_item_xml);
// 关联item中的控件
pitem->init_controls_();
return pitem;
}
这里创建一个新的item, 其中sersson_item.xml,是item的自定义布局,后面贴其完整源码
FillElement
它负责填充数据,比如,上面创建了item,item中的显示内容可以放在这个函数实现。
void session_list::FillElement(ui::Control *control, int index)
{
if (nullptr == control || NULL == control || 0 > index)
return;
session_list_item* pitem = (session_list_item *)(control);
// 定制显示数据
pitem->init_data_();
}
GetElementtCount
告诉当前有多少个item. 比如,100, 2000, 我这里设置的是20.
int session_list::GetElementtCount()
{
return 20;
}
还需要
上面仅仅是定制了item, 要显示, 需要下面的函数配合使用才能达到效果
plistbox_->SetDataProvider(this);
plistbox_->SetElementHeight(50);
plistbox_->InitElement(20);
plistbox_->Refresh();
SetDataProvider
需要显示指定其数据代理的对象。 我这里传递的是this, 是因为我自己定义的类是继承的VirtualListInterface
SetElementHeight
设置子项高度, 示例中,使用DPI,额,我这里就先跳过。我这里设置的是50, 可以参考自己的session_item.xml中定义的height.
下面开始介绍item的个性化
ListContainerElement类
同样的,需要自己新增一个类 继承自ListContainerElement。 负责与界面控件的关联就写在这个派生类中,函数名可以自定义,下面的两个函数非父类的函数。
class session_list_item :public ui::ListContainerElement
{
public:
// 关联控件
virtual int init_controls_();
// 设置初始化数据
int init_data_();
private:
// 下面的控件用于与界面的控件绑定
// 头像
ui::Label* label_protrait_ = nullptr;
// 姓名
ui::Label* label_name_ = nullptr;
// 最新消息
ui::RichEdit* rich_edit_last_msg_ = nullptr;
// 最新消息时间
ui::Label* label_last_msg_time_ = nullptr;
// 是否静音
ui::Label* label_is_muted_ = nullptr;
};
init_controls_
我把初始化控件放在了这个函数中,当创建了item,再调用该函数完成控件绑定
int session_list_item::init_controls_()
{
auto find_sub_ctrl = [&](const std::wstring name, ui::Label* pdst)
{
ui::Control* ptmp = FindSubControl(name);
if (ptmp)
label_protrait_ = dynamic_cast<ui::Label*>(ptmp);
};
// 1.关联其他label控件
find_sub_ctrl(L"label_portrait", label_protrait_);
find_sub_ctrl(L"label_name", label_name_);
find_sub_ctrl(L"label_last_msg_time", label_last_msg_time_);
find_sub_ctrl(L"label_is_muted", label_is_muted_);
// 2.关联上一条消息控件
ui::Control* ptmp = FindSubControl(L"rich_edit_last_msg");
if (ptmp)
rich_edit_last_msg_ = dynamic_cast<ui::RichEdit*>(ptmp);
return 0;
}
init_data_
item显示的内容的填充,可以放到这个函数中,FillElement函数中可以调用该函数完成数据绑定。
int session_list_item::init_data_()
{
//if (rich_edit_last_msg_)
// rich_edit_last_msg_->SetText(L"33");
auto set_text = [&](ui::Label*label, std::wstring str)
{
if (label)
label->SetText(str);
};
static int index = 0;
std::wstring str = fmt::format(L"{}", ++index);
set_text(label_protrait_, str);
//set_text(label_name_, L"22");
//set_text(label_last_msg_time_, L"33");
//set_text(label_is_muted_, L"44");
return 0;
}
session_item.xml
- 单独维护item的样式,很方便。 上面例子中的item样式定义如下

- 整体采用水平布局。
- xml源码内容
<?xml version="1.0" encoding="UTF-8"?>
<Window>
<ListContainerElement class="listitem" normalcolor="bk_wnd_lightcolor" height="60" margin="0,3,0,3">
<!--整体水平布局-->
<HBox width="stretch" height="stretch">
<!--头像-->
<Label name="label_portrait" text="头像" width="50" height="50" bkcolor="green" />
<!--中间显示部分:姓名和上一条消息-->
<VBox width="stretch" height="stretch" bkcolor="red">
<!--姓名-->
<Label text="王老板" name="label_name" width="stretch"/>
<Control />
<!--上一条消息-->
<RichEdit text="这个月加班XXXXXXXXX" name="rich_edit_last_msg" multiline="false" vscrollbar="false" autovscroll="autovscroll" readonly="true" />
</VBox>
<!--右侧显示的事件和是否显示提醒图标-->
<VBox width="50" height="stretch" bkcolor="bk_listitem_selected" >
<!--上一条消息时间-->
<Label name="label_last_msg_time" text="08:08" />
<Control />
<!--是否显示消息提醒图标-->
<Label name="label_is_muted" text="静音" />
</VBox>
</HBox>
<!--整体水平布局-->
</ListContainerElement>
</Window>
virtualListbox的xml
其定义不在上面的sesson_item.xml,如下,
<Box name="box_list_box" width="stretch" height="stretch">
<VirtualListBox class="list" name="virtual_list_box" vscrollunit="1" bkcolor="green" margin="10,0,0,0" vscrollbar="true" />
</Box>
nim_duilib之virtualListbox用法(22)的更多相关文章
- nim_duilib之msgbox用法(23)
概述 本文将介绍 msgbox 的用法 更多用法,请参考 源码 改进了原有的xml样式 一个样式 xml结构 整体垂直布局 xml源码 demo源码下的msg/msg.xml文件内容 改为如下 注意: ...
- 使用 Log4Net 记录日志
第一步:下载Log4Net 下载地址:http://logging.apache.org/log4net/download_log4net.cgi 把下载的 log4net-1.2.11-bin-n ...
- [转]C#使用Log4Net记录日志
第一步:下载Log4Net 下载地址:http://logging.apache.org/log4net/download_log4net.cgi 把下载的 log4net-1.2.11-bin-n ...
- C# Log4Net 日志
C#使用Log4Net记录日志 第一步:下载Log4Net 下载地址:http://logging.apache.org/log4net/download_log4net.cgi ...
- C#使用Log4Net记录日志(转)
出处:http://www.cnblogs.com/wangsaiming/archive/2013/01/11/2856253.html 第一步:下载Log4Net 下载地址:http://logg ...
- C# 知识点集合
1.一个Visual studio软件进程只能打开一个程序集,但是一个程序集可以加载多个项目,通过程序集的添加功能可以实现. 2.F11单步调试,F10跨程序调试(一般用不到) 3.VS如何快速的切换 ...
- Log4Net记录日志(mvc)
转自:http://blog.csdn.net/zhoufoxcn/article/details/2220533 感谢:柄棋先生 第一步:下载Log4Net 下载地址:http://logging. ...
- 小白—职场之Java基础篇
java基础篇 java基础 目录 1.java是一种什么语言,jdk,jre,jvm三者的区别 2.java 1.5之后的三大版本 3.java跨平台及其原理 4.java 语言的特点 5.什么是字 ...
- STL—— 容器(vector)的数据写入、修改和删除
1. 通过 push_back() 尾部增加一个元素 : vector 可以通过 "push_back " 写入数据,通过 push_back 可以将数据直接写入至 vector ...
随机推荐
- 洛谷 P4663 - [BalticOI 2008]魔法石(dp)
题面传送门 A:我该是有多无聊来写这种题的题解啊 B:大概是因为这题题解区里没有题解所以我来写一篇了,说明我有高尚的济世情怀(大雾 跑题了跑题了 首先看到字典序第 \(i\) 小小可以自然地想到按位决 ...
- python的包与模块
win +R d
- eclipse 配置黑色主题(转载)
转载:http://www.cnblogs.com/csulennon/p/4231405.html 虽然以前也使用eclipse的黑色主题,但是配置起来稍微麻烦一点. 这里先声明,下面的方式适合最新 ...
- Linux搭建yum仓库
1.安装nginx 2.为nginx搭建共享目录 3.安装createrepo,创建存储库 4.客户端测试 1.安装nginx yum list |grep nginx #查看是否有可用的nginx包 ...
- Label -- 跳出循环的思路
let num = 0 ; outPoint: //label for (let i = 0; i < 10; i++) { for ( let j = 0; j < 10; j++) { ...
- 多线程高级篇1 — JUC — 只弄到处理高并发集合问题
1.线程池 1.1).什么是线程池? 池( pool ),就是一个容器,所以线程池就是把多个线程对象放到一个容器中 1.2).如何创建线程池? 先来了解几个常识 Executor -- 这是一个接口( ...
- TCP的慢启动、拥塞避免、重传、快恢复乱七八糟总是记不清?11个连环问让你一次性打通任督二脉
摘要:如果你的开发过程涉及数据传输,一直在重传.超时之类的方案里有困惑的话,不妨重新学一学可靠性最精致的TCP协议. 本文分享自华为云社区<TCP的慢启动.拥塞避免.重传.快恢复乱七八糟总是记不 ...
- A Child's History of England.17
CHAPTER 6 ENGLAND UNDER HAROLD HAREFOOT, HARDICANUTE, AND EDWARD THE CONFESSOR Canute left three son ...
- 27.0 linux VM虚拟机IP问题
我的虚拟机是每次换一个不同的网络,b不同的ip,使用桥接模式就无法连接,就需要重新还原默认设置才行: 第一步:点击虚拟机中的编辑-->虚拟网络编辑器 第二步:点击更改设置以管理员权限进入 第三步 ...
- 大数据学习day36-----flume02--------1.avro source和kafka source 2. 拦截器(Interceptor) 3. channel详解 4 sink 5 slector(选择器)6 sink processor
1.avro source和kafka source 1.1 avro source avro source是通过监听一个网络端口来收数据,而且接受的数据必须是使用avro序列化框架序列化后的数据.a ...