您的位置:首页 > 其它

CCScrollView/CCTableView(CCTableViewDelegate CCTableViewDataSource CCTableView-滑动列表-游戏中大量使用 非常重要的一个类)

2016-04-08 10:44 537 查看
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);

///

使用样例

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


////////

///////

首先须要创建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__ */
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: