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 }

效果图:

仔细看的话,会看到是先滑出屏幕后再显示一行的

 

 

posted @ 2015-10-30 19:13  silent-bobo  阅读(5268)  评论(0编辑  收藏  举报