列表视图控件 (SListView)¶
Warning
The current page still doesn't have a translation for this language.
You can read it through google translate.
SOUI中的高性能列表视图控件,基于虚拟化技术实现,支持大量数据的高效显示和滚动。适用于显示单列数据列表,每个项目可以使用自定义模板。
基本信息¶
- 类名:
SListView
- 控件标签:
listview
- 基类:
SPanel
- 功能:提供高性能单列数据列表展示
属性说明¶
基本属性¶
属性名 | 类型 | 默认值 | 说明 |
---|---|---|---|
dividerSize | int | - | 分割行高度 |
wantTab | bool | - | 是否处理tab按键(0-不处理,1-处理) |
vertical | bool | - | 列表排列方式(0-水平,1-垂直) |
外观属性¶
属性名 | 类型 | 默认值 | 说明 |
---|---|---|---|
dividerSkin | string | - | 分割行皮肤 |
使用示例¶
基础列表视图¶
<!-- 基础列表视图 -->
<listview pos="10,10,-10,-10" name="lv_basic"
dividerSize="1" vertical="1" wantTab="0">
<template itemHeight="50" colorHover="#f1f1f1"
colorSelected="#cccccc">
<window>
<text pos="10,|-15" name="txt_name"/>
<text pos="[10,|-15" name="txt_desc"/>
</window>
</template>
</listview>
自定义样式列表视图¶
<!-- 自定义样式列表视图 -->
<listview pos="10,10,-10,-10" name="lv_custom"
dividerSize="2" dividerSkin="skin_divider"
wantTab="1" vertical="1">
<template>
<window>
<img pos="10,10,70,70" name="img_icon"/>
<text pos="80,15" name="txt_title" font="bold:1"/>
<text pos="80,40" name="txt_content"
colorText="#666666"/>
<button pos="-80,|-15" name="btn_action"
skin="skin_btn"/>
</window>
</template>
</listview>
水平排列列表视图¶
<!-- 水平排列列表视图 -->
<listview pos="10,10,-10,110" name="lv_horizontal"
dividerSize="5" vertical="0" wantTab="0">
<template itemHeight="100" itemWidth="150">
<window>
<img pos="10,10,140,90" name="img_icon"/>
</window>
</template>
</listview>
事件处理¶
列表视图控件支持以下事件:
事件名 | EventID | 说明 |
---|---|---|
EVT_LV_SELCHANGING | EventLVSelChanging::EventID | 选择改变前事件 |
EVT_LV_SELCHANGED | EventLVSelChanged::EventID | 选择改变事件 |
EVT_LV_ITEMCLICK | EventLVItemClick::EventID | 项目双击事件 |
// 事件处理示例
EVENT_MAP_BEGIN()
EVENT_NAME_HANDLER(L"lv_basic", EventLVSelChanged::EventID, OnLVSelChanged)
EVENT_NAME_HANDLER(L"lv_basic", EventLVItemClick::EventID, OnLVItemClick)
EVENT_MAP_END()
void OnLVSelChanged(IEvtArgs *pEvt)
{
EventLVSelChanged *pRealEvt = sobj_cast<EventLVSelChanged>(pEvt);
int nOldSel = pRealEvt->nOldSel;
int nNewSel = pRealEvt->nNewSel;
// 处理选择改变事件
}
void OnLVItemClick(IEvtArgs *pEvt)
{
EventLVItemClick *pRealEvt = sobj_cast<EventLVItemClick>(pEvt);
int nItem = pRealEvt->nItem;
// 处理项目点击事件
}
代码操作¶
// 查找列表视图控件
SListView *pListView = FindChildByName2<SListView>(L"lv_basic");
// 设置适配器
pListView->SetAdapter(pAdapter);
// 获取当前选中项
int nCurSel = pListView->GetSel();
// 设置选中项
pListView->SetSel(0);
// 获取项目数量
int nCount = pListView->GetCount();
// 滚动到指定项
pListView->EnsureVisible(10);
实现自定义适配器¶
#include <helper/SAdapterBase.h>
// 定义数据结构
struct ListItemData
{
SStringT strName;
SStringT strDesc;
SStringT strIconSkin;
};
// 实现自定义适配器
class CListAdapter : public SAdapterBase
{
protected:
SArray<ListItemData> m_dataList;
public:
// 获取项目数量,注意 WINAPI 调用约定
virtual int WINAPI getCount()
{
return m_dataList.GetCount();
}
// 获取视图,注意 WINAPI 调用约定
virtual void WINAPI getView(int position, SItemPanel* pItem, SXmlNode xmlTemplate)
{
if(pItem->GetChildrenCount() == 0)
{
pItem->InitFromXml(&xmlTemplate);
}
if(position >= 0 && position < m_dataList.GetCount())
{
const ListItemData& data = m_dataList[position];
// 设置名称
SWindow* pName = pItem->FindChildByName(L"txt_name");
if(pName)
{
pName->SetWindowText(data.strName);
}
// 设置描述
SWindow* pDesc = pItem->FindChildByName(L"txt_desc");
if(pDesc)
{
pDesc->SetWindowText(data.strDesc);
}
// 设置图标
SWindow* pIcon = pItem->FindChildByName(L"img_icon");
if(pIcon)
{
pIcon->SetAttribute(L"skin", data.strIconSkin);
}
}
}
// 添加数据
void AddItem(const ListItemData& item)
{
m_dataList.Add(item);
notifyDataSetChanged(); // 通知视图更新
}
// 获取指定位置的数据
const ListItemData& GetItem(int position)
{
return m_dataList[position];
}
};
// 使用示例
void InitListView()
{
SListView* pListView = FindChildByName2<SListView>(L"lv_basic");
if(pListView)
{
CListAdapter* pAdapter = new CListAdapter();
// 添加测试数据
for(int i = 0; i < 20; i++)
{
ListItemData item;
item.strName.Format(L"项目 %d", i+1);
item.strDesc.Format(L"这是项目 %d 的描述", i+1);
item.strIconSkin = L"skin_icon";
pAdapter->AddItem(item);
}
// 设置适配器
pListView->SetAdapter(pAdapter);
pAdapter->Release(); // 释放引用计数
}
}
最佳实践¶
- 性能优化:使用虚拟化技术,只渲染可见区域的项目
- 交互设计:根据需要设置 wantTab 属性处理Tab键导航
- 视觉效果:通过 dividerSkin 和 dividerSize 属性美化项目分隔
- 布局方向:使用 vertical 属性选择合适的排列方向
常见问题¶
Q: 数据修改后如何刷新视图?¶
A: 如果要刷新全部视图,通过调用 adapter->notifyDataSetChanged() 方法刷新;如果只需要刷新指定的项目,可以通过调用 adapter->notifyItemChanged(position) 方法。
Q: 列表中的edit不响应回车等按键怎么办?¶
A: 确保设置了 wantTab 为 1,默认wantTab为0, 确保tab可以跳转,wantTab为0时,listview会将所有键盘事件转发给第一个可获取焦点的子窗口,这样里面的edit才可以响应这些功能键,其它mvc view也适用这个规则。
Q: 列表项显示不完整怎么办?¶
A: 检查 template 中的 itemHeight 是否设置正确,确保与实际内容高度匹配。
Q: 分隔线显示异常怎么办?¶
A: 检查 dividerSkin 和 dividerSize 是否正确设置。
相关控件¶
- 多列列表视图(SMCListView) - 支持多列显示的列表视图
- 平铺视图(STileView) - 网格形式展示项目的视图
- 树形视图(STreeView) - 支持层级结构数据展示的视图