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个虚函数:tableCellTouchedtableCellHighlighttableCellUnhighlight
tableCellWillRecycle)
{
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*
table, CCTableViewCell* cell)
{
    CCLog("cell
touched at index: %i"
,
cell->getIdx());
}
/////

//每一项的宽度和高度必须重写的一个虚函数

    virtualcocos2d::CCSize
cellSizeForTable(cocos2d::extension::CCTableView *table);
    //生成列表每一项的内容
必须重写的一个虚函数
    virtualcocos2d::extension::CCTableViewCell*
tableCellAtIndex(cocos2d::extension::CCTableView *table, unsigned
intidx);
////////

 
CCTableViewCell*
ListViewLayer::tableCellAtIndex(CCTableView *table, unsigned
intidx)
{
    CCString
*pString = CCString::createWithFormat(
"%d",
idx);
    CCTableViewCell
*pCell = table->dequeueCell(); //得到一个将要离队(释放)的cell
    if(!pCell)
{ //假设释放池中没有 就自己创建一个 节约内存
        pCell
=
newCCTableViewCell();
        pCell->autorelease();
        CCSprite
*pSprite = CCSprite::create(
"listitem.png");
        pSprite->setAnchorPoint(CCPointZero);
        pSprite->setPosition(CCPointZero);
        pCell->addChild(pSprite);
 
        CCLabelTTF
*pLabel = CCLabelTTF::create(pString->getCString(),
"Arial",
20.0);
        pLabel->setPosition(CCPointZero);
        pLabel->setAnchorPoint(CCPointZero);
        pLabel->setTag(123);
        pCell->addChild(pLabel);
    }
    else
    {
        CCLabelTTF
*pLabel = (CCLabelTTF*)pCell->getChildByTag(123);
        pLabel->setString(pString->getCString());
    }
 
    returnpCell;
}

////////

    //一共多少项必须重写的一个虚函数
    virtualunsignedintnumberOfCellsInTableView(cocos2d::extension::CCTableView
*table);
 /////
 
unsignedintListViewLayer::numberOfCellsInTableView(CCTableView
*table)
{
    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-滑动列表-游戏中大量使用 非常重要的一个类)的更多相关文章

  1. 【Cocos2dx游戏开发】CCTableView实现滑动列表

    在游戏中,经常需要用到列表展示,例如我现在做的卡牌游戏中就有卡牌列表和好友列表需要用到CCTableView,下面简单介绍一下使用方法. CCTableView位于扩展库文件cocos-ext.h中, ...

  2. Unity3d NGUI的使用(九)(UIScrollView制作滑动列表)

    UIScrollView制作滑动列表,可横向,竖直展示一些列表在固定可视范围内 UIScrollVIew只是一个可滑动的UI组件 如果需要制作复杂的可视区域UI需要配合使用UIPanel与UIGrid ...

  3. 使用泛型简单封装NGUI的ScrollView实现滑动列表

    懒,是老毛病了,周末跑了半马,跑完也是一通累,好久没锻炼了..也是懒的,有时都懒的写博客..最近看到项目中各种滑动列表框,本着要懒出水平来的原则,决定花点时间简单处理下(暂时未做列表太多时的优化):1 ...

  4. Android滑动列表(拖拽,左滑删除,右滑完成)功能实现(2)

    ItemTouchHelper类 之前我们实现了滑动列表的一些基本功能,为了实现更多的效果,我们来仔细看一下ItemTouchHelper中的类: ItemTouchHelper.SimpleCall ...

  5. [转]ionic3项目实战教程三(创建provider、http请求、图文列表、滑动列表)

    本文转自:https://blog.csdn.net/lyt_angularjs/article/details/81145468 版权声明:本文为博主原创文章,转载请注明出处.谢谢! https:/ ...

  6. [UGUI]滑动列表优化(循环利用)

    需要注意的有下面几点: 1. 区分好表现上的index和逻辑上的index.表现上的index是指这个go是go列表中的第几项,但实际上这个index的意义并不大,因为在滚动的过程中go列表是轮转的: ...

  7. Flexbox + js实现滑动拼图游戏

    滑动拼图就是把一张图片分成几等份,打乱顺序(下图),然后通过滑动拼凑成一张完整的图片. 要实现一个拼图游戏,需要考虑怎样随机的打乱顺序,怎样交换两张图片的位置,等等.但是,使用了Flexbox布局以后 ...

  8. 实现移动端touch事件的横向滑动列表效果

    要实现手机端横向滑动效果并不难,了解实现的原理及业务逻辑就很容易实现.原理:touchstart(手指按下瞬间获取相对于页面的位置)——>touchmove(手指移动多少,元素相应移动多少). ...

  9. egret之好友列表(滑动列表)

    本文采用List+Scroller实现列表滑动功能 首先新建两个皮肤,一个用做好友界面的显示,一个用作单个好友的显示,新建皮肤如下: 皮肤一取名为:wxMainSkin,添加如下控件 皮肤一取名为:w ...

随机推荐

  1. 开发环境配置(netbeans+ant迁移到eclipse+maven)

    新公司入职,接手一个离职人员的项目,拿到的源码是以一个压缩包,用netbeans开发,ant管理:前端:jsp+extjs,后端:springmvc+hibernate+activiti+spring ...

  2. VMware 命令行下安装以及导入Ubuntu系统

    前提: 鉴于个人PC性能太弱,考虑是否可以将在PC上搭建好的环境移植到高性能服务器上.想到后就干呗. 下载完对应操作系统的安装包后按如下步骤操作: 安装包名称:VMware-Workstation-F ...

  3. SQL查询数据库信息, 数据库表名, 数据库表信息

    SQL查询数据库信息, 数据库表名, 数据库表信息 ---------------------------------------------- -- 以下例子, 在sql_server 中可以直接运 ...

  4. mysql error: Access denied for user 'root'@'localhost' (using password: YES)

    昨天重装了下系统,安装好mysql后,安装了客户端工具连接mysql,提示Access denied for user 'root'@'localhost' (using password: YES) ...

  5. STL源码分析读书笔记--第5章--关联式容器

    1.关联式容器的概念 上一篇文章讲序列式容器,序列式容器的概念与关联式容器相对,不提供按序索引.它分为set和map两大类,这两大类各自有各自的衍生体multiset和multimap,的底层机制都是 ...

  6. 神奇的linux发行版 tiny core linux

    首先官网在此 http://tinycorelinux.net/ 真正轻量级 名字里带有“tiny”又带有“core”,想必又是一个所谓的“轻量级”发行版. 轻量级我们见多了,debian号称是轻量级 ...

  7. VMWare高可用集群在企业的应用

    650) this.width=650;" border="0" src="http://img1.51cto.com/attachment/201011/21 ...

  8. UVALive 3959 Rectangular Polygons (排序贪心)

    Rectangular Polygons 题目链接: http://acm.hust.edu.cn/vjudge/contest/129733#problem/G Description In thi ...

  9. (转载)javascript函数作用域和提前声明

    http://www.cnblogs.com/ArthurPatten/p/3274080.html 一些语言如C.java都有块级作用域,即花括号内的每一段代码都具有各自的作用域,而且变量在声明它们 ...

  10. <filter-mapping> 的 <dispatcher> 的作用

    The dispatcher has four legal values: FORWARD, REQUEST, INCLUDE, and ERROR. A value of FORWARD means ...