Cocos2dx TableView常用功能的封装

//*************************************************************************************************
// Creation Time       :2018.7.5
// Module Specification:cocos Tabview实现基础功能的基类。
// Version Number      :
// Author Name         :
//*************************************************************************************************

/* ------------------------------------------------------------------------------------------------
提供功能:
	1.基础的Tabview的显示功能;
	2.点击选中Cell效果;
	3.具体Item定位功能;
	4.选中刷新效果;
	5.支持多个Tabview显示。


 一、csd文件节点的结构如下
 .csd 文件List和Cell同级,子节点都在Cell节点里面即可。(如果需要点击效果,则Cell_n中需要有Select节点)

 ----
	|
	----List
	----Cell
		 |
		 ----Cell_1
		 ----Cell_n

 二、必须调用的接口(注意顺序)
 //1.init data
 initData();

 //2.init layer
 initTabLayer("Gui/PetPVE_Team_Pet.csb");

 //3.init tabview
 initTabView(vTabView);

 三、其他可按照具体需求重写接口即可。

 四、示例代码

  A.UI文件结构
 ----Root
		|
		-Title
		|	|
		|	-Tag
		-Team
		|	|
		|	-List
		|   -Cell
		|		|
		|		-Cell_1
		|			|
		|			-Select
		|
		-Pool
			|
			-List
			-Cell
				|
				-Cell_1
				-Cell_2
				-Cell_n
 ------------------------------------------------------------------------------------------------ */



#ifndef __TABVIEW_BASE_VIEW_H__
#define __TABVIEW_BASE_VIEW_H__

#include "cocos2d.h"
#include "cocostudio/CocoStudio.h"
#include "extensions/cocos-ext.h"
#include "ui/CocosGUI.h"


USING_NS_CC;
USING_NS_CC_EXT;

using namespace cocostudio;
using namespace cocos2d::ui;



class CTableViewBaseView : public Layer, TableViewDataSource, TableViewDelegate
{
public:
	enum class TableViewSign
	{
		FirstTableviewSign = 0,
		SecondTableviewSign,
		MaxTableviewSign,
	};

	struct TableViewParameters
	{
		std::string sTabViewListParentPath;
		extension::ScrollView::Direction firstDirection;
		TableView::VerticalFillOrder firstFillOrder;
		uint32_t iTabviewLineCellCount;

		TableViewParameters(
			std::string _sTabViewListParentPath = "",
			extension::ScrollView::Direction _firstDirection = extension::ScrollView::Direction::HORIZONTAL,
			TableView::VerticalFillOrder _firstFillOrder = TableView::VerticalFillOrder::TOP_DOWN,
			int _iTabviewLineCellCount = 0)
		{
			sTabViewListParentPath = _sTabViewListParentPath;
			firstDirection = _firstDirection;
			firstFillOrder = _firstFillOrder;
			iTabviewLineCellCount = _iTabviewLineCellCount;
		}
	};


public:
	CTableViewBaseView();
	~CTableViewBaseView();

	/*
	must init data, and before initTabLayer and initTabView
	*/
	virtual void initData(int count, ...) = 0;

	/*
	init layer.
	*/
	void initTableLayer(std::string sUICsdPath);

	/*
	init tabview.
	*/
	void initTableView(const std::vector<TableViewParameters> &tabviews);

	/*
	refresh first tabview and second tabview.
	*/
	void refreshUI();

	/*
	update tabview
	*/
	void freshTableView(TableViewSign tableviewIndex = TableViewSign::FirstTableviewSign, bool bForce = true);

	/*
	navigate to tabview some line for index. default navigate to the cell in top
	*/
	void navigateTableviewCell(TableViewSign tableviewIndex = TableViewSign::FirstTableviewSign, uint32_t iCellIndex = 0);

	/*
	select tabview one cell, maybe one line has multiple cell.
	*/
	void selectTableviewCell(TableViewSign tableviewIndex = TableViewSign::FirstTableviewSign, uint32_t iCellIndex = 0);

	/*
	update info, maybe it is Title, name and so on
	*/
	virtual void freshInfo(TableViewSign tableviewIndex = TableViewSign::FirstTableviewSign);


protected:
	/* UI */
	Node* m_pWindow;

	/* tabview1...tabview n's datas size */
	std::vector<uint32_t> m_vAllItemCount;

	/* tabview1...tabview n's select index */
	std::vector<uint32_t> m_vSelectIndex;

