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

本文主要是介绍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__ */


这篇关于CCScrollView/CCTableView(CCTableViewDelegate CCTableViewDataSource CCTableView-滑动列表-游戏中大量使用 很重要的一个类)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/661561

相关文章

使用animation.css库快速实现CSS3旋转动画效果

《使用animation.css库快速实现CSS3旋转动画效果》随着Web技术的不断发展,动画效果已经成为了网页设计中不可或缺的一部分,本文将深入探讨animation.css的工作原理,如何使用以及... 目录1. css3动画技术简介2. animation.css库介绍2.1 animation.cs

使用雪花算法产生id导致前端精度缺失问题解决方案

《使用雪花算法产生id导致前端精度缺失问题解决方案》雪花算法由Twitter提出,设计目的是生成唯一的、递增的ID,下面:本文主要介绍使用雪花算法产生id导致前端精度缺失问题的解决方案,文中通过代... 目录一、问题根源二、解决方案1. 全局配置Jackson序列化规则2. 实体类必须使用Long封装类3.

Python文件操作与IO流的使用方式

《Python文件操作与IO流的使用方式》:本文主要介绍Python文件操作与IO流的使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、python文件操作基础1. 打开文件2. 关闭文件二、文件读写操作1.www.chinasem.cn 读取文件2. 写

PyQt6中QMainWindow组件的使用详解

《PyQt6中QMainWindow组件的使用详解》QMainWindow是PyQt6中用于构建桌面应用程序的基础组件,本文主要介绍了PyQt6中QMainWindow组件的使用,具有一定的参考价值,... 目录1. QMainWindow 组php件概述2. 使用 QMainWindow3. QMainW

使用Python自动化生成PPT并结合LLM生成内容的代码解析

《使用Python自动化生成PPT并结合LLM生成内容的代码解析》PowerPoint是常用的文档工具,但手动设计和排版耗时耗力,本文将展示如何通过Python自动化提取PPT样式并生成新PPT,同时... 目录核心代码解析1. 提取 PPT 样式到 jsON关键步骤:代码片段:2. 应用 JSON 样式到

java变量内存中存储的使用方式

《java变量内存中存储的使用方式》:本文主要介绍java变量内存中存储的使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、介绍2、变量的定义3、 变量的类型4、 变量的作用域5、 内存中的存储方式总结1、介绍在 Java 中,变量是用于存储程序中数据

关于Mybatis和JDBC的使用及区别

《关于Mybatis和JDBC的使用及区别》:本文主要介绍关于Mybatis和JDBC的使用及区别,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、JDBC1.1、流程1.2、优缺点2、MyBATis2.1、执行流程2.2、使用2.3、实现方式1、XML配置文件

macOS Sequoia 15.5 发布: 改进邮件和屏幕使用时间功能

《macOSSequoia15.5发布:改进邮件和屏幕使用时间功能》经过常规Beta测试后,新的macOSSequoia15.5现已公开发布,但重要的新功能将被保留到WWDC和... MACOS Sequoia 15.5 正式发布!本次更新为 Mac 用户带来了一系列功能强化、错误修复和安全性提升,进一步增

Java资源管理和引用体系的使用详解

《Java资源管理和引用体系的使用详解》:本文主要介绍Java资源管理和引用体系的使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、Java的引用体系1、强引用 (Strong Reference)2、软引用 (Soft Reference)3、弱引用 (W

ubuntu系统使用官方操作命令升级Dify指南

《ubuntu系统使用官方操作命令升级Dify指南》Dify支持自动化执行、日志记录和结果管理,适用于数据处理、模型训练和部署等场景,今天我们就来看看ubuntu系统中使用官方操作命令升级Dify的方... Dify 是一个基于 docker 的工作流管理工具,旨在简化机器学习和数据科学领域的多步骤工作流。