首页 > 代码库 > cocos2d-x3.1 下实现类似Android下ExpandListView的效果
cocos2d-x3.1 下实现类似Android下ExpandListView的效果
在左Android开始有SDK提供ExpandListView的可扩展列表,而在iOS下有许多第三方做好的Demo,这里我是参照iOS下RATreeView这个第三方库实现的。
本文代码:需要在3.1以上版本运行。如果是用3.0版本需要将Vec2换成Piont
原文地址:http://blog.csdn.net/qqmcy/article/details/29559241
代码下载:http://download.csdn.net/detail/qqmcy/7469387
下面说下使用方法:
DJDataObject.h 数据模型类
// // DJDataObject.h // testthirdone // // Created by 杜甲 on 14-6-7. // // #ifndef __testthirdone__DJDataObject__ #define __testthirdone__DJDataObject__ #include "cocos2d.h" USING_NS_CC; class DJDataObject :public Ref { public: CREATE_FUNC(DJDataObject); virtual bool init(); std::string name; std::vector<DJDataObject*> children; void initWithNameAndChildren(std::string name,std::vector<DJDataObject*> data_vec); }; #endif /* defined(__testthirdone__DJDataObject__) */
DJDataObject.cpp
// // DJDataObject.cpp // testthirdone // // Created by 杜甲 on 14-6-7. // // #include "DJDataObject.h" bool DJDataObject::init() { bool bRet = false; do { bRet = true; } while (0); return bRet; } void DJDataObject::initWithNameAndChildren(std::string name,std::vector<DJDataObject*> data_vec) { this->name = name; this->children = data_vec; }
ListViewTest.h 可扩展列表的使用类,将这个布局addChild到场景中就OK。
// // ListViewTest.h // testthirdone // // Created by 杜甲 on 14-6-9. // // #ifndef __testthirdone__ListViewTest__ #define __testthirdone__ListViewTest__ #include "cocos2d.h" #include "ui/CocosGUI.h" #include "DJDataObject.h" USING_NS_CC; using namespace ui; class ListViewTest : public ui::Layout { public: CREATE_FUNC(ListViewTest); virtual bool init(); std::vector<DJDataObject*> data_vec; }; #endif /* defined(__testthirdone__ListViewTest__) */
ListViewTest.cpp
// // ListViewTest.cpp // testthirdone // // Created by 杜甲 on 14-6-9. // // #include "ListViewTest.h" #include "DJTreeNode.h" #include "DJTreeNodeInfo.h" #include "DJListView.h" bool ListViewTest::init() { bool bRet = false; do { CC_BREAK_IF(!ui::Layout::init()); setBackGroundColorType(ui::Layout::BackGroundColorType::SOLID); setBackGroundColor(Color3B(18, 23, 222)); std::vector<DJDataObject*>temp1; std::vector<DJDataObject*>temp2; std::vector<DJDataObject*>temp3; std::vector<DJDataObject*>temp4; DJDataObject* data7 = DJDataObject::create(); data7->retain(); //initWithNameAndChildren 参数1:当前数据内容, 参数2 :子集 data7->initWithNameAndChildren("数据1-1-1", temp4); temp1.push_back(data7); DJDataObject* data3 = DJDataObject::create(); data3->retain(); data3->initWithNameAndChildren("数据1-1", temp1); DJDataObject* data4 = DJDataObject::create(); data4->retain(); data4->initWithNameAndChildren("数据1-2", temp4); for (int i = 0; i < 7; i++) { DJDataObject* data6 = DJDataObject::create(); data6->retain(); data6->initWithNameAndChildren("数据h", temp3); temp2.push_back(data6); } DJDataObject* data1 = DJDataObject::create(); data1->retain(); data1->initWithNameAndChildren("数据r", temp2); DJDataObject* data = http://www.mamicode.com/DJDataObject::create();>
这里帖出的是使用方法,稍后我提供实现的类的下载地址。
实现效果:
之后我会把下面的实现传上来,现在网络有限制不让传。
这里也贴出实现类
DJTreeNodeInfo.h 节点信息类
// // DJTreeNodeInfo.h // testthirdone // // Created by 杜甲 on 14-6-6. // // #ifndef __testthirdone__DJTreeNodeInfo__ #define __testthirdone__DJTreeNodeInfo__ #include "cocos2d.h" USING_NS_CC; class DJTreeNode; class DJTreeNodeInfo :public Ref { public: CREATE_FUNC(DJTreeNodeInfo); virtual bool init(); bool expanded; int treeDepthLevel; int siblingsNumber; int positionInsiblings; DJTreeNodeInfo* parent; DJTreeNode* parentTreeNode; std::vector<DJTreeNodeInfo*> children; void* item; std::vector<DJTreeNode*> childrenTreeNodes; void initWithParent(DJTreeNode* parent1 , std::vector<DJTreeNode*> children1); DJTreeNodeInfo* getParent(); std::vector<DJTreeNodeInfo*> getChildren(); }; #endif /* defined(__testthirdone__DJTreeNodeInfo__) */
DJTreeNodeInfo.cpp// // DJTreeNodeInfo.cpp // testthirdone // // Created by 杜甲 on 14-6-6. // // #include "DJTreeNodeInfo.h" #include "DJTreeNode.h" bool DJTreeNodeInfo::init() { bool bRet = false; do { bRet = true; } while (0); return bRet; } void DJTreeNodeInfo::initWithParent(DJTreeNode *parent1, std::vector<DJTreeNode *> children1) { this->parentTreeNode = parent1; this->childrenTreeNodes = children1; } DJTreeNodeInfo* DJTreeNodeInfo::getParent() { if (this->parent == nullptr) { this->parent = this->parentTreeNode->treeNodeInfo1(); } return nullptr; } std::vector<DJTreeNodeInfo*> DJTreeNodeInfo::getChildren() { if (this->children.size() == 0 ) { std::vector<DJTreeNodeInfo*> treeNodesInfos; for (int i = 0; i < this->childrenTreeNodes.size(); i++) { DJTreeNode* treeNode = this->childrenTreeNodes.at(i); treeNodesInfos.push_back(treeNode->treeNodeInfo1()); this->children = treeNodesInfos; } } return this->children; }
DJTreeNode.h 节点类// // DJTreeNode.h // testthirdone // // Created by 杜甲 on 14-6-6. // // #ifndef __testthirdone__DJTreeNode__ #define __testthirdone__DJTreeNode__ #include "cocos2d.h" USING_NS_CC; class DJTreeNodeInfo; class DJTreeNode :public Ref{ public: CREATE_FUNC(DJTreeNode); virtual bool init(); bool expanded; bool visible; DJTreeNode* parent; std::vector<DJTreeNode*> children; DJTreeNodeInfo* treeNodeInfo; DJTreeNodeInfo* treeNodeInfo1(); void* item; int treeDepthLevel; void initWithItem(void* item , DJTreeNode* parent , bool expanded); void addChildNode(DJTreeNode* child); std::vector<DJTreeNode*> visibleDescendants(); int numberOfVisibleDescendants(); void collapse(); void expand(); int startIndex(); int endIndex(); bool isVisible(); int treeDepthLevel1(); }; #endif /* defined(__testthirdone__DJTreeNode__) */
DJTreeNode.cpp// // DJTreeNode.cpp // testthirdone // // Created by 杜甲 on 14-6-6. // // #include "DJTreeNode.h" #include "DJTreeNodeInfo.h" typedef enum DJTreeDepthLevel { DJTreeDepthLevelNotInitialized } DJTreeDepthLevel; bool DJTreeNode::init() { bool bRet = false; do { bRet = true; } while (0); return bRet; } void DJTreeNode::initWithItem(void *item, DJTreeNode *parent, bool expanded) { this->treeDepthLevel = DJTreeDepthLevelNotInitialized; this->item = item; this->parent = parent; this->expanded = expanded; } bool DJTreeNode::isVisible() { return this->parent->expanded || this->parent == nullptr; } void DJTreeNode::addChildNode(DJTreeNode *child) { // if (this->children.size() > 0) { // this->children.clear(); // } std::vector<DJTreeNode*> children1(this->children); children1.push_back(child); this->children = children1; } int DJTreeNode::numberOfVisibleDescendants() { return (int)visibleDescendants().size(); } std::vector<DJTreeNode*> DJTreeNode::visibleDescendants() { std::vector<DJTreeNode*> visibleDescendants; try { if (expanded) { if (this->children.size() > 0) { // log("children.size() = %lu",children.size()); for (int i = 0; i < this->children.size(); i++) { // log("i = %d",i); DJTreeNode* treeNode = children.at(i); visibleDescendants.push_back(treeNode); if (treeNode->expanded) { std::vector<DJTreeNode*> tree_vec = treeNode->visibleDescendants(); for (int i = 0; i < tree_vec.size(); i++) { visibleDescendants.push_back(tree_vec.at(i)); } } } } } } catch (std::out_of_range & exc) { log("exc.what() = %s",exc.what()); } // log("visibleDescendants = %zd",visibleDescendants.size()); return visibleDescendants; } void DJTreeNode::expand() { this->expanded = true; if (this->parent != nullptr) { this->parent->expand(); } } void DJTreeNode::collapse() { this->expanded = false; for (int i = 0; i < children.size(); i++) { DJTreeNode* treeNode = children.at(i); treeNode->collapse(); } } int DJTreeNode::startIndex() { int startIndex; if (this->parent->parent == nullptr) { startIndex = 0; }else{ startIndex = this->parent->startIndex() + 1; } for (int i = 0 ; i < this->parent->children.size() ; i++) { DJTreeNode* treeNode = this->parent->children.at(i); if (treeNode != this) { startIndex += 1; if (treeNode->expanded) { startIndex += treeNode->numberOfVisibleDescendants(); } } else { break; } } return startIndex; } int DJTreeNode::endIndex() { int startIndex = this->startIndex(); return startIndex + numberOfVisibleDescendants(); } DJTreeNodeInfo* DJTreeNode::treeNodeInfo1() { if (this->treeNodeInfo == nullptr) { DJTreeNodeInfo* treeNodeInfo = DJTreeNodeInfo::create(); treeNodeInfo->initWithParent(this->parent, this->children); treeNodeInfo->treeDepthLevel = treeDepthLevel1(); treeNodeInfo->siblingsNumber = (int)this->parent->children.size(); for (int i = 0; i < this->parent->children.size(); i++) { if (this->parent->children.at(i) == this) { treeNodeInfo->positionInsiblings = i; } } this->treeNodeInfo = treeNodeInfo; } this->treeNodeInfo->item = this->item; this->treeNodeInfo->expanded = this->expanded; return this->treeNodeInfo; } int DJTreeNode::treeDepthLevel1() { if (this->treeDepthLevel == DJTreeDepthLevelNotInitialized) { int treeDepthLevel = 0; DJTreeNode* current = this->parent->parent; while (current != nullptr) { treeDepthLevel++; current = current->parent; } this->treeDepthLevel = treeDepthLevel; } return this->treeDepthLevel; }DJTreeNodeCollectionController.h 节点控制类
// // DJTreeNodeCollectionController.h // testthirdone // // Created by 杜甲 on 14-6-6. // // #ifndef __testthirdone__DJTreeNodeCollectionController__ #define __testthirdone__DJTreeNodeCollectionController__ #include "cocos2d.h" USING_NS_CC; class DJTreeNode; class DJTreeNodeInfo; class DJTreeNodeCollectionController : public Ref { public: CREATE_FUNC(DJTreeNodeCollectionController); virtual bool init(); DJTreeNode* root; void addTreeNode(DJTreeNode* treeNode); DJTreeNode* treeNodeForIndex(int index); DJTreeNode* treeNodeForIndex(int index , DJTreeNode* currentTreeNode); int indexForItem(void* item); int indexForItem(void* item , DJTreeNode* currentTreeNode); }; #endif /* defined(__testthirdone__DJTreeNodeCollectionController__) */
DJTreeNodeCollectionController.cpp// // DJTreeNodeCollectionController.cpp // testthirdone // // Created by 杜甲 on 14-6-6. // // #include "DJTreeNodeCollectionController.h" #include "DJTreeNode.h" bool DJTreeNodeCollectionController::init() { bool bRet = false; do { root = DJTreeNode::create(); root->retain(); root->initWithItem(nullptr, nullptr, true); bRet = true; } while (0); return bRet; } void DJTreeNodeCollectionController::addTreeNode(DJTreeNode *treeNode) { if (treeNode->parent == nullptr) { this->root->addChildNode(treeNode); treeNode->parent = this->root; }else { treeNode->parent->addChildNode(treeNode); if (treeNode->expanded) { treeNode->expand(); } } } DJTreeNode* DJTreeNodeCollectionController::treeNodeForIndex(int index) { if (index < 0) { return nullptr; } return treeNodeForIndex(index, this->root); } DJTreeNode* DJTreeNodeCollectionController::treeNodeForIndex(int index, DJTreeNode *currentTreeNode) { for (int i = 0; i < currentTreeNode->children.size(); i++) { DJTreeNode* treeNode = currentTreeNode->children.at(i); if (treeNode->startIndex() == index) { return treeNode; }else if (index <= treeNode->endIndex()) { return treeNodeForIndex(index, treeNode); } } return nullptr; } int DJTreeNodeCollectionController::indexForItem(void *item) { return indexForItem(item, this->root); } int DJTreeNodeCollectionController::indexForItem(void *item, DJTreeNode *currentTreeNode) { std::vector<DJTreeNode*> array = this->root->visibleDescendants(); for (int i = 0; i < array.size(); i++) { DJTreeNode* treeNode = array.at(i); if (treeNode->item == item) { return i; } } return -1; }DayReportListAdapter.h
// // DayReportListAdapter.h // // // Created by 杜甲 on 14-6-4. // // #ifndef __ht_mobile_cpp__DayReportListAdapter__ #define __ht_mobile_cpp__DayReportListAdapter__ #include "cocos2d.h" #include "../../cocos2d/cocos/ui/CocosGUI.h" USING_NS_CC; class DayReportListAdapter :public ui::Layout { public: CREATE_FUNC(DayReportListAdapter); virtual bool init(); ui::Text* organName; ui::Text* prem_day; ui::Text* prem_month; }; #endif /* defined(__ht_mobile_cpp__DayReportListAdapter__) */
DayReportListAdapter.cpp// // DayReportListAdapter.cpp // // // Created by 杜甲 on 14-6-4. // // #include "DayReportListAdapter.h" bool DayReportListAdapter::init() { bool bRet = false; do { CC_BREAK_IF(!ui::Layout::init()); setLayoutType(cocos2d::ui::Layout::Type::RELATIVE); float topLength = 30; organName = ui::Text::create(); organName->setFontSize(30); organName->setColor(Color3B::BLACK); addChild(organName); auto rp_organName = ui::RelativeLayoutParameter::create(); rp_organName->setMargin(ui::Margin(30,topLength,0,0)); rp_organName->setAlign(cocos2d::ui::RelativeLayoutParameter::RelativeAlign::PARENT_TOP_LEFT); organName->setLayoutParameter(rp_organName); prem_month = ui::Text::create(); prem_month->setFontSize(30); prem_month->setColor(Color3B::BLACK); addChild(prem_month); auto rp_prem_month = ui::RelativeLayoutParameter::create(); rp_prem_month->setAlign(cocos2d::ui::RelativeLayoutParameter::RelativeAlign::PARENT_TOP_RIGHT); rp_prem_month->setRelativeName("rp_prem_month"); rp_prem_month->setMargin(ui::Margin(0,topLength,50,0)); prem_month->setLayoutParameter(rp_prem_month); prem_day = ui::Text::create(); prem_day->setFontSize(30); prem_day->setColor(Color3B::BLACK); addChild(prem_day); auto rp_prem_day = ui::RelativeLayoutParameter::create(); rp_prem_day->setAlign(cocos2d::ui::RelativeLayoutParameter::RelativeAlign::PARENT_TOP_CENTER_HORIZONTAL); // rp_prem_day->setRelativeToWidgetName("rp_prem_month"); rp_prem_day->setMargin(ui::Margin(30,topLength,0,0)); prem_day->setLayoutParameter(rp_prem_day); bRet = true; } while (0); return bRet; }
DJListView.h// // DJListView.h // testthirdone // // Created by 杜甲 on 14-6-8. // // #ifndef __testthirdone__DJListView__ #define __testthirdone__DJListView__ #include "cocos2d.h" #include "ui/CocosGUI.h" #include "DJDataObject.h" #include "DJExpandListView.h" USING_NS_CC; using namespace ui; class DJListView :public ui::Layout { public: CREATE_FUNC(DJListView); virtual bool init(); void selectedItemEvent(Ref *pSender, cocos2d::ui::ListView::EventType type); Size winSize; std::vector<DJDataObject*> data_vec; void addExpandedListView( std::vector<DJDataObject*> data_vec); private: ui::ListView* listView; ssize_t numberOfCellsInListView(void *item); void* treeViewItem( int index, void *item); DJTreeNodeCollectionController* treeNodeCollectionController; std::vector<void*> childrenForItem(void *item); void setupTreeStructure(); void setupTreeStructureWithParentNode(DJTreeNode* parentTreeNode ,int treeDepthLevel); void collapseCellForTreeNode(cocos2d::Ref *pSender,DJTreeNode* treeNode); DJTreeNode* treeNodeForIndex(int index); void expandCellForTreeNode(cocos2d::Ref *pSender , DJTreeNode* treeNode); }; #endif /* defined(__testthirdone__DJListView__) */
DJListView.cpp// // DJListView.cpp // testthirdone // // Created by 杜甲 on 14-6-8. // // #include "DJListView.h" #include "DayReportListAdapter.h" #include "DJTreeNode.h" #include "DJTreeNodeInfo.h" #include "DJTreeNodeCollectionController.h" bool DJListView::init() { bool bRet = false; do { CC_BREAK_IF(!ui::Layout::init()); setLayoutType(cocos2d::ui::Layout::Type::RELATIVE); winSize = Director::getInstance()->getWinSize(); bRet = true; } while (0); return bRet; } void DJListView::addExpandedListView( std::vector<DJDataObject*> data_vec1) { data_vec = data_vec1; listView = ui::ListView::create(); listView->setDirection(cocos2d::ui::ScrollView::Direction::VERTICAL); listView->setTouchEnabled(true); listView->setBounceEnabled(true); listView->setSize(Size(winSize.width,winSize.height - 100)); listView->setBackGroundColorType(ui::Layout::BackGroundColorType::SOLID); listView->setBackGroundColor(Color3B::WHITE); listView->addEventListener(CC_CALLBACK_2(DJListView::selectedItemEvent, this)); auto rp_listView = ui::RelativeLayoutParameter::create(); rp_listView->setAlign(cocos2d::ui::RelativeLayoutParameter::RelativeAlign::PARENT_BOTTOM_CENTER_HORIZONTAL); listView->setLayoutParameter(rp_listView); setupTreeStructure(); // set model for (int i = 0; i < treeNodeCollectionController->root->numberOfVisibleDescendants(); i++) { DJDataObject* dobject = static_cast<DJDataObject*>(treeNodeForIndex(i)->item) ; auto tableLayout1 = DayReportListAdapter::create(); tableLayout1->setSize(Size(winSize.width, 1)); tableLayout1->setBackGroundColorType(ui::Layout::BackGroundColorType::SOLID); tableLayout1->setBackGroundColor(Color3B(189, 203, 222)); listView->pushBackCustomItem(tableLayout1); tableLayout1->organName->setString(dobject->name); tableLayout1->prem_day->setString(StringUtils::format("%d",i)); tableLayout1->prem_month->setString("fffff"); } auto tableLayout2 = DayReportListAdapter::create(); tableLayout2->setSize(Size(winSize.width, 1)); tableLayout2->setBackGroundColorType(ui::Layout::BackGroundColorType::SOLID); tableLayout2->setBackGroundColor(Color3B(189, 203, 222)); listView->pushBackCustomItem(tableLayout2); auto layout21 = ui::Layout::create(); layout21->setLayoutType(cocos2d::ui::Layout::Type::RELATIVE); layout21->setSize(winSize); layout21->addChild(listView); layout21->setBackGroundColorType(ui::Layout::BackGroundColorType::SOLID); layout21->setBackGroundColor(Color3B(89, 203, 222)); auto tableLayout1 = ui::Layout::create(); tableLayout1->setSize(winSize); tableLayout1->setBackGroundColorType(ui::Layout::BackGroundColorType::SOLID); tableLayout1->setBackGroundColor(Color3B(189, 203, 222)); //listView->pushBackCustomItem(tableLayout1); listView->setGravity(cocos2d::ui::ListView::Gravity::CENTER_VERTICAL); listView->setItemsMargin(100.0f); auto page = ui::PageView::create(); page->setLayoutType(cocos2d::ui::Layout::Type::RELATIVE); page->setSize(winSize); page->addPage(layout21); page->addPage(tableLayout1); addChild(page); auto rp_page = ui::RelativeLayoutParameter::create(); rp_page->setAlign(cocos2d::ui::RelativeLayoutParameter::RelativeAlign::PARENT_BOTTOM_CENTER_HORIZONTAL); page->setLayoutParameter(rp_page); } void DJListView::selectedItemEvent(cocos2d::Ref *pSender, cocos2d::ui::ListView::EventType type) { switch (type) { case ui::ListView::EventType::ON_SELECTED_ITEM_END: { ui::ListView* listView = static_cast<ui::ListView*>(pSender); DJTreeNode* treeNode = treeNodeForIndex((int)listView->getCurSelectedIndex()); if (treeNode->children.size() == 0) { return; } if (treeNode->expanded) { collapseCellForTreeNode(pSender, treeNode); }else{ log("treeNode->expanded = %d",treeNode->expanded); expandCellForTreeNode(pSender, treeNode); } listView->refreshView(); } break; default: break; } } ssize_t DJListView::numberOfCellsInListView(void *item) { if (item == nullptr) { log("%zd",data_vec.size()); return data_vec.size(); } DJDataObject* data = http://www.mamicode.com/static_cast(item);>
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。