cocos2dx ListView 动态加载(代码)
cocos2dx ListView 动态加载(代码)
其实是根据上篇文章得出的:
在ListView中加载少量的内容,
然后在滑出界面的时候在加载一部分剩余的内容,
这样实现动态加载!!!
为了看出效果来,需要建立一个场景,然后点击按钮之后实现跳转,进而可以看出等待时间
代码:
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 }
效果图:
仔细看的话,会看到是先滑出屏幕后再显示一行的