	/* tabview one line has cell count */
	std::vector<uint32_t> m_vTableViewLineCellCount;

private:
	void __initTableLayer(std::string sUICsdPath);
	void __initTableView(const std::vector<TableViewParameters> &tabviews);

private:
	//
	/*
	tabview need overload function
	*/
	virtual void tableCellTouched(TableView* table, TableViewCell* cell);
	virtual void tableCellTouched(TableView* table, TableViewCell* cell, Touch *pTouch);
	virtual Size tableCellSizeForIndex(TableView *table, ssize_t idx);
	virtual TableViewCell* tableCellAtIndex(TableView *table, ssize_t idx);
	virtual ssize_t numberOfCellsInTableView(TableView *table);
	virtual void scrollViewDidScroll(extension::ScrollView* view);
	virtual void scrollViewDidZoom(extension::ScrollView* view);

	virtual void setCell(Node* pCell, TableViewSign tableviewIndex, uint32_t iIndex);

private:
	//
	/* UI */
	std::vector<TableView*> m_vTableView;
	std::vector<Size> m_vCellSize;

	//
	/* data */

	/* tabview count*/
	uint32_t m_iTableViewMaxCount;//min 1

	/* tabview1...tabview n's parent path */
	std::vector<std::string> m_vTableViewListParentPath;
};

#endif //__TABVIEW_BASE_VIEW_H__

 

 

 

#include "WildsPCH.h"
#include "TableviewBaseView.h"



CTableViewBaseView::CTableViewBaseView()
	: m_pWindow(nullptr)
	, m_iTableViewMaxCount(0)
{
	m_vTableView.clear();
	m_vCellSize.clear();
	m_vAllItemCount.clear();
	m_vSelectIndex.clear();
	m_vTableViewListParentPath.clear();
	m_vTableViewLineCellCount.clear();
}

CTableViewBaseView::~CTableViewBaseView()
{
}

void CTableViewBaseView::initTableLayer(std::string sUICsdPath)
{
	/*
	para sUICsdPath: cocos csd path. For example "Gui/PetPVE_Team_Pet.csb";
	*/
	__initTableLayer(sUICsdPath);
}

void CTableViewBaseView::initTableView(const std::vector<TableViewParameters> &tabviews)
{
	assert(m_vAllItemCount.size() == tabviews.size());

	__initTableView(tabviews);
}

void CTableViewBaseView::refreshUI()
{
	freshTableView(TableViewSign::FirstTableviewSign);
	freshTableView(TableViewSign::SecondTableviewSign);
}

void CTableViewBaseView::freshTableView(TableViewSign tableviewIndex /*= TableViewSign::FirstTableviewSign*/, bool bForce /*= true*/)
{
	uint32_t iTableViewTag = uint32_t(tableviewIndex);
	if (iTableViewTag >= 0 && iTableViewTag < m_iTableViewMaxCount)
	{
		if (bForce)
		{
			m_vTableView.at(iTableViewTag)->reloadData();
		}
		else
		{
			ssize_t size = numberOfCellsInTableView(m_vTableView.at(iTableViewTag));
			for (int i = 0, c = size; i < c; ++i)
			{
				m_vTableView.at(iTableViewTag)->updateCellAtIndex(i);
			}
		}
	}
}

void CTableViewBaseView::freshInfo(TableViewSign tableviewIndex /*= TableViewSign::FirstTableviewSign*/)
{

}

void CTableViewBaseView::navigateTableviewCell(TableViewSign tableviewIndex /*= TableViewSign::FirstTableviewSign*/, uint32_t iCellIndex /*= 0*/)
{
	uint32_t iTableViewTag = uint32_t(tableviewIndex);

	if (iTableViewTag < 0 || iTableViewTag >= m_iTableViewMaxCount)
		return;

	//date size
	uint32_t size = m_vAllItemCount.at(iTableViewTag);

	//line count
	uint32_t iTabviewLineCellCount = m_vTableViewLineCellCount.at(iTableViewTag);

	if (iCellIndex < 0 || iCellIndex >= size)
		return;

	float fCellHeight = m_vCellSize.at(iTableViewTag).height;
	float fTabviewHeight = m_vTableView.at(iTableViewTag)->getContentSize().height;

	float fTotalHeight = fCellHeight * ((size + iTabviewLineCellCount - 1) / iTabviewLineCellCount);
	float fUpLeftHeight = fCellHeight * (iCellIndex / iTabviewLineCellCount);

	float fOffsetY = 0.0;
	if (fTotalHeight < fTabviewHeight)
	{
		fOffsetY = fTabviewHeight - fTotalHeight;
	}
	else
	{
		fOffsetY = fTabviewHeight - (fTotalHeight - fUpLeftHeight);
		if (fOffsetY > 0) fOffsetY = 0;
	}

	m_vTableView.at(iTableViewTag)->setContentOffset(Vec2(0.0f, fOffsetY), false);
}

