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__ */


最新文章

  1. Android-开发工具
  2. BenchmarkSQL测试脚本实现
  3. mapreduce精简概括--转
  4. Java 8 Lambda表达式
  5. Python 删除 数组
  6. iOS 页面间传值 之 属性传值,代理传值
  7. RxJava开发精要3-向响应式世界问好
  8. linux软件安装(rpm,源码编译)
  9. 一个案例深入Python中的__new__和__init__
  10. 免费MD5解密网站,轻松破解md5密码,mysql5/mysql323,ntlm,salt密码
  11. Vue.js响应式原理
  12. intelj idea中JRebel激活
  13. 剑指Offer——网易笔试题+知识点总结
  14. ES 在聚合结果中进行过滤
  15. Scheme来实现八皇后问题(2)
  16. hdoj:2027
  17. Python 读取目录、文件
  18. C#编程(六十)----------LINQ的概述
  19. tomcat的war由于损坏不能解压导致的服务不能启动
  20. wampserver 权限配置

热门文章

  1. Sikulix IDE简介
  2. JDBC项目实践
  3. 基于select模型的udp客户端实现超时机制
  4. NativeInt
  5. Spark RDD概念学习系列之RDD的依赖关系(宽依赖和窄依赖)(三)
  6. Chef
  7. MySQL [Warning] Can’t create test file xxx lower-test(转)
  8. 解析XtraBackup备份MySQL的原理和过程(转)
  9. Objective-C 学习笔记(1)
  10. WIFI接入Internet配置过程