cocococococos 2 dxのTable ViewとSrollViewの混合は使います.


*********************************************************************
時間:2015-01-09
作者:Sharing_Li
転載先:http://blog.csdn.net/sharing_li/articale/detail/4298317
*********************************************************************
 
このゲームをプレイしたことがある人は、このようなデザインがあると知っているはずです.
cocos2dx之TableView和ScrollView的混合使用_第1张图片
         左右にスライドしてもいいし、上下にスライドしてもいいです.左右にスライドする時は上下にスライドできません.上下にスライドする時は左右にスライドできません.この効果はTableViewとScrelViewとを組み合わせて実現できます.つまりSrollViewを作って、二つのTablewiwをコンテンツとしてこのScrrollViewに入れてもいいです.このUI設計は「喜び消楽」の友達の手紙にも適用されます.一つのTablewiwだけ多くなりました.
         次にコード解説を行います.cococos 2 dxのバージョンは3.2です.まず実現後の効果図を見せてください.
cocos2dx之TableView和ScrollView的混合使用_第2张图片
 効果図を見終わったら、本文を見て、クラスを定義します.
 ヘッダファイル:CommoneView.h
#ifndef __COMBINE_VIEW_H__
#define __COMBINE_VIEW_H__

#include "cocos2d.h"
#include "extensions/cocos-ext.h"

USING_NS_CC;
USING_NS_CC_EXT;

enum Table
{
	Table_Left = 0,
	Table_Center,
	Table_Right
};

class CombineView : public Layer,TableViewDataSource,TableViewDelegate
{
public:
	CombineView();
	~CombineView();

	virtual bool init();
	static cocos2d::Scene * create();

	virtual Size tableCellSizeForIndex(TableView *table, ssize_t idx);
	virtual TableViewCell* tableCellAtIndex(TableView *table, ssize_t idx);
	virtual ssize_t numberOfCellsInTableView(TableView *table);
	virtual void tableCellTouched(TableView* table, TableViewCell* cell);

	virtual void scrollViewDidScroll(ScrollView* view);
	virtual void scrollViewDidZoom(ScrollView* view);

public:
	void SetTouch(bool isTouched);
	// scrollview   
	void adjustScrollView(float offset);
private:
	ScrollView * m_scrollView;
	TableView * m_leftTable;
	TableView * m_centerTable;
	TableView * m_rightTable;
	//scrollview       
	int m_curPage;
	//      
	Vec2 m_firstPoint;
	//scrollview   
	Vec2 m_offset;
	//         
	bool m_horizontal;
	bool m_vertical;
	//View   
	Size m_viewSize;
};

#endif // !__COMBINE_VIEW_H__
更にcppファイルの実現を見てみて、ここで主要なコードを説明して、完全なコードと資源が欲しいです.文章の最後にダウンロード(0ポイントダウンロード)をクリックしてください.
コードを書きます.メンバー変数を初期化する習慣を身につけます.このようにすれば、思わぬ間違いを避けることができます.使わない資源を覚えながら釈放してください.
CombineView::CombineView()
{
	m_scrollView = NULL;
	m_leftTable = NULL;
	m_centerTable = NULL;
	m_rightTable = NULL;
	m_curPage = 0;
	m_firstPoint = Vec2(0,0);
	m_offset = Vec2(0,0);
	m_vertical = false;
	m_horizontal = false;
	m_viewSize = Size(0,0);
}
効果図のように、私たちはscrollviewを作りたいです.こいつは5ヶ月の3つの細胞を妊娠しています.それぞれ3つのtableviewです.この3人の息子を区別するために、私達は彼らに名前をつけます.彼ら3人は一つの関数であるtableCllatIndexを共有します.名前を付けないと、どのように2番目の子供か分かりますか?
        m_scrollView = ScrollView::create();
	m_scrollView->setViewSize(m_viewSize);
	m_scrollView->setContentOffset(Point::ZERO);
	m_scrollView->setDelegate(this);
	m_scrollView->setDirection(ScrollView::Direction::HORIZONTAL);
	m_scrollView->setAnchorPoint(Point::ZERO);
	m_scrollView->setPosition(Vec2::ZERO);
	m_scrollView->setTouchEnabled(false);//       scrollview   ,     ~
	pView->addChild(m_scrollView);
	
	//    
	auto pContainer = Layer::create();
	pContainer->setContentSize(Size(m_viewSize.width * 3,m_viewSize.height));
	pContainer->setAnchorPoint(Point::ZERO);
	pContainer->setPosition(Vec2::ZERO);
	m_scrollView->setContainer(pContainer);

	//  tabelview
	auto containerSize = pContainer->getContentSize();
	m_leftTable = TableView::create(this, ViewSize);
	m_leftTable->setTag(Table_Left);
	m_leftTable->ignoreAnchorPointForPosition(false);
	m_leftTable->setAnchorPoint(Vec2(0.5,0.5));
	m_leftTable->setPosition(Vec2(containerSize.width / 6,containerSize.height / 2));
	m_leftTable->setDirection(ScrollView::Direction::VERTICAL);
	m_leftTable->setDelegate(this);
	m_leftTable->setVerticalFillOrder(TableView::VerticalFillOrder::TOP_DOWN);
	m_leftTable->reloadData();
	pContainer->addChild(m_leftTable);

	m_centerTable = TableView::create(this, ViewSize);	
	m_centerTable->setTag(Table_Center);
	m_centerTable->ignoreAnchorPointForPosition(false);
	m_centerTable->setAnchorPoint(Vec2(0.5,0.5));
	m_centerTable->setPosition(Vec2(containerSize.width / 2,containerSize.height / 2));
	m_centerTable->setDirection(ScrollView::Direction::VERTICAL);
	m_centerTable->setDelegate(this);
	m_centerTable->setVerticalFillOrder(TableView::VerticalFillOrder::TOP_DOWN);
	m_centerTable->reloadData();
	pContainer->addChild(m_centerTable);

	m_rightTable = TableView::create(this, ViewSize);
	m_rightTable->setTag(Table_Right);
	m_rightTable->ignoreAnchorPointForPosition(false);
	m_rightTable->setAnchorPoint(Vec2(0.5,0.5));
	m_rightTable->setPosition(Vec2(containerSize.width / 6 * 5,containerSize.height / 2));
	m_rightTable->setDirection(ScrollView::Direction::VERTICAL);
	m_rightTable->setDelegate(this);
	m_rightTable->setVerticalFillOrder(TableView::VerticalFillOrder::TOP_DOWN);
	m_rightTable->reloadData();
	pContainer->addChild(m_rightTable);
