cocos2dx ListView 動態加載(代碼)node
實際上是根據上篇文章得出的:json
在ListView中加載少許的內容,數組
而後在滑出界面的時候在加載一部分剩餘的內容,iphone
這樣實現動態加載!!!函數
爲了看出效果來,須要創建一個場景,而後點擊按鈕以後實現跳轉,進而能夠看出等待時間性能
代碼:測試
1 MainScene.h 2 3 #ifndef __MAINSCENE_SCENE_H__ 4 #define __MAINSCENE_SCENE_H__ 5 6 #include "cocos2d.h" 7 8 // 使用 cocosStudio 1.6 製做的頭文件 9 #include "cocos-ext.h" 10 USING_NS_CC; 11 USING_NS_CC_EXT; 12 using namespace cocos2d::ui; 13 14 USING_NS_CC; 15 16 class MainScene : public cocos2d::CCLayer 17 { 18 public: 19 // Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone 20 virtual bool init(); 21 22 // there's no 'id' in cpp, so we recommend returning the class instance pointer 23 static cocos2d::CCScene* scene(); 24 25 // a selector callback 26 void menuCloseCallback(cocos2d::CCObject*pSender,cocos2d::ui::TouchEventType type); 27 28 // implement the "static node()" method manually 29 CREATE_FUNC(MainScene); 30 }; 31 32 #endif // __MAINSCENE_SCENE_H__
MainScene.cpp #include "MainScene.h" #include "HelloWorldScene.h" // there's no 'id' in cpp, so we recommend returning the class instance pointer cocos2d::CCScene* MainScene::scene(){ // 'scene' is an autorelease object CCScene *scene = CCScene::create(); // 'layer' is an autorelease object MainScene *layer = MainScene::create(); // add layer as a child to scene scene->addChild(layer); // return the scene return scene; } // Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone bool MainScene::init(){ if ( !CCLayer::init() ) { return false; } // 如下使用的必須是json文件 cocos2d::ui::Widget *m_pWidget = GUIReader::shareReader()->widgetFromJsonFile("ListViewItem_1/ListViewItem_1.json"); // 建立一個能夠裝Widge的一個層 cocos2d::ui::UILayer *m_pUIlayer = cocos2d::ui::UILayer::create(); // 使用 addWidget 方法加載 cocosStudio製做的json文件 m_pUIlayer->addWidget(m_pWidget); // 將 UILayer 添加到場景中 this->addChild(m_pUIlayer); // 獲取按鈕 cocos2d::ui::UIButton *button = dynamic_cast<cocos2d::ui::UIButton*>(m_pUIlayer->getWidgetByName("dybtn_buttonitem")); button->setTouchEnabled(true); button->addTouchEventListener(this, SEL_TouchEvent(&MainScene::menuCloseCallback)); return true; } // a selector callback void MainScene::menuCloseCallback(cocos2d::CCObject*pSender,cocos2d::ui::TouchEventType type){ switch (type) { case cocos2d::ui::TouchEventType::TOUCH_EVENT_BEGAN: { CCLOG("-- silent -- began -- menuCallBack ---- "); } break; case cocos2d::ui::TouchEventType::TOUCH_EVENT_MOVED: { } break; case cocos2d::ui::TouchEventType::TOUCH_EVENT_ENDED: { CCScene *pScene = HelloWorld::scene(); CCDirector::sharedDirector()->replaceScene(pScene); } break; case cocos2d::ui::TouchEventType::TOUCH_EVENT_CANCELED: { } break; default: break; } }
HelloWorldScene.h 測試ListView的動態加載的場景 #ifndef __HELLOWORLD_SCENE_H__ #define __HELLOWORLD_SCENE_H__ #include "cocos2d.h" #include "ListViewItem.h" // 使用 cocosStudio 1.6 製做的頭文件 #include "cocos-ext.h" USING_NS_CC; USING_NS_CC_EXT; using namespace cocos2d::ui; class HelloWorld : public cocos2d::CCLayer { public: // Here's a difference. Method 'init' in cocos2d-x returns bool, instead of returning 'id' in cocos2d-iphone virtual bool init(); // there's no 'id' in cpp, so we recommend returning the class instance pointer static cocos2d::CCScene* scene(); // implement the "static node()" method manually CREATE_FUNC(HelloWorld); // 往ListView中添加內容,實現動態加載ListView中的內容 void addObjiceList(); private: cocos2d::ui::UIListView *m_pListView; // ListView 對象 }; #endif // __HELLOWORLD_SCENE_H__
HelloWorldScene.cpp #include "HelloWorldScene.h" #include "UIMyListView.h" #include "cocos-ext.h" USING_NS_CC_EXT; USING_NS_CC; CCScene* HelloWorld::scene() { // 'scene' is an autorelease object CCScene *scene = CCScene::create(); // 'layer' is an autorelease object HelloWorld *layer = HelloWorld::create(); // add layer as a child to scene scene->addChild(layer); // return the scene return scene; } // on "init" you need to initialize your instance bool HelloWorld::init() { ////////////////////////////// // 1. super init first if ( !CCLayer::init() ) { return false; } // 如下使用的必須是json文件 cocos2d::ui::Widget *m_pWidget = GUIReader::shareReader()->widgetFromJsonFile("ListView_1/ListView_1.json"); // 建立一個能夠裝Widge的一個層 cocos2d::ui::UILayer *m_pUIlayer = cocos2d::ui::UILayer::create(); // 使用 addWidget 方法加載 cocosStudio製做的json文件 m_pUIlayer->addWidget(m_pWidget); // 將 UILayer 添加到場景中 this->addChild(m_pUIlayer); // 獲取文件中的 ListView 列表容器 m_pListView = dynamic_cast<cocos2d::ui::UIListView*>(m_pUIlayer->getWidgetByName("dylv_twolistview")); // 獲取按鈕 cocos2d::ui::UIButton *button = dynamic_cast<cocos2d::ui::UIButton*>(m_pUIlayer->getWidgetByName("dybtn_button")); // 在動態加載以前,先加載一屏幕的內容 addObjiceList(); addObjiceList(); addObjiceList(); addObjiceList(); //動態加載listView //使用方法 UIMyDynamicListView* m_pDynamicListView; //建立動態類 m_pDynamicListView = UIMyDynamicListView::createExpendDynamicListView(); //將ListView加載到動態類中 m_pDynamicListView->init(m_pListView); //當listView加載到頂部時 動態加載的數量 m_pDynamicListView->setAddCount(1); //設置listview中Item的總數 m_pDynamicListView->setItemNeedDynamicCount(50); //界面類中添加的回調函數 addObjiceList爲回調函數 處理listview的信息 // 就是在外面初始化以後再添加到listView中,這樣就能夠動態加載了 m_pDynamicListView->setCallBackFunctionAddItem(this,(m_AddItemfunction)(&HelloWorld::addObjiceList)); return true; } void HelloWorld::addObjiceList() { //for(int i = 0; i < 100; i++) { // 建立一個 layout 用來添加另外一個 cocosStudio 導出的 json 文件 cocos2d::ui::Layout *pLayout = cocos2d::ui::Layout::create(); // 設置 layout 的大小 pLayout->setSize(cocos2d::CCSizeMake(70,70)); for(int i = 0; i < 5; i ++) { // 建立另外一個 json 文件, 即一個按鈕 (使用 cocosStudio 製做) ListViewItem *item = ListViewItem::create(i); // 設置按鈕的位置 ( 實現三排的效果, 在中間以後一次日後排 ) item->setPosition(ccp((i)*70,0)); // 將三個 按鈕 都添加到一個 layout 中,使其實如今同一排的效果 pLayout->addChild(item); } //vecLayout.push_back(pLayout); // 初始化 100 個 m_pListView->pushBackCustomItem(pLayout); // 將 layout 添加到 ListView 中 } }
UIMyListView.h 動態類,主要是這個類的做用 #ifndef _UI_MYLISTVIEW_ #define _UI_MYLISTVIEW_ #include "cocos2d.h" #include "cocos-ext.h" USING_NS_CC_EXT; typedef void (cocos2d::CCObject::*m_AddItemfunction)(); class UI_MyListView: public cocos2d::ui::UIListView { public: //設置listview的選項 void setCurSelectedIndex(int index); //設置listview的移動點 void setPositionOfContainer(cocos2d::CCPoint pos); //得到listview的移動點 cocos2d::CCPoint getPositionOfContainer(); }; //動態加載listView //使用方法 //UIMyDynamicListView* m_pDynamicListView; //建立動態類 //m_pDynamicListView = UIMyDynamicListView::createExpendDynamicListView(); //將ListView加載到動態類中 //m_pDynamicListView->init(m_pServerList); //當listView加載到頂部時 動態加載的數量 //m_pDynamicListView->setAddCount(3); //設置listview中Item的總數 //m_pDynamicListView->setItemNeedDynamicCount(m_allServers.size()); //界面類中添加的回調函數 addObjiceList爲回調函數 處理listview的信息 //m_pDynamicListView->setCallBackFunctionAddItem(this,(m_AddItemfunction)(&ObjiceLayer::addObjiceList)); class UIMyDynamicListView:public cocos2d::CCObject { public: static UIMyDynamicListView* createExpendDynamicListView(); // 建立動態類用來包裹ListView UIMyDynamicListView(); ~UIMyDynamicListView(); void init(cocos2d::ui::UIListView* listView); // 將ListView添加到動態類中 void addItemTo(); // 加載的item cocos2d::CCObject* m_pListener; void setCallBackFunctionAddItem(cocos2d::CCObject* pListener, void (cocos2d::CCObject::*pfunction)()) { m_pListener = pListener; m_pCallFunc = pfunction; } void setAddCount(unsigned int nCount); // 設置動態加載的數量(即每次滑到底部的時候要加載的數量) unsigned int getAddCount(); // 獲取動態加載的數量 void setItemNeedDynamicCount(unsigned int nCount); // 設置未加載的個數 unsigned int getItemNeedDynamicCount(); // 獲取未加載的個數 private: // ListView的滑動事件 void menuEvent(cocos2d::CCObject*pSender, cocos2d::ui::ScrollviewEventType type); m_AddItemfunction m_pCallFunc; // void (cocos2d::CCObject::*m_AddItemfunction)() m_pCallFuncs; bool m_bLockAddItem; // 是否加載 unsigned int m_nAddCount; //每次動態添加的個數 unsigned int m_nItemNeedDynamicCount; //item的剩餘未加載數 cocos2d::ui::UIListView* m_listView; // 外界傳進來的ListView }; #endif
1 UIMyListView.cpp 2 3 4 #include "UIMyListView.h" 5 USING_NS_CC; 6 using namespace cocos2d::ui; 7 8 9 void UI_MyListView::setCurSelectedIndex(int index) 10 { 11 _curSelectedIndex = index; 12 updateInnerContainerSize(); 13 if(_curSelectedIndex>0) 14 { 15 float fPercent = float(_curSelectedIndex - 1)/(getChildrenCount() - 3); 16 if(fPercent>1.000000f) 17 { 18 fPercent = 1.000000f; 19 } 20 //CCScrollViewDirection s = this->get(); 21 if (this->getDirection() == SCROLLVIEW_DIR_HORIZONTAL) 22 { 23 jumpToPercentHorizontal(fPercent*100); 24 } 25 else if (this->getDirection() == SCROLLVIEW_DIR_VERTICAL) 26 { 27 jumpToPercentVertical(fPercent*100); 28 } 29 30 } 31 else 32 { 33 if (this->getDirection() == SCROLLVIEW_DIR_HORIZONTAL) 34 { 35 jumpToPercentHorizontal(0); 36 } 37 else if (this->getDirection() == SCROLLVIEW_DIR_VERTICAL) 38 { 39 jumpToPercentVertical(0); 40 } 41 } 42 } 43 void UI_MyListView::setPositionOfContainer(cocos2d::CCPoint pos) 44 { 45 _innerContainer->setPosition(pos); 46 } 47 48 cocos2d::CCPoint UI_MyListView::getPositionOfContainer() 49 { 50 return _innerContainer->getPosition(); 51 } 52 53 54 55 UIMyDynamicListView::UIMyDynamicListView() 56 { 57 58 } 59 60 UIMyDynamicListView::~UIMyDynamicListView() 61 { 62 m_pListener = NULL; 63 m_pCallFunc = NULL; 64 } 65 66 UIMyDynamicListView* UIMyDynamicListView::createExpendDynamicListView() 67 { 68 69 UIMyDynamicListView* widget = new UIMyDynamicListView(); 70 if (widget) 71 { 72 widget->retain(); 73 return widget; 74 } 75 CC_SAFE_DELETE(widget); 76 return NULL; 77 } 78 79 void UIMyDynamicListView::init(cocos2d::ui::UIListView* listView) 80 { 81 if (listView) 82 { 83 m_bLockAddItem = true; // 設置未加載 84 m_listView = listView; 85 m_nAddCount = 0; 86 m_nItemNeedDynamicCount = 0; 87 m_listView->addEventListenerScrollView(this,cocos2d::ui::SEL_ScrollViewEvent(&UIMyDynamicListView::menuEvent)); 88 } 89 90 } 91 92 void UIMyDynamicListView::menuEvent(cocos2d::CCObject*pSender, cocos2d::ui::ScrollviewEventType type) 93 { 94 switch (type) 95 { 96 //case cocos2d::ui::SCROLLVIEW_EVENT_SCROLLING: // 在ListView滑動的時候添加內容,只要界面滑動就能夠添加內容 97 // { 98 // if (m_bLockAddItem) 99 // { 100 // addItemTo(); 101 // } 102 // } 103 // break; 104 case cocos2d::ui::SCROLLVIEW_EVENT_SCROLL_TO_BOTTOM: // 在ListView滑動到底部的時候添加內容 105 { 106 if (m_bLockAddItem) 107 { 108 addItemTo(); 109 } 110 } 111 break; 112 case cocos2d::ui::SCROLLVIEW_EVENT_SCROLL_TO_RIGHT: // 在ListView滑動到右部的時候添加內容 113 { 114 if (m_bLockAddItem) 115 { 116 addItemTo(); 117 } 118 } 119 break; 120 default: 121 break; 122 } 123 } 124 125 // 每次要添加的內容 126 void UIMyDynamicListView::setAddCount(unsigned int nCount) 127 { 128 m_nAddCount = nCount; 129 } 130 131 unsigned int UIMyDynamicListView::getAddCount() 132 { 133 return m_nAddCount; 134 } 135 136 // 設置還須要加載的數量 137 void UIMyDynamicListView::setItemNeedDynamicCount(unsigned int nCount) 138 { 139 m_nItemNeedDynamicCount = nCount; 140 } 141 142 unsigned int UIMyDynamicListView::getItemNeedDynamicCount() 143 { 144 return m_nItemNeedDynamicCount; 145 } 146 147 // 設置加載函數 148 void UIMyDynamicListView::addItemTo() 149 { 150 // 若是ListView存在的話 151 if (m_listView) 152 { 153 // 將其設置爲未加載 154 m_bLockAddItem = false; 155 int nAddCount = 0; // 設置本次加載的數量 156 // 當還有要加載的內容時 157 while (m_nItemNeedDynamicCount) 158 { 159 nAddCount++; // 將本次加載數量 +1 160 // 將本次加載數量與每次要加載的數量作比較,本次加載多於每次加載時則再也不加載了 161 if (nAddCount>m_nAddCount) 162 { 163 m_bLockAddItem = true; 164 return; 165 } 166 // 更新未加載的數量 167 m_nItemNeedDynamicCount--; 168 m_listView->pushBackDefaultItem(); 169 if (m_pListener == 0 || m_pCallFunc == 0) 170 { 171 assert(false); 172 return; 173 } 174 (m_pListener->*m_pCallFunc)(/*sender*/); 175 m_listView->sortAllChildren();//在繪畫以前,排列全部的孩子數組一次,而不是每次添加或者刪除子節點時都排序。 這個方法能夠大幅度地提升性能。註解:不要手動調用這個方法,除非一個添加過的子節點將要被刪除在這個結構內。176 } 177 } 178 }
效果圖:ui
仔細看的話,會看到是先滑出屏幕後再顯示一行的this