当应用中出现列表时,就需要用到CCTableView,具体的用法见下面的代码:
#ifndef __loading__marketContent__ #define __loading__marketContent__ #include <iostream> #include "cocos2d.h" #include "cocos-ext.h" USING_NS_CC; class marketContent :public CCLayer,public cocos2d::extension::CCTableViewDataSource,public cocos2d::extension::CCTableViewDelegate { public: virtual bool init(int type); virtual void scrollViewDidScroll(cocos2d::extension::CCScrollView* view); //直接重写吧,什么也不做,基本上用不到 virtual void scrollViewDidZoom(cocos2d::extension::CCScrollView* view); //直接重写吧,什么也不做,基本上用不到 //处理触摸事件,可以计算点击的是哪一个子项 virtual void tableCellTouched(cocos2d::extension::CCTableView* table, cocos2d::extension::CCTableViewCell* cell); //每一项的宽度和高度,第一个是指定所有列表的宽带和高度,当列表宽高不需要变化时,就用这个吧,当列表需要变化时(比如点击时改变宽高),就用第二个吧,这个分别设置指定的那个子项的宽高。 virtual cocos2d::CCSize cellSizeForTable(cocos2d::extension::CCTableView *table); virtual cocos2d::CCSize tableCellSizeForIndex(cocos2d::extension::CCTableView *table, unsigned int idx); //生成列表每一项的内容 virtual cocos2d::extension::CCTableViewCell* tableCellAtIndex(cocos2d::extension::CCTableView *table, unsigned int idx); //一共多少项,返回列表的子项的个数 virtual unsigned int numberOfCellsInTableView(cocos2d::extension::CCTableView *table); //下面的后面会用到,就先不解释 static marketContent *create(int ty); //重写create方法,因为CREATE_FUNC()是不能传参的 int type; int isOpen; int lastOpen; cocos2d::extension::CCTableView *pTableView; void buyNow(CCObject *pSender); };.cpp的代码:
#include "marketContent.h" #include "marketContentSprite.h" USING_NS_CC_EXT; marketContent * marketContent::create(int ty) { marketContent *pRet = new marketContent(); if (pRet && pRet->init(ty)) // 重写也就再这里传个参数,这个参数设定是显示的那个列表 { pRet->autorelease(); return pRet; } else { CC_SAFE_DELETE(pRet); return NULL; } } bool marketContent::init(int newtype) { if(!CCLayer::init()) { return false; } type = newtype; isOpen = 0; lastOpen = 0; //下面的CCSizeMake是很关键的,他设定列表显示的范围,如果列表上面显示不全,总有一部分被遮挡,那就调整高度吧,同理,长度也一样 pTableView = CCTableView::create(this, CCSizeMake(960, 510)); pTableView->setDirection(kCCScrollViewDirectionVertical); //设置列表为上下滑动的 pTableView->setPosition(CCPointZero); //设置列表显示的初始位置 pTableView->setDelegate(this); //记得要注册 pTableView->setVerticalFillOrder(kCCTableViewFillTopDown); //列表设置为从小到大显示,及idx从0开始 this->addChild(pTableView); pTableView->reloadData(); //重新加载数据,当遮挡后,再显示,是必须的。 return true; }
下面是主要代码:
cocos2d::extension::CCTableViewCell * marketContent::tableCellAtIndex(CCTableView *table, unsigned int idx) { CCString *string = CCString::createWithFormat("%d", idx); //此函数会缓存列表邻近两个暂时不显示的列,这样,当滑动列表时,可以快速创建出列表,提高效率,所以,最好不要每次都重新生成cell //如果列表子项是可变的,那就用下面的方法,否则,就推荐用这个方法,产生不变大小的子项. //CCTableViewCell *cell = table->dequeueCell(); CCTableViewCell *cell = table->cellAtIndex(idx); if (!cell) { cell = new CCTableViewCell(); cell->autorelease(); if(type == 1) { //另一个类,产生可变的精灵,其实就是继承自CCSprite,根据点击与否,产生不同大小的列表子项,大的由两张背景图片组成,小的由一张图片组成。 MarketContentSprite *backGround = MarketContentSprite::create(idx, isOpen); cell->addChild(backGround ,1); cell->setTag(idx); backGround->setPosition(ccp(480, 50)); } else { CCSprite *backGround = CCSprite::create("market_item_2.png"); if(idx == 0) { backGround = CCSprite::create("market_item_1.png"); } else if(idx == 5) { backGround = CCSprite::create("market_item_3.png"); } cell->addChild(backGround ,1); backGround->setPosition(ccp(480, 50)); //这里设置不当,也有可能导致列表显示不全等 CCString *string = CCString::createWithFormat("market_chipsLogo%d.png",idx); CCSprite *moneyLogo = CCSprite::create(string->getCString()); backGround->addChild(moneyLogo); moneyLogo->setPosition(ccp(120, 50)); CCSprite *normSprite = CCSprite::create("btn_market_buy_pre.png"); CCLabelTTF *buyttf = CCLabelTTF::create("buy now", "", 22); buyttf->setPosition(ccp(70, 30)); normSprite->addChild(buyttf); CCSprite *selectedSprite = CCSprite::create("btn_market_buy.png"); buyttf = CCLabelTTF::create("buy now", "", 29); buyttf->setPosition(ccp(70, 30)); selectedSprite->addChild(buyttf); //设置不同的字体,从而使点击时,看到变大的字体 CCMenuItemSprite *buysprite = CCMenuItemSprite::create(normSprite, selectedSprite, NULL, this, menu_selector(marketContent::buyNow)); CCMenu *buyMenu = CCMenu::create(buysprite,NULL); backGround->addChild(buyMenu,1); buyMenu->setPosition(ccp(600, 50)); } CCLabelTTF *label = CCLabelTTF::create(string->getCString(), "Helvetica", 20.0); label->setPosition(CCPointZero); label->setTag(123); cell->addChild(label); } else //更改显示的内容,因为通过cellAtIndex和dequeueCell缓存返回的值,原来显示的内容和现在的可能是不同的,所以需要重置,否则,通过几次滑动后,列表就会混乱 { CCLabelTTF *label = (CCLabelTTF*)cell->getChildByTag(123); label->setString(string->getCString()); } return cell; } unsigned int marketContent::numberOfCellsInTableView(cocos2d::extension::CCTableView *table) { if(type == 1) { return 4; } else { return 6; } } CCSize marketContent::cellSizeForTable(cocos2d::extension::CCTableView *table) { return CCSizeMake(960, 102); } CCSize marketContent::tableCellSizeForIndex(cocos2d::extension::CCTableView *table, unsigned int idx) { if(type == 1) { if(idx == isOpen - 1) //根据不同的状态,返会不同的子项的宽度 { return CCSizeMake(960, 264); } else { return CCSizeMake(960,102); } } else { return CCSizeMake(960, 102); } } void marketContent::scrollViewDidScroll(cocos2d::extension::CCScrollView *view) { } void marketContent::scrollViewDidZoom(cocos2d::extension::CCScrollView *view) { } void marketContent::tableCellTouched(CCTableView *table, cocos2d::extension::CCTableViewCell *cell) { int idx = cell->getIdx(); if(type == 1) { if(idx == isOpen -1) //处理触摸事件,更改显示状态 { isOpen = 0; lastOpen = 0; pTableView->reloadData(); return; } idx = cell->getIdx(); isOpen = idx +1; lastOpen = isOpen; pTableView->reloadData(); if(isOpen == 4) { pTableView->setContentOffset(pTableView->maxContainerOffset()); //如果是最后一个的话,列表向上弹到最大位置 } } CCLog("%d",idx); } void marketContent::buyNow(cocos2d::CCObject *pSender) { // 获得点击列表的子项,确定点击的按钮 CCTableViewCell *tablecell = (CCTableViewCell *)(((CCMenu*)pSender)->getParent()->getParent()->getParent()); CCLog("hhh %d",tablecell->getIdx()); }