void CTableViewBaseView::selectTableviewCell(TableViewSign tableviewIndex /*= TableViewSign::FirstTableviewSign*/, uint32_t iCellIndex /*= 0*/)
{
	uint32_t iTableViewTag = uint32_t(tableviewIndex);

	if (iTableViewTag < 0 || iTableViewTag >= m_iTableViewMaxCount)
		return;

	//date size
	uint32_t size = m_vAllItemCount.at(iTableViewTag);

	if (iCellIndex < size)
		m_vSelectIndex.at(iTableViewTag) = iCellIndex;

	freshTableView((TableViewSign)iTableViewTag, false);
	freshInfo((TableViewSign)iTableViewTag);
}


//-------------------------------- private >>> --------------------------------------------------------
void CTableViewBaseView::__initTableLayer(std::string sUICsdPath)
{
	m_pWindow = HelpFunc::CreateUINode(sUICsdPath);
	assert(m_pWindow);
	addChild(m_pWindow, 0, "CPetFightingPetChoose");
}

void CTableViewBaseView::__initTableView(const std::vector<TableViewParameters> &tabviews)
{
	/*
	para sFirstTabViewListParentPath:
	*/

	//init m_iTableViewMaxCount
	m_iTableViewMaxCount = tabviews.size();

	int iTableViewIndex = 0;
	for (auto tabview : tabviews)
	{
		std::string sTabViewListParentPath = tabview.sTabViewListParentPath;
		extension::ScrollView::Direction firstDirection = tabview.firstDirection;
		TableView::VerticalFillOrder firstFillOrder = tabview.firstFillOrder;
		uint32_t iTabviewLineCellCount = tabview.iTabviewLineCellCount;

		assert(sTabViewListParentPath != "");
		assert(iTabviewLineCellCount > 0);

		m_vTableViewListParentPath.push_back(sTabViewListParentPath);
		m_vTableViewLineCellCount.push_back(iTabviewLineCellCount);

		m_vSelectIndex.push_back(0);

		//
		Node* pMain = m_pWindow->getChildByPath(sTabViewListParentPath);
		assert(pMain);

		//set cell item size
		Layout* pListCell = (Layout*)pMain->getChildByPath("Cell");
		assert(pListCell);

		pListCell->setVisible(false);//very import
		m_vCellSize.push_back(pListCell->getContentSize());

		//reset tabview
		ListView* pSubListView = (ListView*)pMain->getChildByPath("List");
		assert(pSubListView);

		pSubListView->removeAllItems();

		TableView* pTableView = TableView::create(this, pSubListView->getContentSize());
		pTableView->setTag(iTableViewIndex);
		pTableView->setDirection(firstDirection);
		pTableView->ignoreAnchorPointForPosition(false);
		pTableView->setAnchorPoint(Vec2(0, 0));
		pTableView->setPosition(pSubListView->getPosition());
		pTableView->setDelegate(this);
		pTableView->setVerticalFillOrder(firstFillOrder);
		pTableView->reloadData();
		pMain->addChild(pTableView);

		m_vTableView.push_back(pTableView);

		iTableViewIndex++;
	}
}


//-------------------------------- override >>> --------------------------------------------------------
void CTableViewBaseView::scrollViewDidScroll(extension::ScrollView* view)
{
}

void CTableViewBaseView::scrollViewDidZoom(extension::ScrollView* view)
{
}

void CTableViewBaseView::tableCellTouched(TableView* table, TableViewCell* cell)
{
}

