CCScrollView/CCTableView(CCTableViewDelegate CCTableViewDataSource CCTableView-滑动列表-游戏中大量使用 非常重要的一个类)
tableview
scrollViewDidScroll函数中有一段 ---- 即---滑动tableview时触发的函数 : 会将全部显示的cell又一次刷新(刷新函数中调用了自己定义的tableCellAtIndex)
//////
for (unsigned int i=startIdx; i <= endIdx; i++)
{
//if ([m_pIndices containsIndex:i])
if (m_pIndices->find(i) != m_pIndices->end())
{
continue;
}
this->updateCellAtIndex(i);
}
////////
updateCellAtIndex(i);中有一段
////
cell = m_pDataSource->tableCellAtIndex(this, idx);
///
使用样例
class
ListViewLayer
:
public
cocos2d::CCLayer,
public
cocos2d::extension::CCTableViewDataSource, (关于cell的数据
包含4个虚函数:
tableCellSizeForIndexcellSizeForTabletableCellAtIndexnumberOfCellsInTableView)
public
cocos2d::extension::CCTableViewDelegate(继承自CCScrollViewDelegate
又添加了4个触摸回调 包含4个虚函数:tableCellTouchedtableCellHighlighttableCellUnhighlight
tableCellWillRecycle){
public
:
virtual
bool
init();
///////
bool
ListViewLayer::init()
{
bool
bRet
=
false
;
do
{
CC_BREAK_IF(
!CCLayer::init() );
CCTableView*
pTableView = CCTableView::create(
this
,
CCSizeMake(960, 640));
pTableView->setDirection(kCCScrollViewDirectionVertical);
pTableView->setPosition(CCPointZero);
pTableView->setDelegate(
this
);
pTableView->setVerticalFillOrder(kCCTableViewFillTopDown);
this
->addChild(pTableView);
pTableView->reloadData();
bRet
=
true
;
}
while
(0);
return
bRet;
}
//////
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);
//////
void ListViewLayer::tableCellTouched(CCTableView* { CCLog( "cell , } ///// |
//每一项的宽度和高度必须重写的一个虚函数
virtual
cocos2d::CCSize
cellSizeForTable(cocos2d::extension::CCTableView *table);
//生成列表每一项的内容
必须重写的一个虚函数
virtual
cocos2d::extension::CCTableViewCell*
tableCellAtIndex(cocos2d::extension::CCTableView *table, unsigned
int
idx);
////////
CCTableViewCell* int idx) { CCString "%d" , CCTableViewCell if (!pCell) pCell new CCTableViewCell(); pCell->autorelease(); CCSprite "listitem.png" ); pSprite->setAnchorPoint(CCPointZero); pSprite->setPosition(CCPointZero); pCell->addChild(pSprite); CCLabelTTF "Arial" , pLabel->setPosition(CCPointZero); pLabel->setAnchorPoint(CCPointZero); pLabel->setTag(123); pCell->addChild(pLabel); } else { CCLabelTTF pLabel->setString(pString->getCString()); } return pCell; } |
////////
//一共多少项必须重写的一个虚函数
virtual
unsigned
int
numberOfCellsInTableView(cocos2d::extension::CCTableView
*table);
unsigned int ListViewLayer::numberOfCellsInTableView(CCTableView { return 20; } |
///////
CREATE_FUNC(ListViewLayer);
};
首先须要创建CCTableView。设置它的显示区域和显示方向,这里使用了纵向。设置每一个子项的宽度和高度,子项的数量以及每一个子项相应的内容。每一个子项是一个CCTableViewCell,这里进行了优化。复用了子项对象。
以下是效果图:
#ifndef __CCTABLEVIEW_H__
#define __CCTABLEVIEW_H__
#include "CCScrollView.h"
#include "CCTableViewCell.h"
#include <set>
#include <vector>
NS_CC_EXT_BEGIN
class CCTableView;
class CCArrayForObjectSorting;
typedef enum {
kCCTableViewFillTopDown, //靠顶端
kCCTableViewFillBottomUp
} CCTableViewVerticalFillOrder; //fill 装满 填充
/**
* Sole(唯一的) purpose(目的 用途) of this delegate(代表) is to single touch(单点触摸) event in this version.//这个版本号仅支持单点触摸
*/
class CCTableViewDelegate : public CCScrollViewDelegate
{
public:
/**
* Delegate to respond(做出反应) touch event
*/
virtual void tableCellTouched(CCTableView* table, CCTableViewCell* cell) = 0;
/**
* Delegate to respond a table cell press event.
*/
virtual void tableCellHighlight(CCTableView* table, CCTableViewCell* cell){};//Highlight
突出 加亮 点击事件
/**
* Delegate to respond a table cell release event
*/
virtual void tableCellUnhighlight(CCTableView* table, CCTableViewCell* cell){};//松开事件
/**
* Delegate called when the cell is about to(即将) be recycled. Immediately
* after this call the cell will be removed from the scene graph and
* recycled.
*/
virtual void tableCellWillRecycle(CCTableView* table, CCTableViewCell* cell){};//cell即将回收事件
};
/**
* Data source that governs(治理) table backend(后端) data.
*/
class CCTableViewDataSource
{
public:
virtual ~CCTableViewDataSource() {}
/**
* cell size for a given index
*
* @param idx the index of a cell to get a size
* @return size of a cell at given index
*/
virtual CCSize tableCellSizeForIndex(CCTableView *table, unsigned int idx) { //得到指定ins的cell的size
return cellSizeForTable(table);
};
/**
* cell height for a given table.
*/
virtual CCSize cellSizeForTable(CCTableView *table) { //cell的size
return CCSizeZero;
};
/**
* a cell instance at a given index
*
* @param idx index to search for a cell
* @return cell found at idx
*/
virtual CCTableViewCell* tableCellAtIndex(CCTableView *table, unsigned int idx) = 0; //得到指定idx的
cell
/**
* Returns number of cells in a given table view.
*/
virtual unsigned int numberOfCellsInTableView(CCTableView *table) = 0;//得到cell数量
};
/**
* UITableView counterpart(副本) for cocos2d for iphone.
* this is a very basic, minimal(最低的) implementation(实现) to bring UITableView-like
component into(作为组件插入) cocos2d world.
*/
class CCTableView : public CCScrollView, public CCScrollViewDelegate
{
public:
CCTableView();
virtual ~CCTableView();
/**
* An initialized(初始的) table view object
*/
static CCTableView* create(CCTableViewDataSource* dataSource, CCSize size);
/**
* An initialized table view object
*/
static CCTableView*create(CCTableViewDataSource* dataSource, CCSize size, CCNode
*container);
//////
CCTableView* CCTableView::create(CCTableViewDataSource* dataSource, CCSize size, CCNode *container)
{
CCTableView *table = new CCTableView();
table->initWithViewSize(size, container);
table->autorelease();
table->setDataSource(dataSource);
table->_updateCellPositions();
table->_updateContentSize();
return table;
}
///////
CCTableViewDataSource* getDataSource() { return m_pDataSource; }
void setDataSource(CCTableViewDataSource* source) { m_pDataSource = source; }
CCTableViewDelegate* getDelegate() { return m_pTableViewDelegate; }
void setDelegate(CCTableViewDelegate* pDelegate) { m_pTableViewDelegate = pDelegate; }
/**
* determines how cell is ordered and filled in the view. //确定cell在tableview中怎样排列
*/
void setVerticalFillOrder(CCTableViewVerticalFillOrder order);
CCTableViewVerticalFillOrder getVerticalFillOrder();
boolinitWithViewSize(CCSize size, CCNode* container = NULL);
////////
bool CCTableView::initWithViewSize(CCSize size, CCNode* container/* = NULL*/)
{
if (CCScrollView::initWithViewSize(size,container))
{
m_pCellsUsed = new CCArrayForObjectSorting();
m_pCellsFreed = new CCArrayForObjectSorting();
m_pIndices = new std::set<unsigned int>();
m_eVordering = kCCTableViewFillBottomUp;
this->setDirection(kCCScrollViewDirectionVertical);
CCScrollView::setDelegate(this);
return true;
}
return false;
}
////////
/**
* Updates the content of the cell at a given index.
*/
voidupdateCellAtIndex(unsigned int idx);//更新cell
////////////////
void CCTableView::updateCellAtIndex(unsigned int idx)
{
if (idx == CC_INVALID_INDEX)
{
return;
}
unsigned int uCountOfItems = m_pDataSource->numberOfCellsInTableView(this);
if (0 == uCountOfItems || idx > uCountOfItems-1)
{
return;
}
CCTableViewCell* cell = this->cellAtIndex(idx);
if (cell)
{
this->_moveCellOutOfSight(cell);
}
cell = m_pDataSource->tableCellAtIndex(this, idx);
this->_setIndexForCell(idx, cell);
this->_addCellIfNecessary(cell);
}
//////////////
void insertCellAtIndex(unsigned int idx);//插入新的cell
void removeCellAtIndex(unsigned int idx);//移除cell
void reloadData();//又一次下载datasource view 将更新
/**
* Dequeues a free cell if available. nil if not.
*/
CCTableViewCell *dequeueCell();//得到一个将要离队(释放)的cell
///////
CCTableViewCell *CCTableView::dequeueCell()
{
CCTableViewCell *cell;
if (m_pCellsFreed->count() == 0) {
cell = NULL; //假设释放池中没有就返回0
} else { //假设释放池中有就返回第一个
cell = (CCTableViewCell*)m_pCellsFreed->objectAtIndex(0);
cell->retain();
m_pCellsFreed->removeObjectAtIndex(0);
cell->autorelease();
}
return cell;
}
//////////
/**
* Returns an existing(眼下的) cell at a given index. Returns nil if a cell is nonexistent at the moment of query.
*/
CCTableViewCell *cellAtIndex(unsigned int idx);//按给定的idx
返回一个cell
////////
CCTableViewCell *CCTableView::cellAtIndex(unsigned int idx)
{
CCTableViewCell *found = NULL;
if (m_pIndices->find(idx) != m_pIndices->end())
{
found = (CCTableViewCell *)m_pCellsUsed->objectWithObjectID(idx);
}
return found;
}
///////////
virtual voidscrollViewDidScroll(CCScrollView* view);
//////////
void CCTableView::scrollViewDidScroll(CCScrollView* view)
{
unsigned int uCountOfItems = m_pDataSource->numberOfCellsInTableView(this);
if (0 == uCountOfItems)
{
return;
}
if(m_pTableViewDelegate != NULL) {
m_pTableViewDelegate->scrollViewDidScroll(this);
}
unsigned int startIdx = 0, endIdx = 0, idx = 0, maxIdx = 0;
CCPoint offset = ccpMult(this->getContentOffset(), -1);
maxIdx = MAX(uCountOfItems-1, 0);
if (m_eVordering == kCCTableViewFillTopDown)
{
offset.y = offset.y + m_tViewSize.height/this->getContainer()->getScaleY();
}
startIdx = this->_indexFromOffset(offset);
if (startIdx == CC_INVALID_INDEX)
{
startIdx = uCountOfItems - 1;
}
if (m_eVordering == kCCTableViewFillTopDown)
{
offset.y -= m_tViewSize.height/this->getContainer()->getScaleY();
}
else
{
offset.y += m_tViewSize.height/this->getContainer()->getScaleY();
}
offset.x += m_tViewSize.width/this->getContainer()->getScaleX();
endIdx = this->_indexFromOffset(offset);
if (endIdx == CC_INVALID_INDEX)
{
endIdx = uCountOfItems - 1;
}
#if 0 // For Testing.
CCObject* pObj;
int i = 0;
CCARRAY_FOREACH(m_pCellsUsed, pObj)
{
CCTableViewCell* pCell = (CCTableViewCell*)pObj;
CCLog("cells Used index %d, value = %d", i, pCell->getIdx());
i++;
}
CCLog("---------------------------------------");
i = 0;
CCARRAY_FOREACH(m_pCellsFreed, pObj)
{
CCTableViewCell* pCell = (CCTableViewCell*)pObj;
CCLog("cells freed index %d, value = %d", i, pCell->getIdx());
i++;
}
CCLog("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
#endif
if (m_pCellsUsed->count() > 0)
{
CCTableViewCell* cell = (CCTableViewCell*)m_pCellsUsed->objectAtIndex(0);
idx = cell->getIdx();
while(idx <startIdx)
{
this->_moveCellOutOfSight(cell);
if (m_pCellsUsed->count() > 0)
{
cell = (CCTableViewCell*)m_pCellsUsed->objectAtIndex(0);
idx = cell->getIdx();
}
else
{
break;
}
}
}
if (m_pCellsUsed->count() > 0)
{
CCTableViewCell *cell = (CCTableViewCell*)m_pCellsUsed->lastObject();
idx = cell->getIdx();
while(idx <= maxIdx && idx > endIdx)
{
this->_moveCellOutOfSight(cell);
if (m_pCellsUsed->count() > 0)
{
cell = (CCTableViewCell*)m_pCellsUsed->lastObject();
idx = cell->getIdx();
}
else
{
break;
}
}
}
for (unsigned int i=startIdx; i <= endIdx; i++)
{
//if ([m_pIndices containsIndex:i])
if (m_pIndices->find(i) != m_pIndices->end())
{
continue;
}
this->updateCellAtIndex(i);
}
}
//////////
virtual void scrollViewDidZoom(CCScrollView* view) {}
virtual bool ccTouchBegan(CCTouch *pTouch, CCEvent *pEvent);
virtual void ccTouchMoved(CCTouch *pTouch, CCEvent *pEvent);
virtual void ccTouchEnded(CCTouch *pTouch, CCEvent *pEvent);
virtual void ccTouchCancelled(CCTouch *pTouch, CCEvent *pEvent);
protected:
CCTableViewCell *m_pTouchedCell;//当前触摸的cell
CCTableViewVerticalFillOrder m_eVordering;//fill 模式
/**
* index set to query the indexes of the cells used.
*/
std::set<unsigned int>* m_pIndices;//保存cell idx的set
/**
* vector with all cell positions
*/
std::vector<float> m_vCellsPositions;//保存cell position的vector
//NSMutableIndexSet *indices_;
/**
* cells that are currently in the table
*/
CCArrayForObjectSorting* m_pCellsUsed;// table中当前全部cell
/**
* free list of cells
*/
CCArrayForObjectSorting* m_pCellsFreed;///
/**
* weak link to the data source object
*/
CCTableViewDataSource* m_pDataSource;////
/**
* weak link to the delegate object
*/
CCTableViewDelegate* m_pTableViewDelegate;////
CCScrollViewDirection m_eOldDirection;////
int __indexFromOffset(CCPoint offset);//依据偏移量得到idx
unsigned int _indexFromOffset(CCPoint offset);
CCPoint __offsetFromIndex(unsigned int index);//依据idx得到偏移量
CCPoint _offsetFromIndex(unsigned int index);
void _moveCellOutOfSight(CCTableViewCell *cell);////
void _setIndexForCell(unsigned int index, CCTableViewCell *cell);
void _addCellIfNecessary(CCTableViewCell * cell);///Necessary
必要的
void_updateCellPositions();//更新cell位置
///////
void CCTableView::_updateCellPositions() {
int cellsCount = m_pDataSource->numberOfCellsInTableView(this);
m_vCellsPositions.resize(cellsCount + 1, 0.0);
if (cellsCount > 0)
{
float currentPos = 0;
CCSize cellSize;
for (int i=0; i < cellsCount; i++)
{
m_vCellsPositions[i] = currentPos;
cellSize = m_pDataSource->tableCellSizeForIndex(this, i);
switch (this->getDirection())
{
case kCCScrollViewDirectionHorizontal:
currentPos += cellSize.width;
break;
default:
currentPos += cellSize.height;
break;
}
}
m_vCellsPositions[cellsCount] = currentPos;//1 extra value allows us to get right/bottom of the last cell
}
}
////////
public:
void_updateContentSize();//更新table尺寸
/////////
void CCTableView::_updateContentSize()
{
CCSize size = CCSizeZero;
unsigned int cellsCount = m_pDataSource->numberOfCellsInTableView(this);
if (cellsCount > 0)
{
float maxPosition = m_vCellsPositions[cellsCount];
switch (this->getDirection())
{
case kCCScrollViewDirectionHorizontal:
size = CCSizeMake(maxPosition, m_tViewSize.height);
break;
default:
size = CCSizeMake(m_tViewSize.width, maxPosition);
break;
}
}
this->setContentSize(size);
if (m_eOldDirection != m_eDirection)
{
if (m_eDirection == kCCScrollViewDirectionHorizontal)
{
this->setContentOffset(ccp(0,0));
}
else
{
this->setContentOffset(ccp(0,this->minContainerOffset().y));
}
m_eOldDirection = m_eDirection;
}
}
/////////
};
NS_CC_EXT_END
#endif /* __CCTABLEVIEW_H__ */
CCScrollView/CCTableView(CCTableViewDelegate CCTableViewDataSource CCTableView-滑动列表-游戏中大量使用 非常重要的一个类)的更多相关文章
- 【Cocos2dx游戏开发】CCTableView实现滑动列表
在游戏中,经常需要用到列表展示,例如我现在做的卡牌游戏中就有卡牌列表和好友列表需要用到CCTableView,下面简单介绍一下使用方法. CCTableView位于扩展库文件cocos-ext.h中, ...
- Unity3d NGUI的使用(九)(UIScrollView制作滑动列表)
UIScrollView制作滑动列表,可横向,竖直展示一些列表在固定可视范围内 UIScrollVIew只是一个可滑动的UI组件 如果需要制作复杂的可视区域UI需要配合使用UIPanel与UIGrid ...
- 使用泛型简单封装NGUI的ScrollView实现滑动列表
懒,是老毛病了,周末跑了半马,跑完也是一通累,好久没锻炼了..也是懒的,有时都懒的写博客..最近看到项目中各种滑动列表框,本着要懒出水平来的原则,决定花点时间简单处理下(暂时未做列表太多时的优化):1 ...
- Android滑动列表(拖拽,左滑删除,右滑完成)功能实现(2)
ItemTouchHelper类 之前我们实现了滑动列表的一些基本功能,为了实现更多的效果,我们来仔细看一下ItemTouchHelper中的类: ItemTouchHelper.SimpleCall ...
- [转]ionic3项目实战教程三(创建provider、http请求、图文列表、滑动列表)
本文转自:https://blog.csdn.net/lyt_angularjs/article/details/81145468 版权声明:本文为博主原创文章,转载请注明出处.谢谢! https:/ ...
- [UGUI]滑动列表优化(循环利用)
需要注意的有下面几点: 1. 区分好表现上的index和逻辑上的index.表现上的index是指这个go是go列表中的第几项,但实际上这个index的意义并不大,因为在滚动的过程中go列表是轮转的: ...
- Flexbox + js实现滑动拼图游戏
滑动拼图就是把一张图片分成几等份,打乱顺序(下图),然后通过滑动拼凑成一张完整的图片. 要实现一个拼图游戏,需要考虑怎样随机的打乱顺序,怎样交换两张图片的位置,等等.但是,使用了Flexbox布局以后 ...
- 实现移动端touch事件的横向滑动列表效果
要实现手机端横向滑动效果并不难,了解实现的原理及业务逻辑就很容易实现.原理:touchstart(手指按下瞬间获取相对于页面的位置)——>touchmove(手指移动多少,元素相应移动多少). ...
- egret之好友列表(滑动列表)
本文采用List+Scroller实现列表滑动功能 首先新建两个皮肤,一个用做好友界面的显示,一个用作单个好友的显示,新建皮肤如下: 皮肤一取名为:wxMainSkin,添加如下控件 皮肤一取名为:w ...
随机推荐
- selenium python (二) 元素定位方法
定位的原则就是:id name class 优先,强烈建议和前端哥哥搞好关系.定位就不是问题:实在不行就xpath和css大部分偶可以定位到. webdriver定位的方法是通过一个By类,By类中有 ...
- js中document.all 的用法
1. document.all是什么? document.all 实质就是文档中所有元素的集合.可以看做一个数组. 2.document.all怎么用? 2.1 根据下标取元素. 语法: docu ...
- [转]linux 下使用dump和restore命令
转自:http://blog.sina.com.cn/s/blog_63eb479a01011sdu.html dump 支持分卷和增量备份(所谓增量备份是指备份最近一次备份以来修改过的文件,也称差异 ...
- textBox只能输入汉字
private void textBox1_KeyPress(object sender, KeyPressEventArgs e) { if ((e.KeyChar > 0 && ...
- pycharm出现乱码
1. 'gbk' codec can't encode character u'\xb8' 解决办法 import sys reload(sys)sys.setdefaultencoding('utf ...
- 该不该将变量设为 null ?
该不该将变量设为 null ? 对于引用类型的变量,在什么时候需要将其显式设为 null ,在什么时候不需要呢? 局部变量 对于局部变量,在方法结束的时候,变量就会失效,变量指向的对象引用也会减少一个 ...
- 基于mapreduce的大规模连通图寻找算法
基于mapreduce的大规模连通图寻找算法 当我们想要知道哪些账号是一个人的时候往往可以通过业务得到两个账号之间有联系,但是这种联系如何传播呢? 问题 已知每个账号之间的联系 如: A B B C ...
- [POJ] #1004# Financial Management : 浮点数运算
一. 题目 Financial Management Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 173910 Acc ...
- vim编辑十六进制文件
首先用二进制方式打开 vim file -b 之后输入 :%!xxd 还原为二进制文件 :%!xxd -r
- TCP三次握手及四次挥手详细图解(未完)
TCP是主机对主机层的传输控制协议,提供可靠的连接服务,采用三次握手确认建立一个连接: (完成三次握手,客户端与服务器开始传送数据) 所谓三次握手(Three-way Handshake),是指建立一 ...