CocoStudio sample讲解 SampleImageViewer 图片查看器

CocoStuido sample----SampleImageViewer源代码地址
https://github.com/chukong/CocoStudioSamples
大家可以预先下载这个源代码, 等下要用到里面的图片资源哦
一 目标

在本教程里, 我们使用UI编辑器制作一个简易的图片查看器, 可以通过左右滑动来切换, 并在cocos2d-x中运行.
我们使用的cocos2d-x的版本是2.2.2, CocoStudio的版本是1.2.0.1. 不同的版本, 功能上会有差异, 大家学习时, 最好采用对应的版本.
二 创建项目并导入资源
大家可以在下载到的源代码的SampleImageViewer\SampleImageViewer_editor\Resources 目录下找到我们需要的资源.
我们首先打开UI编辑器, 并创建一个新的项目.
然后大家可以在资源面板点击导入文件按钮, 导入这些资源文件, 导入后的资源面板如下.

三 构建界面
大家可以在画布列表看到默认的画布, 可以给其重命名以便于识别, 我们这里将其命名为"page_1".

让我们先来为我们的项目添加一个背景吧.
从工具栏面板拖拽一个图片控件到渲染区, 在对象结构面板选中这个图片控件, 打开属性面板.
我们在属性面板中修改其名字为"background_imageview", 并从资源面板拖拽"background.png"到其文件属性框中. 如下图所示:


这张图是作为背景图的, 所以我们还需要在渲染区中将其移动到合适的位置.
然后我们再来制作下顶部的标题栏.
拖拽一个层容器控件, 然后修改其属性. 宽高分别是480, 57, 勾选开启九宫格, 名字为"page_alert_top_panel", 将"ribbon.png"拖拽到文件属性框, 填充颜色选无颜色. 然后将其在渲染区拖拽到合适的位置. 这里不再截图.
我们还需要在标题栏区域显示文字, 来标示当前显示的图片.
拖拽一个文本框控件到渲染区"page_alert_top_panel"上, "page_alert_top_panel"应该会被标示为黄色的框.

这时我们新添加的文本框将成为"page_alert_top_panel"的子节点.
我们可以将整个UI想象成一个树状的结构, 合理地设置父子节点, 会便于我们管理界面元素中节点的关系.
大家可以参照源代码下的工程, 一一添加所需要的节点, 并修改其位置和各种属性, 这里不再一一赘述, 如果有问题, 欢迎大家来CocoaChina论坛的CocoStudio专区来交流讨论.
最后我们再来看下对象结构面板, 大家可以清晰地看到节点的树状关系.

如果发现界面元素前后关系不对, 比如page_alert_top_panel被background_imageview遮挡, 这时就需要在属性面板中调整渲染层级. 将page_alert_top_panel的渲染层级调的高于background_imageview即可.
四 导出资源
用快捷键Ctrl+E打开导出对话框, 选择导出的路径, 按默认配置导出. 我们稍后会用到这些文件.
五 在cocos2d-x工程中添加导出后的资源
想必各位看官都已经熟练掌握了cocos2d-x工程的创建, 我这里就不再啰嗦了.
创建完工程之后, 需要将我们上面用CocoStudio导出的几个文件拷贝到cocos2d-x工程的Resources文件夹下.
六 代码实现
我们在工程中添加一个CocosGUIExamplesPageScene的类, 我们先来看下CocosGUIExamplesPageScene.h类的声明部分.

//添加头文件#include “cocos2d.h”#include “cocos-ext.h”
//使用命名空间USING_NS_CC ;USING_NS_CC_EXT ;using namespace gui;
//定义一个tag#define PAGE_PAGEVIEW_TAG 1000
//从CCScene派生class CocosGUIExamplesPageScene : public CCScene{public : virtual void onEnter(); virtual void onExit(); protected : void menuCloseCallback( CCObject * pSender, TouchEventType type); void PageInit(); //页面初始化函数 void pageViewEvent( CCObject * pSender, PageViewEventType type); //页面切换回调事件 protected : TouchGroup* m_pUILayer; //layer对象};

我们再来看下CocosGUIExamplesPageScene.cpp, 类的实现部分.

