//*************************************************************************************************
// 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属性结构一样的话,继承了就直接可以实现功能。