そして、タッチ機能の実現を見に来ました.まずtouchbeganです.
        auto listenerT = EventListenerTouchOneByOne::create();

	listenerT->onTouchBegan = [=](Touch * touch,Event * pEvent){
		m_firstPoint = touch->getLocation();
		m_offset = m_scrollView->getContentOffset();
		if (!m_scrollView->getBoundingBox().containsPoint(m_firstPoint))
		{
			return false;
		}
		return true;
	};
PS:m_をfirst Pointを和m_に変換する.scrollView同じ親ノードの下の座標、すなわちm_を呼び出します.first Point=pView->convert ToNodeSpace(mufirst Point)
簡潔で明瞭です.そしてtouchmovedを見ます.
        listenerT->onTouchMoved = [=](Touch * touch,Event * pEvent){
		auto movePoint = touch->getLocation();
		auto distance = movePoint.x - m_firstPoint.x;

		if ((distance > 0 && this->m_curPage == 0) || (distance < 0 && this->m_curPage == 2))
		{
			return;
		}

		//      ,  scorll table    
		if (fabs(movePoint.y - m_firstPoint.y) / fabs(distance) > 0.7 || m_vertical)
		{
			if (!m_horizontal)
			{
				m_vertical = true;
			}
			return;
		}
		else //  
		{
			if (!m_vertical)
			{
				m_horizontal = true;
			}
		}
		if (m_horizontal)
		{
			this->SetTouch(false);
		}
		m_scrollView->setContentOffset(Vec2(distance + m_offset.x,0));
	};
このコードの意味は、まず垂直にスライドするとm_を作ります.verticalはtrueに設定されていますので、水平にスライドできません.まず水平にスライドしたら、m_を作ります.horizontalはtrueに設定されていますので、関数Set Touchを呼び出して、3人の子供に対してtableviewで子守歌を歌います.おとなしく寝てください.そしてtouchendedを見に来ます.
       listenerT->onTouchEnded = [=](Touch * touch,Event * pEvent){
		auto endPoint = touch->getLocation();
		auto distance = endPoint.x - m_firstPoint.x;
		//      
		bool flag = false;
		if (fabsf(distance) < 60)
		{
			flag = true;
			if (distance < 0)
			{
				m_curPage--;
			}
			else if (distance > 0)
			{
				m_curPage++;
			}
		}

		//      ,  scroll table    
		if (m_vertical)
		{
			m_vertical = false;
			if (flag)
			{
				if (distance > 0)
				{
					m_curPage--;
				}
				else if (distance < 0)
				{
					m_curPage++;
				}
			}
			
			return ;
		}
		else
		{
			this->SetTouch(true);
		}

		this->adjustScrollView(distance);
		m_horizontal = false;
	};
