Duilib List中Item内容切换效果

作者: 云谁之殇 | 来源:发表于2018-03-22 11:26 被阅读63次

    先看几个效果:

    在正常状态下是这样的:
    1.png
    鼠标经过是这样的:
    2.png
    选中的时候是这样的:
    3.png

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

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

    1、首先,每个Item有这样的几种布局界面,需要将这几种布局包含在TabLayout中,使用TabLayout进行布局的切换。如图,包含了这三种状态的布局。

    4.png

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

    <?xml version="1.0" encoding="UTF-8"?>
    <Window size="800,450">
        <VerticalLayout bkcolor="FFF3F3F3">
            <ListView name="mylist" header="hidden" vscrollbar="true">
            </ListView>
        </VerticalLayout>
    </Window>
    

    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<CTabLayoutUI*>(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<CTabLayoutUI*>(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<CListItemUI*>(this->GetItemAt(m_nActiveItem));
            pItem->SetActive(false);
        }
        m_nActiveItem = iIndex;
        //将新的item选中状态
        if (m_nActiveItem != -1)
        {
            CListItemUI* pItem = static_cast<CListItemUI*>(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<CListViewUI*>(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<CListViewUI*>(m_PaintManager.FindControl(L"mylist"));
    
        for (int i = 0; i < 20; i++)
        {
            CDialogBuilder builder;
            CListItemUI* pItem = static_cast<CListItemUI*>(builder.Create(L"ListItemLayout.xml", (UINT)0, this, &m_PaintManager));
    
            CDuiString text;
            text.Format(L"test-%02d", i);
            pItem->SetItemName(text);
            pListView->Add(pItem);
        }
    }
    

    效果图

    5.gif

    相关文章

      网友评论

        本文标题:Duilib List中Item内容切换效果

        本文链接:https://www.haomeiwen.com/subject/bqxaqftx.html