平铺视图控件 (STileView)¶
Warning
The current page still doesn't have a translation for this language.
You can read it through google translate.
SOUI中的平铺视图控件,以网格形式展示项目,支持自适应布局和固定大小布局,适用于图片、图标等内容的网格展示。基于虚拟化技术实现,可以高效处理大量数据。
基本信息¶
- 类名:
STileView
- 控件标签:
tileview
- 基类:
SPanel
- 功能:提供网格形式的项目展示
属性说明¶
基本属性¶
属性名 | 类型 | 默认值 | 说明 |
---|---|---|---|
marginSize | int | - | 边框大小 |
wantTab | bool | - | 是否处理tab按键(0-不处理,1-处理) |
align | int | left | left,center,right, 用于水平对齐方式 |
使用示例¶
基础平铺视图¶
<!-- 基础平铺视图 -->
<tileview pos="10,10,-10,-10" name="tile_basic"
marginSize="10" wantTab="0">
<template>
<window>
<img pos="10,10,-10,-40" name="img_icon"/>
<text pos="10,-30,-10,-10" name="txt_name"
align="center"/>
</window>
</template>
</tileview>
自定义样式平铺视图¶
<!-- 自定义样式平铺视图 -->
<tileview pos="10,10,-10,-10" name="tile_custom"
marginSize="15" wantTab="1">
<template>
<window colorBkgnd="#FFFFFF">
<img pos="10,10,-10,130" name="img_cover"/>
<text pos="10,135,-10,155" name="txt_title"
font="bold:1"/>
<text pos="10,160,-10,175" name="txt_desc"
colorText="#666666"/>
</window>
</template>
</tileview>
带选择效果的平铺视图¶
<!-- 带选择效果的平铺视图 -->
<tileview pos="10,10,-10,-10" name="tile_select"
marginSize="10" wantTab="0" selectionMode="1">
<template>
<window layout="vbox" padding="5" colorBkgnd="#F5F5F5">
<img name="img_thumb" size="0,0" flex="1"
scale="1" margin="0,0,0,5"/>
<text name="txt_name" size="0,20" align="center"
font="size:14"/>
<check name="chk_select" size="16,16"
align="center" text="选择"/>
</window>
</template>
</tileview>
代码示例¶
#include <helper/SAdapterBase.h>
// 创建平铺视图适配器
class CTileAdapter : public SAdapterBase
{
protected:
SArray<TileItemData> m_items;
public:
// 获取项目数量,注意 WINAPI 调用约定
virtual int WINAPI getCount()
{
return m_items.GetCount();
}
// 获取项目视图,注意 WINAPI 调用约定
virtual void WINAPI getView(int position, SItemPanel* pItem,
SXmlNode xmlTemplate)
{
if(!pItem) return;
// 初始化模板
if(pItem->GetChildrenCount() == 0)
{
pItem->InitFromXml(&xmlTemplate);
// 订阅复选框事件
SWindow* pCheck = pItem->FindChildByName(L"chk_select");
if(pCheck)
{
pCheck->GetEventSet()->subscribeEvent(
EventCmd::EventID,
Subscriber(&CTileAdapter::OnCheckChanged, this));
}
}
const TileItemData &item = m_items[position];
// 设置图标
SImageWnd *pImg =
pItem->FindChildByName2<SImageWnd>(L"img_icon");
if(pImg)
{
pImg->SetAttribute(L"skin", item.strIcon);
}
// 设置名称
SWindow *pName =
pItem->FindChildByName(L"txt_name");
if(pName)
{
pName->SetWindowText(item.strName);
}
}
// 处理复选框变化
bool OnCheckChanged(EventArgs* pEvt)
{
SWindow* pCheck = sobj_cast<SWindow>(pEvt->sender);
if(pCheck)
{
SItemPanel* pItem = sobj_cast<SItemPanel>(pCheck->GetParent());
if(pItem)
{
int nIndex = (int)pItem->GetItemIndex();
bool bChecked = pCheck->GetCheck();
// 处理选中状态变化
HandleCheckChanged(nIndex, bChecked);
}
}
return true;
}
// 添加项目
void AddItem(const TileItemData &item)
{
m_items.Add(item);
notifyDataSetChanged();
}
// 获取项目数据
const TileItemData& GetItem(int nIndex) const
{
return m_items[nIndex];
}
};
// 使用平铺视图
void InitTileView()
{
// 获取平铺视图控件
STileView *pTileView =
FindChildByName2<STileView>(L"tile_demo");
if(pTileView)
{
// 创建适配器
CTileAdapter *pAdapter = new CTileAdapter();
// 添加测试数据
for(int i = 0; i < 100; i++)
{
TileItemData item;
item.strName.Format(L"项目 %d", i + 1);
item.strIcon.Format(L"skin_icon_%d", i % 10);
pAdapter->AddItem(item);
}
// 设置适配器
pTileView->SetAdapter(pAdapter);
pAdapter->Release();
// 订阅选择变化事件
pTileView->GetEventSet()->subscribeEvent(
EventTileViewSelChanged::EventID,
Subscriber(&CMainDlg::OnTileSelChanged, this));
}
}
事件处理¶
平铺视图控件支持以下事件:
事件名 | EventID | 说明 |
---|---|---|
EVT_LV_SELCHANGIING | EventLVSelChangiing::EventID | 选择改变前事件 |
EVT_LV_SELCHANGED | EventLVSelChanged::EventID | 选择改变事件 |
EVT_LV_ITEMCLICK | EventLVItemClick::EventID | 项目点击事件 |
// 事件处理示例
EVENT_MAP_BEGIN()
EVENT_NAME_HANDLER(L"tile_basic", EventLVSelChanged::EventID, OnLVSelChanged)
EVENT_NAME_HANDLER(L"tile_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 OnLVItemDbClick(IEvtArgs *pEvt)
{
EventLVItemClick *pRealEvt = sobj_cast<EventLVItemClick>(pEvt);
int nItem = pRealEvt->nItem;
// 处理项目点击事件
}
代码操作¶
// 查找平铺视图控件
STileView *pTileView = FindChildByName2<STileView>(L"tile_basic");
// 设置适配器
pTileView->SetAdapter(pAdapter);
// 获取当前选中项
int nCurSel = pTileView->GetSel();
// 设置选中项
pTileView->SetSel(0);
// 获取项目数量
int nCount = pTileView->GetCount();
// 滚动到指定项
pTileView->EnsureVisible(15);
// 设置边距
pTileView->SetAttribute(L"marginSize", L"20");
实现图片浏览器示例¶
#include <helper/SAdapterBase.h>
// 图片项数据结构
struct ImageItemData
{
SStringT strName; // 图片名称
SStringT strPath; // 图片路径
SStringT strThumbSkin; // 缩略图皮肤
DWORD dwFileSize; // 文件大小
SYSTEMTIME stModified; // 修改时间
};
// 图片浏览器适配器
class CImageAdapter : public SAdapterBase
{
protected:
SArray<ImageItemData> m_images;
public:
// 获取项目数量,注意 WINAPI 调用约定
virtual int WINAPI getCount()
{
return m_images.GetCount();
}
// 获取视图,注意 WINAPI 调用约定
virtual void WINAPI getView(int position, SItemPanel* pItem, SXmlNode xmlTemplate)
{
if(pItem->GetChildrenCount() == 0)
{
pItem->InitFromXml(&xmlTemplate);
}
if(position >= 0 && position < m_images.GetCount())
{
const ImageItemData& imageData = m_images[position];
// 设置缩略图
SWindow* pThumb = pItem->FindChildByName(L"img_thumb");
if(pThumb)
{
pThumb->SetAttribute(L"skin", imageData.strThumbSkin);
}
// 设置名称
SWindow* pName = pItem->FindChildByName(L"txt_name");
if(pName)
{
pName->SetWindowText(imageData.strName);
}
// 设置大小
SWindow* pSize = pItem->FindChildByName(L"txt_size");
if(pSize)
{
SStringT strSize;
if(imageData.dwFileSize < 1024)
strSize.Format(L"%d B", imageData.dwFileSize);
else if(imageData.dwFileSize < 1024 * 1024)
strSize.Format(L"%.1f KB", (float)imageData.dwFileSize / 1024);
else
strSize.Format(L"%.1f MB", (float)imageData.dwFileSize / (1024 * 1024));
pSize->SetWindowText(strSize);
}
// 设置修改时间
SWindow* pDate = pItem->FindChildByName(L"txt_date");
if(pDate)
{
SStringT strDate;
strDate.Format(L"%04d-%02d-%02d",
imageData.stModified.wYear,
imageData.stModified.wMonth,
imageData.stModified.wDay);
pDate->SetWindowText(strDate);
}
}
}
// 添加图片
void AddImage(const ImageItemData& image)
{
m_images.Add(image);
notifyDataSetChanged();
}
// 获取指定位置的图片数据
const ImageItemData& GetImage(int position)
{
return m_images[position];
}
// 清空所有图片
void Clear()
{
m_images.RemoveAll();
notifyDataSetChanged();
}
};
// 图片浏览器初始化
void InitImageViewer()
{
STileView* pTileView = FindChildByName2<STileView>(L"tile_images");
if(pTileView)
{
CImageAdapter* pAdapter = new CImageAdapter();
// 模拟添加图片数据
for(int i = 0; i < 50; i++)
{
ImageItemData image;
image.strName.Format(L"图片%d.jpg", i+1);
image.strPath.Format(L"C:\\图片\\图片%d.jpg", i+1);
image.strThumbSkin.Format(L"skin_thumb_%d", i % 10);
image.dwFileSize = (i + 1) * 1024 * 50; // 模拟不同大小
// 设置修改时间
GetLocalTime(&image.stModified);
image.stModified.wDay -= i % 30; // 模拟不同日期
pAdapter->AddImage(image);
}
// 设置适配器
pTileView->SetAdapter(pAdapter);
pAdapter->Release();
}
}
// 处理图片选择
void OnImageSelected(int nIndex)
{
STileView* pTileView = FindChildByName2<STileView>(L"tile_images");
if(pTileView)
{
CImageAdapter* pAdapter = (CImageAdapter*)pTileView->GetAdapter();
if(pAdapter)
{
const ImageItemData& image = pAdapter->GetImage(nIndex);
// 处理图片选择,例如显示大图
ShowLargeImage(image.strPath);
}
}
}
// 显示大图(示例函数)
void ShowLargeImage(const SStringT& strImagePath)
{
// 实现显示大图的逻辑
// 例如打开一个新的窗口显示大图
}
最佳实践¶
- 间距控制:通过 marginSize 属性控制项目间距,确保布局美观
- 键盘导航:根据需要设置 wantTab 属性处理Tab键导航
- 尺寸设计:合理设计项目尺寸,确保内容完整显示且布局协调
常见问题¶
Q: 项目间距过大或过小怎么办?¶
A: 调整 marginSize 属性值,设置合适的边框大小。
Q: Tab键导航不工作怎么办?¶
A: 确保设置了 wantTab 为 1,并正确处理相关事件。
Q: 项目显示不完整怎么办?¶
A: 检查 template 中的 itemWidth 和 itemHeight 是否设置正确。
相关控件¶
- 列表视图(SListView) - 单列数据列表视图
- 多列列表视图(SMCListView) - 支持多列显示的列表视图
- 树形视图(STreeView) - 支持层级结构数据展示的视图