除了做普通的菜单栏之外,同样也可以利用TableView设计一个滚动的菜单栏,譬如是做关卡选择或者是角色选择的时候,需要一张稍大的图片来展示额外的信息。此时利用滚动菜单就能很好的解决这个问题。
要实现上述功能,我们应当先了解这四个类
TabelView -用于响应触摸事件,判断触摸位置
TableViewCell - 用于表示TableView中单元格的抽象类(注:此处没有纯虚函数,实际为普通基类,不能算抽象类)
TableViewDataSource - 用于管理表格后端数据的数据源
TableViewDelegate - 代理TabelView 触摸事件
实现步骤:
1.自己实现TableViewDataSource 类
class MyDataSource : public TableViewDataSource
{
public:
//创建一个数组用来保存需要的菜单
Array *m_cells;
MyDataSource()
{
m_cells = Array::create();
m_cells->retain();
//循环创建n个TableView中单元格(即我们需要的菜单)
for (int i = 0; i < n; i++)
{
//创建TableView中单元格
TableViewCell *cell = new TableViewCell;
//cell->init();
cell->autorelease();
//将创建的单元格加到Array数组中
m_cells->addObject(cell);
//创建精灵显示内容
String str = "xxx"+(i+1)+".png";
Sprite *sprite = Sprite::create(str)
//将实物精灵添加到单元格
//此时的cell才代表一个菜单选项
cell->addChild(sprite);
//设置精灵位置
sprite->setPosition(Point(winSize.width / 2,
winSize.height / 2));
}
}
~MyDataSource()
{
m_cells->release();
}
//重载TableViewDataSource类的虚函数
virtual Size cellSizeForTable(TableView *table) {
return winSize;
};
virtual TableViewCell* tableCellAtIndex(TableView *table, ssize_t idx)
{
return (TableViewCell*)m_cells->objectAtIndex(idx);
}
virtual ssize_t numberOfCellsInTableView(TableView *table)
{
return m_cells->count();
}
};
2.重写TableView类响应触摸事件
#ifndef __MyTabelView_H__
#define __MyTabelView_H__
class MyTabelView : public TableView
{
public:
static MyTabelView *create(TableViewDataSource *source,Size size);
virtual void onTouchEnded(Touch *pTouch, Event *pEvent);
};
.cpp文件
#include "MyTabelView.h"
MyTabelView * MyTabelView::create(TableViewDataSource *source, Size size)
{
MyTabelView *table = new MyTabelView;
//初始化
table->initWithViewSize(size, NULL);
table->autorelease();
table->setDataSource(source);
table->_updateCellPositions();
table->_updateContentSize();
return table;
}
void MyTabelView::onTouchEnded(Touch *pTouch, Event *pEvent)
{
if (!this->isVisible()) {
return;
}
if (_touchedCell){
//判断pTouch是否点击了m_pTouchedCell这个格子里的精灵,如果点中了精灵,才调用
Vector<Node *> vec = (Vector<Node *>) _touchedCell->getChildren();
Sprite *sprite = (Sprite*)vec.at(0);
Rect rcSprite = sprite->boundingBox();
Point ptInWorld = pTouch->getLocation();
Point ptInCell = _touchedCell->convertToNodeSpace(ptInWorld);
if (/*bb.containsPoint(pTouch->getLocation()) &&*/
rcSprite.containsPoint(ptInCell) && _tableViewDelegate != NULL)
{
_tableViewDelegate->tableCellUnhighlight(this, _touchedCell);
_tableViewDelegate->tableCellTouched(this, _touchedCell);
}
this->_touchedCell = NULL;
}
ScrollView::onTouchEnded(pTouch, pEvent);
}
3.让需要实现滚动菜单的Layer继承TableViewDelegate代理
class LayerMenu : public Layer,public TableViewDelegate
{
public:
CREATE_FUNC(LayerMenu);
void onEnter();
void onExit();
void Back(Object *);
void addScrollViewMenu();
public:
//添加MyDataSource 和MyTabelView 成员变量
MyDataSource *m_dataSource;
MyTabelView *m_table;
//重载TableViewDelegate虚函数
virtual void tableCellTouched(TableView* table, TableViewCell* cell);
//重载ScrollView的虚函数
virtual void scrollViewDidScroll(ScrollView* view)
{
}
virtual void scrollViewDidZoom(ScrollView* view)
{}
};
4.实现添加滚动菜单的函数,并加入触摸响应的操作
void LayerMenu::addScrollViewMenu()
{
m_dataSource = new MyDataSource();
MyTabelView *view = MyTabelView::create(m_dataSource, winSize);
//将滚动菜单添加到Layer
this->addChild(view);
view->setDirection(ScrollView::Direction::HORIZONTAL);
//加载资源
view->reloadData();
//将自己设为代理
view->setDelegate(this);
}
void LayerMenu::tableCellTouched(TableView* table, TableViewCell* cell)
{
int index = cell->getIdx();
//得到点击的为哪一个菜单选项,
//用它做一些额外操作
//例如进入到对应的游戏场景
}