基于cocoStudio的UIListView的可以左右滑动翻页的ListView

//WidgetSlideListView.h

class WidgetEaseInListView : public cocos2d::gui::UIListView

{

public:

	static WidgetEaseInListView* create(cocos2d::gui::UIListView* pAnthor=NULL);

	void doEaseIn(bool bRight2Left=true);



protected:

	virtual void copySpecialProperties(cocos2d::gui::Widget* model);



protected:

	virtual void onEaseInOver();

	virtual void startEaseIn(bool bRight2Left);

	virtual void tick(float delta);



protected:

	bool m_bRight2Left;

};



class SlideListViewDataSource

{

public:

	virtual size_t getTotalItemNum() = 0;

	virtual size_t getEveryPageItemNum() = 0;

	virtual cocos2d::gui::UIWidget* getWidgetAt(size_t nIdx) = 0;

	virtual void onPageTurnOver(size_t nCurrentPage){}

};



class WidgetSlideListView : public WidgetEaseInListView

{

	enum SlideDir

	{

		eSlideDir_None = 0,

		eSlideDir_Horizon_Left,

		eSlideDir_Horizon_Right,

		eSlideDir_Virtical

	};



protected:

	WidgetSlideListView();

	virtual ~WidgetSlideListView();



public:

	static WidgetSlideListView* create(SlideListViewDataSource* pDelegate,cocos2d::gui::UIListView* pAnthor=NULL);



public:

	void		setDelegate(SlideListViewDataSource* pDelegate){ m_pDelegate = pDelegate; }

	void		reloadData();

	size_t		getCurrentPage()const{ return m_nCurrentPage; }

	void		turnToPage(unsigned int nPage);



protected:

	virtual bool init();

	virtual void handleMoveLogic(const cocos2d::CCPoint &touchPoint);

	virtual void handleReleaseLogic(const cocos2d::CCPoint &touchPoint);    

	void		scheduleTurnPage(float t);





protected:

	SlideListViewDataSource* m_pDelegate;

	size_t		m_nCurrentPage;

	SlideDir	m_eSlideDir;

	cocos2d::CCPoint		m_BackPos;

};

  

//WidgetSlideListView.cpp

#include "../include/WidgetSlideListView.h"



USING_NS_CC;

USING_NS_CC_EXT;

using namespace cocos2d::gui;



WidgetEaseInListView* WidgetEaseInListView::create(UIListView* pAnthor/*=NULL*/)

{

	WidgetEaseInListView* pRet = new WidgetEaseInListView();

	if (pRet && pRet->init())

	{

		pRet->autorelease();

		if (pAnthor)

		{

			pRet->copyProperties(pAnthor);

		}



		return pRet;

	}

	else

	{

		delete pRet;

		pRet = NULL;

		return NULL;

	}

}



void WidgetEaseInListView::copySpecialProperties(cocos2d::gui::Widget* model)

{

	UIListView::copySpecialProperties(model);



	setDirection(SCROLLVIEW_DIR_VERTICAL);

	setBounceEnabled(true);

	setTouchEnabled(true);

}



void WidgetEaseInListView::tick(float delta)

{

	startEaseIn(m_bRight2Left);

}



void WidgetEaseInListView::doEaseIn(bool bRight2Left)

{

	stopAllActions();

	for (unsigned int i=0; i<getItems()->count(); i++)

	{

		UIWidget* pWidget = getItem(i);

		pWidget->setVisible(false);

	}

	m_bRight2Left = bRight2Left;

	scheduleOnce(schedule_selector(WidgetEaseInListView::tick),0);

}



void WidgetEaseInListView::startEaseIn(bool bRight2Left)

{

	setTouchEnabled(false);



	static const float fDelay = 0.1f;

	static const float fMoveTime = 0.4f;



	CCArray* pActSeq = CCArray::create();



	float fVisibleHeight = 0.0f;

	float fTotalHeight = getSize().height;

	CCArray* pArr = getItems();

	int nSlidCount =0;

	for (unsigned int i=0; i<pArr->count(); i++)

	{

		UIWidget* pWidget = getItem(i);

		pWidget->setVisible(true);



		fVisibleHeight+=pWidget->getSize().height;

		if (fVisibleHeight<fTotalHeight+pWidget->getSize().height)

		{

			float fOffset = (bRight2Left?1:-1)*pWidget->getContentSize().width;

			CCPoint startPos = ccpAdd(pWidget->getPosition(),ccp(fOffset,0));

			//CCPoint startPos = ccp(pWidget->getContentSize().width/2+fOffset,pWidget->getPosition().y);

			pWidget->setPosition(startPos);

			CCSequence* pAct = CCSequence::createWithTwoActions(CCDelayTime::create(fDelay*i),CCEaseBackOut::create(CCMoveBy::create(fMoveTime,ccp(-fOffset,0))));

			pActSeq->addObject(CCTargetedAction::create(pWidget,pAct) );



			nSlidCount++;

		}

	}

	CCSequence* pAct = CCSequence::createWithTwoActions(CCDelayTime::create(fDelay*nSlidCount),CCCallFunc::create(this,callfunc_selector(WidgetEaseInListView::onEaseInOver)));

	pActSeq->addObject(pAct);



	runAction(CCSpawn::create(pActSeq));

}



