Duilib List中Item内容切换效果

先看几个效果:

在正常状态下是这样的
鼠标经过是这样的:
选中的时候是这样的:

这里以List为容器实现这样的切换效果(当然也可以使用Tree实现):

项目地址:github(https://github.com/Washington-DC/Duilib-ListView)

1、首先,每个Item有这样的几种布局界面,需要将这几种布局包含在TabLayout中,使用TabLayout进行布局的切换。如图,包含了这三种状态的布局。Duilib List中Item内容切换效果_第1张图片

2、创建一个List的布局文件,这里我用自定义的ListView标签。



    
        
        
    
3、继承 CListContainerElementUI 类实现我们自己的ListItem,并重写 DoEvent 方法。
class CListItemUI:public CListContainerElementUI
{
public:
	CListItemUI();
	~CListItemUI();

	LPCTSTR GetClass() const;
	void DoEvent(TEventUI& event);

	bool m_bActive;//标识是否被选中
	void SetActive(bool bActive = true);//是否选中

	//以下为item中的内容,根据自己需要
	LPCTSTR m_strItemName;
	LPCTSTR m_strItemContent;
	LPCTSTR m_strItemInfo;
	void SetItemName(LPCTSTR strName);
	void SetItemContent(LPCTSTR strContent);
	void SetItemInfo(LPCTSTR strInfo);
};
void CListItemUI::DoEvent(TEventUI& event)
{
	CTabLayoutUI* pTabUI = static_cast(this->FindSubControl(L"tab"));
	if (!m_bActive)
	{
		if (event.Type == UIEVENT_MOUSEENTER)//enter
		{
			pTabUI->SelectItem(1);
		}
		else if (event.Type == UIEVENT_MOUSELEAVE)//leave
		{
			pTabUI->SelectItem(0);
		}
		else if (event.Type == UIEVENT_MOUSEHOVER)//hover
		{
		}
	}
	CListContainerElementUI::DoEvent(event);
}
4、添加 SetActive 方法,用于选中处理
void CListItemUI::SetActive(bool bActive /*= true*/)
{
	m_bActive = bActive;
	CTabLayoutUI* pTabUI = static_cast(this->FindSubControl(L"tab"));
	if (m_bActive)
	{
		this->SetFixedHeight(80);
		pTabUI->SelectItem(2);
	}
	else
	{
		this->SetFixedHeight(50);
		pTabUI->SelectItem(0);
	}
}

5、继承CListUIIDialogBuilderCallback两个类实现ListView,并重写一些方法。

class CListViewUI:public CListUI,public IDialogBuilderCallback
{
public:
	CListViewUI();
	~CListViewUI();

	LPCTSTR GetClass() const;
	LPVOID GetInterface(LPCTSTR pstrName);
	void DoEvent(TEventUI& event);
	int m_nActiveItem;//标识选中的item
	bool SetActiveItem(int iIndex,bool bTakeFocus);
	CControlUI* CreateControl(LPCTSTR pstrClass);
};
LPVOID CListViewUI::GetInterface(LPCTSTR pstrName)
{
	if (_tcscmp(pstrName, _T("ListView")) == 0) 
		return this;
	return CListUI::GetInterface(pstrName);
}

CControlUI* CListViewUI::CreateControl(LPCTSTR pstrClass)
{
	if (_tcsicmp(pstrClass, L"ListItem") == 0)
		return new CListItemUI();
	return NULL;
}

6、用SetActiveItem方法更改选中项item的状态

bool CListViewUI::SetActiveItem(int iIndex, bool bTakeFocus)
{
	if (!__super::SelectItem(iIndex,bTakeFocus))
	{
		return false;
	}
	//取消原有的选中状态
	if (m_nActiveItem != -1)
	{
		CListItemUI* pItem = static_cast(this->GetItemAt(m_nActiveItem));
		pItem->SetActive(false);
	}
	m_nActiveItem = iIndex;
	//将新的item选中状态
	if (m_nActiveItem != -1)
	{
		CListItemUI* pItem = static_cast(this->GetItemAt(m_nActiveItem));
		pItem->SetActive(true);
	}
	return true;
}

7、最后在主对话框中创建ListView,并处理DUI_MSGTYPE_ITEMSELECT消息即可。

CControlUI * CDuiMainWnd::CreateControl(LPCTSTR pstrClass)
{
	if (_tcsicmp(pstrClass, L"ListView") == 0)
		return	new CListViewUI();
	if (_tcsicmp(pstrClass, L"ListItem") == 0)
		return new CListItemUI();
	return NULL;
}

void CDuiMainWnd::Notify(TNotifyUI& msg)
{
	CListViewUI* pListView = static_cast(m_PaintManager.FindControl(L"mylist"));
	if (msg.sType == DUI_MSGTYPE_ITEMSELECT)
	{
		int index = pListView->GetCurSel();
		pListView->SetActiveItem(index, true);
	}
	__super::Notify(msg);
}

在初始化窗口时添加一些示例数据,就可以看到效果了。

void CDuiMainWnd::InitWindow()
{
	CListViewUI* pListView = static_cast(m_PaintManager.FindControl(L"mylist"));

	for (int i = 0; i < 20; i++)
	{
		CDialogBuilder builder;
		CListItemUI* pItem = static_cast(builder.Create(L"ListItemLayout.xml", (UINT)0, this, &m_PaintManager));

		CDuiString text;
		text.Format(L"test-%02d", i);
		pItem->SetItemName(text);
		pListView->Add(pItem);
	}
}

效果图

Duilib List中Item内容切换效果_第2张图片

你可能感兴趣的:(Duilib)