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);
///
使用样例
classListViewLayer
: publiccocos2d::CCLayer, publiccocos2d::extension::CCTableViewDataSource, (关于cell的数据
包含4个虚函数:tableCellSizeForIndexcellSizeForTabletableCellAtIndexnumberOfCellsInTableView)publiccocos2d::extension::CCTableViewDelegate(继承自CCScrollViewDelegate
又添加了4个触摸回调 包含4个虚函数:tableCellTouchedtableCellHighlighttableCellUnhighlighttableCellWillRecycle){public: virtualboolinit(); ///////boolListViewLayer::init(){ boolbRet
= 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); returnbRet;}////// virtualvoidscrollViewDidScroll(cocos2d::extension::CCScrollView*
view); virtualvoidscrollViewDidZoom(cocos2d::extension::CCScrollView*
view); //处理触摸事件。能够计算点击的是哪一个子项 virtualvoidtableCellTouched(cocos2d::extension::CCTableView*
table, cocos2d::extension::CCTableViewCell* cell);
|
//////
voidListViewLayer::tableCellTouched(CCTableView*{ CCLog("cell,}///// |
//每一项的宽度和高度必须重写的一个虚函数
virtualcocos2d::CCSize
cellSizeForTable(cocos2d::extension::CCTableView *table); //生成列表每一项的内容
必须重写的一个虚函数 virtualcocos2d::extension::CCTableViewCell*
tableCellAtIndex(cocos2d::extension::CCTableView *table, unsignedintidx);////////
CCTableViewCell*intidx){ CCString"%d", CCTableViewCell if(!pCell) pCellnewCCTableViewCell(); 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()); } returnpCell;} |
////////
//一共多少项必须重写的一个虚函数 virtualunsignedintnumberOfCellsInTableView(cocos2d::extension::CCTableView
*table);
unsignedintListViewLayer::numberOfCellsInTableView(CCTableView{ return20;} |
///////
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 ...
随机推荐
- 自学Java过程
由于之前判断失误,其实也不应该说失误吧,自己脱产花了几个月来啃C,现在基本上算是啃完了吧,之所以说失误是因为:没有找到跟C有关的适合我的工作!!! 本来的打算是先把基础搞定然后去找找看有没有肯收留打杂 ...
- 【LeetCode】58 - Length of Last Word
Given a string s consists of upper/lower-case alphabets and empty space characters ' ', return the l ...
- 数往知来C#面向对象〈三〉
C# 基础方法篇 一.复习 1)方法的重载 方法的重载并不是一个方法,实际上方法的重载就是一些不同的 方法,目的是为了方便程序员编码,所以将功能相近的方法命名相同 根据参数,编译器自动的去匹配方法体, ...
- The serializable class does not declare a static final serialVersionUID field of type long
在编译以下Java程序时,出现The serializable class does not declare a static final serialVersionUID field of typ ...
- C语言——内存分配
1.在C语言的运行过程中,需要内存来存储数据.C语言使用的内存总体可以分为两类:一类是静态区,一类是动态区.2.静态数据存储区包含:只读数据区.已初始化的读写数据区.未初始化的读写数据区 动态 ...
- MySQL 5.6 警告信息 command line interface can be insecure 修复
在命令行输入密码,就会提示这些安全警告信息. Warning: Using a password on the command line interface can be insecure. 注: ...
- algorithm@ Sieve of Eratosthenes (素数筛选算法) & Related Problem (Return two prime numbers )
Sieve of Eratosthenes (素数筛选算法) Given a number n, print all primes smaller than or equal to n. It is ...
- Spark RDD概念学习系列之RDD是什么?(四)
RDD是什么? 通俗地理解,RDD可以被抽象地理解为一个大的数组(Array),但是这个数组是分布在集群上的.详细见 Spark的数据存储 Spark的核心数据模型是RDD,但RDD是个抽象类 ...
- MVC中过虑特殊字符检测
[ValidateInput(false)] [HttpPost] public ActionResult Modify(Models.BlogArticle model) { //...... } ...
- Deep Learning 学习笔记——第9章
总览: 本章所讲的知识点包括>>>> 1.描述卷积操作 2.解释使用卷积的原因 3.描述pooling操作 4.卷积在实践应用中的变化形式 5.卷积如何适应输入数据 6.CNN ...