void WidgetEaseInListView::onEaseInOver()

{

	setTouchEnabled(true);

}





WidgetSlideListView::WidgetSlideListView()

	:m_pDelegate(NULL)

	,m_nCurrentPage(0)

	,m_eSlideDir(eSlideDir_None)

{



}



WidgetSlideListView::~WidgetSlideListView()

{



}



WidgetSlideListView* WidgetSlideListView::create(SlideListViewDataSource* pDelegate,UIListView* pAnthor/*=NULL*/)

{

	WidgetSlideListView* pRet = new WidgetSlideListView();

	if (pRet && pRet->init())

	{

		pRet->autorelease();

		pRet->setDelegate(pDelegate);

		if (pAnthor)

		{

			pRet->copyProperties(pAnthor);

		}



		return pRet;

	}

	else

	{

		delete pRet;

		pRet = NULL;

		return NULL;

	}



}



bool WidgetSlideListView::init()

{

	if (UIListView::init())

	{

		setDirection(SCROLLVIEW_DIR_VERTICAL);

		setBounceEnabled(true);

		setTouchEnabled(true);

		return true;

	}

	return false;

}



void WidgetSlideListView::reloadData()

{

	assert(m_pDelegate);

	assert(m_pDelegate->getEveryPageItemNum()>0);

	unsigned int nTotalPage = m_pDelegate->getTotalItemNum()/m_pDelegate->getEveryPageItemNum();

	nTotalPage+= m_pDelegate->getTotalItemNum()%m_pDelegate->getEveryPageItemNum()>0 ? 1 : 0;



	assert(m_nCurrentPage>=0);



	removeAllItems();

	if (m_pDelegate->getTotalItemNum()>0)

	{

		assert(m_nCurrentPage<nTotalPage);



		for (size_t i=0; i<m_pDelegate->getEveryPageItemNum(); i++)

		{

			if (m_pDelegate->getTotalItemNum()<(i+1)+m_nCurrentPage*m_pDelegate->getEveryPageItemNum())

			{

				break;

			}



			UIWidget* pChild = m_pDelegate->getWidgetAt(m_nCurrentPage*m_pDelegate->getEveryPageItemNum()+i);



			if (!pChild)

			{

				break;

			}



			pushBackCustomItem(pChild);

		}

	}

	jumpToTop();

}



void WidgetSlideListView::handleMoveLogic( const CCPoint &touchPoint )

{

	_touchMovedPoint = convertToNodeSpace(touchPoint);

	CCPoint delta = _touchMovedPoint - _touchBeganPoint;



	if (eSlideDir_None==m_eSlideDir)

	{

		m_eSlideDir = fabs(delta.x)>fabs(delta.y) ? eSlideDir_Horizon_Left : eSlideDir_Virtical;

		m_BackPos = _innerContainer->getPosition();

	}



	if (eSlideDir_Virtical==m_eSlideDir)

	{

		UIListView::handleMoveLogic(touchPoint);

	}

	else if (eSlideDir_None!=m_eSlideDir)

	{

		if (isTouchEnabled())

		{

			CCPoint pt = ccp(m_BackPos.x+delta.x,m_BackPos.y);

			_innerContainer->setPosition(pt);

		}

	}	

}



void WidgetSlideListView::handleReleaseLogic( const CCPoint &touchPoint )

{

	if (eSlideDir_Virtical==m_eSlideDir)

	{

		UIListView::handleReleaseLogic(touchPoint);

		m_eSlideDir = eSlideDir_None;

	}

	else if (eSlideDir_None!=m_eSlideDir)

	{

		if (isTouchEnabled())

		{

			CCPoint delta = _touchMovedPoint - _touchBeganPoint;



			static const float fDelatPosX = 30;

			if (delta.x<-fDelatPosX && m_pDelegate->getTotalItemNum()>(m_nCurrentPage+1)*m_pDelegate->getEveryPageItemNum())

			{

				m_eSlideDir = eSlideDir_Horizon_Left;

				scheduleOnce( schedule_selector(WidgetSlideListView::scheduleTurnPage),0);

			}

			else if (delta.x>fDelatPosX && m_nCurrentPage>0)

			{

				m_eSlideDir = eSlideDir_Horizon_Right;

				scheduleOnce( schedule_selector(WidgetSlideListView::scheduleTurnPage),0);

			}

			else

			{

				m_eSlideDir = eSlideDir_None;

				_innerContainer->setPosition(m_BackPos);

			}

		}

	}



}



void WidgetSlideListView::turnToPage(unsigned int nPage)

{

	bool bRight2Left = m_nCurrentPage<=nPage;

	m_nCurrentPage=nPage;

	reloadData();

	doEaseIn(bRight2Left);

	m_pDelegate->onPageTurnOver(m_nCurrentPage);

}



void WidgetSlideListView::scheduleTurnPage(float t)

{

	if (eSlideDir_Horizon_Left==m_eSlideDir)

	{

		turnToPage(m_nCurrentPage+1);

	}

	else if (eSlideDir_Horizon_Right==m_eSlideDir)

	{

		turnToPage(m_nCurrentPage-1);

	}



	m_eSlideDir = eSlideDir_None;

}

  

 

你可能感兴趣的:(ListView)