void CTableViewBaseView::tableCellTouched(TableView* table, TableViewCell* cell, Touch *pTouch)
{
	uint32_t iTableViewTag = (uint32_t)table->getTag();

	//date size
	uint32_t size = m_vAllItemCount.at(iTableViewTag);

	//line count
	uint32_t iTabviewLineCellCount = m_vTableViewLineCellCount.at(iTableViewTag);

	for (int i = 0; i < iTabviewLineCellCount; ++i)
	{
		Node* pCell = cell->getChildByPath("Cell/Cell_" + std::to_string(i + 1));
		if (!pCell || (pCell && !pCell->isVisible()))
			continue;

		/*
		very import .
		here use node “Select”,because pCell had scale ,so must use a new node show boundingBox.
		if has demand, can overload.
		*/
		ImageView* pCellSelect = (ImageView*)pCell->getChildByPath("Select");
		if(!pCellSelect)
			continue;

		Rect bb = pCellSelect->getBoundingBox();
		bb.origin = pCellSelect->getParent()->convertToWorldSpace(bb.origin);

		if (bb.containsPoint(pTouch->getLocation()))
		{
			uint32_t index = pCell->getTag();

			if (index < size)
				m_vSelectIndex.at(iTableViewTag) = index;

			freshTableView((TableViewSign)iTableViewTag, false);
			freshInfo((TableViewSign)iTableViewTag);
			break;
		}
	}
}

Size CTableViewBaseView::tableCellSizeForIndex(TableView *table, ssize_t idx)
{
	// 设置cell的大小
	uint32_t iTableViewTag = (uint32_t)table->getTag();

	if (iTableViewTag >= 0 && iTableViewTag < m_iTableViewMaxCount)
	{
		return m_vCellSize.at(iTableViewTag);
	}

	return Size(0.0, 0.0);
}

TableViewCell* CTableViewBaseView::tableCellAtIndex(TableView *table, ssize_t idx)
{
	// 获取序号为idx的cell
	auto cell = table->dequeueCell();
	auto cellSize = this->tableCellSizeForIndex(table, idx);
	auto iTableViewTag = table->getTag();

	if (iTableViewTag < 0 || iTableViewTag >= m_iTableViewMaxCount)
	{
		return cell;
	}

	if (!cell)
	{
		cell = new TableViewCell();
		cell->autorelease();
		Node* pMain = m_pWindow->getChildByPath(m_vTableViewListParentPath.at(iTableViewTag));
		assert(pMain);
		Layout* pListCell = (Layout*)pMain->getChildByPath("Cell");
		assert(pListCell);

		Layout* pCellClone = (Layout*)pListCell->clone();
		pCellClone->setPosition(Vec2(0, 0));
		pCellClone->setTouchEnabled(false);//very import
		pCellClone->setVisible(true);
		cell->addChild(pCellClone, 0, "Cell");
	}

	//date size
	uint32_t size = m_vAllItemCount.at(iTableViewTag);

	//line count
	uint32_t iTabviewLineCellCount = m_vTableViewLineCellCount.at(iTableViewTag);
	for (int i = 0; i < iTabviewLineCellCount; ++i)
	{
		uint32_t index = idx * iTabviewLineCellCount + i;

		Node* pCell = cell->getChildByPath("Cell/Cell_" + std::to_string(i + 1));
		if(!pCell)
			continue;

		bool bHasInfo = index < size;
		pCell->setVisible(bHasInfo);

		if (!bHasInfo)
			continue;

		pCell->setTag(index);

		setCell(pCell, (TableViewSign)iTableViewTag, index);
	}

	return cell;
}

void CTableViewBaseView::setCell(Node* pCell, TableViewSign tableviewIndex, uint32_t iIndex)
{
}

ssize_t CTableViewBaseView::numberOfCellsInTableView(TableView *table)
{
	uint32_t iTableViewTag = (uint32_t)table->getTag();

	if (iTableViewTag >= 0 && iTableViewTag < m_iTableViewMaxCount)
	{
		uint32_t iTabviewItemCount = m_vAllItemCount.at(iTableViewTag);
		uint32_t iTabviewLineCellCount = m_vTableViewLineCellCount.at(iTableViewTag);

		return ((iTabviewItemCount + iTabviewLineCellCount - 1) / iTabviewLineCellCount);
	}

	return 0;
}
//--------------------------------<<< override  --------------------------------------------------------

这里主要将cocos2dx中的Tableview中的常用的一些功能封装起来,方便下次使用。Tableview是重写numberOfCellsInTableView等几个接口的,所有这里直接将基础功能的几个函数都重写了,如果不需要特殊的功能的话,只要csd属性结构一样的话,继承了就直接可以实现功能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值