#include “CocosGUIExamplesPageScene.h”
//图片路径const char * page_image_textures ={ “cocosgui/gui_examples/page_1/page_content/CocoStudio_AnimationEditor.png” , “cocosgui/gui_examples/page_1/page_content/CocoStudio_DataEditor.png” , “cocosgui/gui_examples/page_1/page_content/CocoStudio_SceneEditor.png” , “cocosgui/gui_examples/page_1/page_content/CocoStudio_UIEditor.png” ,};
void CocosGUIExamplesPageScene ::onEnter(){ CCScene::onEnter(); m_pUILayer = TouchGroup ::create();//生成一个TouchGroup对象 m_pUILayer->scheduleUpdate(); addChild(m_pUILayer); PageInit(); //初始化页面 CCSize winSize = CCDirector ::sharedDirector()->getWinSize(); //添加一个提示 gui:: Label* label = gui:: Label ::create(); label->setText( “Move by horizontal direction” ); const char* font =#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) // custom ttf files are defined in Test-info.plist “Marker Felt”;#else “fonts/Marker Felt.ttf”;#endif label->setFontName(font); label->setFontSize(32); label->setAnchorPoint( ccp (0.5f, -1)); label->setPosition( ccp (winSize.width / 2.0f, winSize.height / 2.0f + label->getSize().height * 1.5)); m_pUILayer->addWidget(label); //添加一个退出按钮 Button* exit_button = Button ::create(); exit_button->setTouchEnabled( true ); exit_button->loadTextures( “CloseNormal.png” , “CloseSelected.png” , “”); exit_button->setPosition( ccp (m_pUILayer->getContentSize().width - exit_button->getSize().width, exit_button->getSize().height)); exit_button->addTouchEventListener( this , toucheventselector (CocosGUIExamplesPageScene ::menuCloseCallback)); m_pUILayer->addWidget(exit_button);}
//退出时清理各种资源void CocosGUIExamplesPageScene ::onExit(){ m_pUILayer->removeFromParent(); SceneReader::sharedSceneReader()->purge(); GUIReader::shareReader()->purge(); cocos2d::extension:: ActionManager ::shareManager()->purge(); CCScene::onExit();}
//响应退出按钮void CocosGUIExamplesPageScene ::menuCloseCallback( CCObject* pSender , TouchEventType type){ if ( type == TOUCH_EVENT_ENDED ) { CCDirector ::sharedDirector()->end(); #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS) exit(0);#endif }}
void CocosGUIExamplesPageScene ::PageInit(){ //加载UI资源 Layout* page_root = dynamic_cast <Layout >( GUIReader::shareReader()->widgetFromJsonFile( “cocosgui/gui_examples/page_1/page_1.json” )); m_pUILayer->addWidget(page_root); //获取page_panel对象 Layout page_layout = dynamic_cast <Layout >(page_root->getChildByName( “page_panel”)); //创建一个PageView对象 PageView pageView = PageView ::create(); pageView->setTouchEnabled( true );//启用触摸 pageView->setSize(page_layout->getSize()); //添加4个page for ( int i = 0; i < 4; ++i) { Layout * layout = Layout ::create(); layout->setSize(pageView->getSize()); ImageView * imageView = ImageView ::create(); //在每个page下添加一张图片. imageView->setTouchEnabled( true ); imageView->loadTexture(page_image_textures*);* imageView->setPosition( ccp (layout->getSize().width / 2, layout->getSize().height / 2)); layout->addChild(imageView); pageView->addPage(layout); } //绑定页面切换事件监听 pageView->addEventListenerPageView( this , pagevieweventselector ( CocosGUIExamplesPageScene::pageViewEvent)); page_layout->addChild(pageView);}
//页面切换监听事件void CocosGUIExamplesPageScene ::pageViewEvent( CCObject * pSender , PageViewEventType type){ PageView* pageView = dynamic_cast <PageView >( pSender); int page = pageView->getCurPageIndex() + 1; //获取当前页数 Layout page_root = dynamic_cast <Layout >(m_pUILayer->getWidgetByName( “page_root”)); //获取UI的根节点. gui:: Label page_alert_label = dynamic_cast <gui::Label >( UIHelper::seekWidgetByName(page_root, “page_alert_label” )); //获取标题栏的标题 page_alert_label->setText( CCString ::createWithFormat(“page %d” , page)->getCString()); //设置标题
//设置下面换页指示器 Layout
page_alert_bottom_layout = dynamic_cast <Layout *>( UIHelper::seekWidgetByName(page_root, “page_alert_bottom_panel” )); int count = page_alert_bottom_layout->getChildren()->count(); for ( int i = count / 2; i < count; ++i) { UIWidget * child = dynamic_cast <UIWidget >(page_alert_bottom_layout->getChildren()->objectAtIndex(i)); child->setVisible( false );//隐藏所有指示器 } ImageView page_imageview = dynamic_cast <ImageView *>( UIHelper::seekWidgetByName(page_root, CCString ::createWithFormat(“page_%d_imageview” , page)->getCString())); page_imageview->setVisible( true );//只显示当前指示器}
然后我们在AppDelegate.cpp中, 添加引用.

#include “CocosGUIExamplesPageScene.h”

修改AppDelegate::applicationDidFinishLaunching函数, 使用CocosGUIExamplesPageScene启动.

 CocosGUIExamplesPageScene *pScene = new CocosGUIExamplesPageScene ();    pScene->autorelease();
// run    pDirector->runWithScene(pScene);

好啦, 快运行下吧!

1、pageViewEvent( CCObject * pSender , PageViewEventType type)
不用对 type 类型进行检测吗?应该是翻页结束后再执行里面的内容吧。

2、
for ( int i = count / 2; i < count; ++i)
{
UIWidget * child = dynamic_cast <UIWidget *>(page_alert_bottom_layout->getChildren()->objectAtIndex(i));
child->setVisible( false );//隐藏所有指示器
}

这个循环为什么是从count / 2 开始的呀?不是说要“隐藏所有指示器”吗?

— Begin quote from ____

引用第1楼icepower于2014-03-11 09:42发表的 :
1、pageViewEvent( CCObject * pSender , PageViewEventType type)
不用对 type 类型进行检测吗?应该是翻页结束后再执行里面的内容吧。

2、
http://www.cocoachina.com/bbs/job.php?action=topost&tid=192658&pid=901035

— End quote

您很细心哈. 给您+32个赞.

您提出的问题的答案, 分别如下.

typedef enum
{
PAGEVIEW_EVENT_TURNING,
}PageViewEventType;

这个是PageViewEventType的定义, 只有一个.
确实是如果判断下类型代码会更严谨一些.

注意看下page_alert_bottom_panel下面总共有8个元素.
page_1_bg_imageview
page_2_bg_imageview
page_3_bg_imageview
page_4_bg_imageview
page_1_imageview
page_2_imageview
page_3_imageview
page_4_imageview
其中背景是始终显示的. 所以这里隐藏的是后面4个红色的指示器. 并不隐藏其背景.
所以循环的i是从count/2 (即8/2=4, 从4)开始.

我在lua中调用json文件 提示找不到TouchGroup这个类 需要引入什么文件吗 o6HK(yc.
local _uiLayer = TouchGroup:create() n`6nJRm7
local _widget = GUIReader:shareReader():widgetFromJsonFile(“NewProject_1.json”) *+<_IaH
_uiLayer:addWidget(_widget) Z;a?:p:x2v
提示找不到TouchGroup类型,是不是需要定义或者引入头文件部分呢???

你看下是否有UILayer这个类?

我这边对Lua不太熟悉.

TouchGroup似乎是新版本引入的. 较早版本可能没有.

Label *alert_label= (Label *)Helper::seekWidgetByName(page_root, “alert_label”);
alert_label->setString(__String::createWithFormat(“page:%d”,page)->getCString());
之后label就不显示了 为什么?

这个教程写得不详细,
对初学者没有多大帮助。

我想问一下,这个里面的滑动的图片是在cocostudio里实现的还是在代码中实现的

里面的滑动的图片是在cocostudio里实现的还是在代码中实现的

我用CocoStudio的版本是1.2.0.1 打不开page.xml.ui工程

在Cocostudio中即可实现。

你好,这个工程由于用1.3.0.0打开过,所以无法回退到1.2.0.1

还在做这个滚动页面,可以在单个页面放多个控件吗?如二张图片和按钮?

描述不太清晰,不适合初学者

这个效果可以在cocos studio的模拟器上实际进行操作码?

这个例子好像不是在cocostudio中实现的,cocostudio中只是添加了一个层容器,然后在代码中加入了一个继承自UIScrollInterface的PageView,再在上面添加一个层,在层上放图片。:12:

m_pUILayer->scheduleUpdate();
这句在这里是不是没什么用?

非常好,学习了:14:

类型已有一个ccui.PageViewEventType.turning 我怎么判断是向左移动还是向右移动,有时候需要动态加载的时候特别麻烦!这个谁做过吗

感谢楼主分享。
对于下栏 page 的指示器,我用了不同方法,感觉更简洁。只需要添加两个成员变量
int currentPage; // 当前指示页
int lastPage; // 前个指示页

cocostudio 里把那4个页面的image_view 标好tag(逻辑标签)
自己学习写的代码,和楼主树状结构和楼主有点不同,道理大家能看明白就行!

// 设置下面换页指示器
currentPage = page;
Node* bottom_layout = root->getChildByName("bottom_panel");
bottom_layout->getChildByTag(lastPage)->setVisible(false);
bottom_layout->getChildByTag(currentPage)->setVisible(true);
lastPage = currentPage;