このコードの意味は、if(fabsf(distance)<60)というif文はスライド効果の最適化であり、スライドが小さい場合はこのスライドを無視して、図は相変わらずです.
cocos2dx之TableView和ScrollView的混合使用_第3张图片
これは一目瞭然ですよね.次のコードは垂直にスライドするかそれとも水平にスライドするかを判断します.垂直になれば、そのままリターンします.リターンの前にm_を復元します.curPageの値.先のレベルなら、熟睡している3人の子供を起こします.そしてscrollviewの最終表示画面の調整:
void CombineView::adjustScrollView(float offset)
{
	if (offset < 0)
	{
		m_curPage++;
	}
	else if (offset > 0)
	{
		m_curPage--;
	}

	if (m_curPage < 0)
	{
		m_curPage = 0;
	}
	else if (m_curPage > 2)
	{
		m_curPage = 2;
	}

	auto adjustPoint = Vec2(-m_viewSize.width * m_curPage,0);
	m_scrollView->setContentOffsetInDuration(adjustPoint,0.1f);
}
リストされていないコードの一部は以下の通りです.
TableViewCell* CombineView::tableCellAtIndex(TableView *table, ssize_t idx)
{
	auto cell = table->dequeueCell();
	auto cellSize = this->tableCellSizeForIndex(table, idx);
	auto tag = table->getTag();

	if (!cell)
	{
		cell = new TableViewCell();
		cell->autorelease();
		Sprite * pCellBg = NULL;
		Label * pNum = NULL;
		Sprite * pIcon = NULL;
		switch (tag)
		{
		case Table_Left:
			{
				pCellBg = Sprite::create("combineview/cell.png");
				pNum = Label::createWithTTF("1","fonts/Marker Felt.ttf",20);
				pIcon = Sprite::create("combineview/book.png");
			}
			break;
		case Table_Center:
			{
				pCellBg = Sprite::create("combineview/cell2.png");
				pNum = Label::createWithTTF("2","fonts/Marker Felt.ttf",20);
				pIcon = Sprite::create("combineview/plane.png");
			}
			break;
		case Table_Right:
			{
				pCellBg = Sprite::create("combineview/cell3.png");
				pNum = Label::createWithTTF("3","fonts/Marker Felt.ttf",20);
				pIcon = Sprite::create("combineview/setting.png");
			}
		default:
			break;
		}
		pCellBg->setPosition(Vec2(cellSize.width / 2,cellSize.height / 2));
		cell->addChild(pCellBg);
		pNum->setColor(Color3B(255,0,0));
		pNum->setPosition(Vec2(cellSize.width * 0.1,cellSize.height / 2));
		cell->addChild(pNum);
		pIcon->setPosition(Vec2(cellSize.width * 0.85,cellSize.height / 2));
		pIcon->setScale(0.2);
		cell->addChild(pIcon);
	}
	return cell;
}
 
void CombineView::SetTouch(bool isTouched)
{
	m_leftTable->setTouchEnabled(isTouched);
	m_centerTable->setTouchEnabled(isTouched);
	m_rightTable->setTouchEnabled(isTouched);
}
最後に、終わりました.......おかしいです
コードには問題があります.わざとバグを残しました.みんなが発見したかどうかは分かりません.このバグが解決されないと、プログラムが壊れてしまいます.もし私の前のコードに従って運行したら、テーブルCelAtIndex関数の中で崩壊します.これはなぜですか?私たちはtableviewを作る時に、tableviewごとに設置したからです.なぜ成功しなかったですか?私たちはまだセットしていないので、タイブルCelAtIndexという斯は走り始めました.私たちはタイブル-getTagを通じて、実際には取れません.取れない以上、画像文字を作成することができません.空のポインタを呼び出すので、プログラムはBOOMになります.その張本人はTable View:create(this、View Size)です.こいつ、私達はソースコードの追跡を調整しました.
TableView* TableView::create(TableViewDataSource* dataSource, Size size, Node *container)
{
    TableView *table = new TableView();
    table->initWithViewSize(size, container);
    table->autorelease();
    table->setDataSource(dataSource);
    table->_updateCellPositions();
    table->_updateContentSize();

    return table;
}
最後から二番目の文章はテーブル->('uudateContentSize();内部では、テーブルCelAtIndexという関数が呼び出されます.問題を見つけました.どう解決すればいいですか?分かりにくいです.ソースを変えますか?いいえ、私達はこのようにtableviewを作成できます.
        //m_rightTable = TableView::create(this, ViewSize);	
	m_rightTable = new TableView();
	m_rightTable->initWithViewSize(m_viewSize, NULL);
	m_rightTable->autorelease();
	m_rightTable->setDataSource(this);
では、なぜテーブル-><>を外しましたか?udateCelPositions();これは保護メンバー関数ですので、訪問できません.また使えません.これからも似たような問題があったら、このように解決してもいいです.そして三つのテーブルビューを変えたらいいです.
コードとリソースのダウンロード先:http://download.csdn.net/detail/sharing_li/8345111