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);

///

使用样例

class ListViewLayer : 
public cocos2d::CCLayer, 
public cocos2d::extension::CCTableViewDataSource, (关于cell的数据 包含4个虚函数: tableCellSizeForIndex cellSizeForTable tableCellAtIndex numberOfCellsInTableView
public cocos2d::extension::CCTableViewDelegate(继承自CCScrollViewDelegate 又添加了4个触摸回调 包含4个虚函数:tableCellTouchedtableCellHighlighttableCellUnhighlight tableCellWillRecycle)
{
public :
     virtual bool init(); 
///
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;
}
//

 
     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);
// 
voidListViewLayer::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 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;
}
     //一共多少项必须重写的一个虚函数
     virtual unsigned int numberOfCellsInTableView(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__ */


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值