标签:
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*
table, CCTableViewCell* cell) { CCLog( "cell
touched at index: %i" ,
cell->getIdx()); } ///// |
//每一项的宽度和高度必须重写的一个虚函数
virtual
cocos2d::CCSize
cellSizeForTable(cocos2d::extension::CCTableView *table);
//生成列表每一项的内容
必须重写的一个虚函数
virtual
cocos2d::extension::CCTableViewCell*
tableCellAtIndex(cocos2d::extension::CCTableView *table, unsigned
int
idx);
////////
CCTableViewCell*
ListViewLayer::tableCellAtIndex(CCTableView *table, unsigned int idx) { CCString
*pString = CCString::createWithFormat( "%d" ,
idx); CCTableViewCell
*pCell = table->dequeueCell(); //得到一个将要离队(释放)的cell if (!pCell)
{ //假设释放池中没有 就自己创建一个 节约内存 pCell
= new CCTableViewCell(); 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()); } return pCell; } |
//一共多少项必须重写的一个虚函数
virtual
unsigned
int
numberOfCellsInTableView(cocos2d::extension::CCTableView
*table);
unsigned int ListViewLayer::numberOfCellsInTableView(CCTableView
*table) { 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__ */
标签:
原文地址:http://www.cnblogs.com/bhlsheji/p/5367050.html