接上一节内容:cocos2dx - shader实现任意动画的残影效果

本节主要讲一下扩展PageView控件功能

  在实际游戏应用中,经常会碰到用原来的控件难以实现的功能。这时候就需要根据需求,通过选择合适的控件进行方便的扩展来实现。

扩展控件一般是通过对原来的控件进行继承来实现,这样可以很好的应用原来的属性及方法,同时可以方便的添加自己需要的方法及属性。

例子:实现对pageview进行循环翻页效果。

分析:

  1、翻页方法有2个方式,滑动翻页及点击按钮左右翻动。

  2、在触发翻页后需要移动页面位置保持当前新的选中页面在中间。

  3、每次翻页后需要触发事件,实现更新内容。

实现:

1、为了优化显示,我们不在一开始创建所有页面,仅创建3个layout来存储显示的内容,然后在翻页触发后刷新页面内容。

    Layout* m_pLeftLayout;
Layout* m_pRightLayout;
Layout* m_pCurLayout;

2、同时重写覆盖以下几个方法,来实现移动页面的判断。

    void scrollToPage(ssize_t idx) ; 

    virtual bool scrollPages(Vec2 touchOffset) override;

    virtual void handleMoveLogic(Touch *touch) override;

    virtual void handleReleaseLogic(Touch *touch) override;

    void movePages(Vec2 offset);

主要是通过判断移动的方向,来判断需要更新的下一个页面。然后在移动了一定比例的页面距离后(0.75),将下一个页面设为当前界面,重设对应左右界面。
代码如下:

void CCyclePageView::movePages(Vec2 offset)
{
if (!m_pCurLayout || !m_pRightLayout || !m_pLeftLayout)
{
return;
}
m_pCurLayout->setPosition(m_pCurLayout->getPosition() + offset);
m_pRightLayout->setPosition(m_pRightLayout->getPosition() + offset);
m_pLeftLayout->setPosition(m_pLeftLayout->getPosition() + offset);
Size size = getContentSize();
switch (_touchMoveDirection)
{
case TouchDirection::LEFT: // left
if (m_pCurLayout->getPositionX()<-size.width*0.75)
{ Layout* newRight = m_pLeftLayout;
newRight->setPositionX(m_pRightLayout->getPositionX() + size.width);
m_pLeftLayout = m_pCurLayout;
m_pCurLayout = m_pRightLayout;
m_pRightLayout = newRight; ++_curPageIdx;
UpdateShowLayout(_curPageIdx, m_pCurLayout,true);
} break;
case TouchDirection::RIGHT: // right
if (m_pCurLayout->getPositionX()>size.width*0.75)
{
Layout* newLeft = m_pRightLayout;
newLeft->setPositionX(m_pLeftLayout->getPositionX() - size.width);
m_pRightLayout = m_pCurLayout;
m_pCurLayout = m_pLeftLayout;
m_pLeftLayout = newLeft; --_curPageIdx;
UpdateShowLayout(_curPageIdx, m_pCurLayout, true);
}
break;
case TouchDirection::UP:
if (m_pCurLayout->getPositionY()>size.width*0.75)
{
Layout* newLeft = m_pRightLayout;
newLeft->setPositionX(m_pLeftLayout->getPositionX() - size.height);
m_pRightLayout = m_pCurLayout;
m_pCurLayout = m_pLeftLayout;
m_pLeftLayout = newLeft;
--_curPageIdx;
UpdateShowLayout(_curPageIdx, m_pCurLayout, true);
}
break;
case TouchDirection::DOWN:
if (m_pCurLayout->getPositionY()<-size.height*0.75)
{
Layout* newRight = m_pLeftLayout;
newRight->setPositionX(m_pRightLayout->getPositionX() + size.height);
m_pLeftLayout = m_pCurLayout;
m_pCurLayout = m_pRightLayout;
m_pRightLayout = newRight;
++_curPageIdx;
UpdateShowLayout(_curPageIdx, m_pCurLayout, true);
}
break;
default:
break;
}
if (_curPageIdx<)
{
_curPageIdx = m_nPageSize-;
}
if (_curPageIdx >= m_nPageSize)
{
_curPageIdx = ;
}
}

3、通过以下几个方法实现更新界面显示

    Layout* GetCurPage(){ return m_pCurLayout;}

    void addPageChangedListener(const std::function<void(Layout*, size_t)> callback){ m_callback = callback; }

    void UpdateShowLayout(ssizs_t nCurIdx, Layout* layout, bool isForceCallBack=false);

在UpdateshowLayout中将传入待更新的页面更新内容为nCurIdx的内容,这里通过Tag标识来判断。若Tag与待显示的Idx不一致则通过addPageChangedListener中设置的回调来实现更新。

void CCyclePageView::UpdateShowLayout(ssize_t nCurIdx, Layout* layout,bool isForceCallBack)
{
if (nCurIdx<)
{
nCurIdx = m_nPageSize - ;
}
if (nCurIdx >= m_nPageSize)
{
nCurIdx = ;
}
if (layout && (isForceCallBack || layout->getTag() != nCurIdx))
{
layout->setTag(nCurIdx);
if (m_callback)
{
m_callback(layout,nCurIdx);
}
}
}

这里的 isForceCallBack 用来在void movePages(Vec2 offset)中实现最后更新的一个页面为当前选中的页面。

使用:

1、在创建后,通过SetPageSize设置循环页面个数,并通过addPageChangedListener中添加页面变化监听。

2、翻页使用scrollToPage()翻到指定页面,或者直接通过拖动控件活动实现。

3、在监听中必须添加更新显示效果。

            CCyclePageView* pNewPageView = CCyclePageView::create();
pNewPageView->addPageChangedListener(std::bind(&CMainWnd::onPageViewUpdate, this, std::placeholders::_1, std::placeholders::_2));
pNewPageView->setDirection(cocos2d::ui::PageView::Direction::HORIZONTAL);
pNewPageView->SetPageSize(nCount);
pNewPageView->scrollToPage(0);

完整代码地址:https://github.com/mydishes/cocos2dx-Ex/tree/master/CyclePageView

cocos2dx - 控件扩展之pageview循环显示的更多相关文章

  1. WinForm控件TreeView 只部分节点显示 CheckBox

    WinForm控件TreeView 只部分节点显示  CheckBox 用过asp.net的应该知道,要在treeview中实现上述功能可以使用ShowCheckBox 属性指定那些节点显示check ...

  2. Scroll View 控件以Thumbnail的方式显示一个目录的全部图片,相似图片浏览器

    MAC : XCode -> Scroll View 控件以Thumbnail的方式显示一个目录的全部图片,类似图片浏览器 STEP1:将两个目录复制到project里面ImageBrowser ...

  3. 给easyui datebox时间框控件扩展一个清空的实例

    给easyui datebox扩展一个清空的实例 步骤一:拓展插件 /** * 给时间框控件扩展一个清除的按钮 */ $.fn.datebox.defaults.cleanText = '清空'; ( ...

  4. WPF开源控件扩展库 - MaterialDesignExtensions

    Material Design Extensions 在WPF开源控件库 Material Design in XAML Toolkit(本站介绍:链接)的基础上进行了控件扩展和特性新增.本开源项目中 ...

  5. ASP.NET MVC显示UserControl控件(扩展篇)

    昨晚Insus.NET有怀旧一下<念念不忘,ASP.NET MVC显示WebForm网页或UserControl控件>http://www.cnblogs.com/insus/p/3641 ...

  6. Silverlight中DataPager控件扩展

    大家一定遇到这样的情况,想改变一下SL的DataPager的显示信息,比如希望分页控件上显示数据的总数.那么就需要扩展一下DataPager控件即可. 其实扩展DataPager很简单,只要获取到Da ...

  7. android控件RecyclerView中,如何显示自定义分割线以及最后一项去除分割线

    在控件RecyclerView中,分割线DividerItemDecoration类的使用经常见,如果是使用自带的分割线,只需要这样写即可 RecyclerView mRecyclerView; mR ...

  8. Winform下让你的DataGridView控件支持点语法(即显示list中的子对象属性)

    前言: 不想看前言的直接去看正文吧!另外文末有彩蛋. DataGridView可以支持多种数据源格式,比如DataTable和List. DataTable没啥特殊的,本身就是一张二维的表,可以和Da ...

  9. 玩转控件:扩展Dev中SimpleButton

    何为扩展,顾名思义,就是在原有控件属性.事件的基础上拓展自己需要或实用的属性.事件等等.或者可以理解为,现有的控件已经不能完全满足我(的需求)了.好的扩展会使控件更加完善,实用,好用.不好的扩展,说白 ...

随机推荐

  1. 详解 mpls vpn 的实现

    MPLS VPN的实现 一.实验目的 该实验通过MPLS VPN的数据配置,使学生掌握路由器相关接口的IP地址设置.路由协议的配置以及MPLS VPN的完整的创建过程, 从而加深对IP网络的IP编址. ...

  2. 团队作业4——第一次项目冲刺(Alpha版本)第一天+第二天+第三天+第四天+第五天+第六天+第七天

    冲刺第一天 一.Daily Scrum Meeting照片 二.每个人的工作 1.今天计划完成的任务 GUI.计时功能.题目生成 2.工作中遇到的困难 刚开始在计时功能模块只能做到秒位,经过查询资料后 ...

  3. 团队作业4——第一次项目冲刺(Alpha版本)2st day

    一.Daily Scrum Meeting照片 二.燃尽图 三.项目进展 界面 1.四个用户登录界面已经完成. 2.界面内的功能完成了一小部分. 登陆部分 1.QQ授权已经申请,还未通过. 2.通过好 ...

  4. java中覆盖必须满足的约束

    子类方法的名称,参数何返回类型必须与父类一致. 子类方法不能缩小父类方法的访问权限 子类方法不能抛出比父类方法更多的异常 方法覆盖只存在于子类和父类,同一个类中方法只能被重载 父类的静态方法不能被子类 ...

  5. 201521123045 《JAVA程序设计》第1周学习总结 1

    1. 本周学习总结 学习了入门的java知识,知道了jdk.eclipse等基础软件,了解了如何编译最基础的java程序.知道了java的基本原理以及java的几种数据类型.掌握使用简单编译器编写ja ...

  6. 201521123008 《Java程序设计》 第九周学习总结

    1. 本周学习总结 2. 书面作业 本次PTA作业题集异常 1.常用异常 题目5-1 1.1 截图你的提交结果(出现学号) 1.2 自己以前编写的代码中经常出现什么异常.需要捕获吗(为什么)?应如何避 ...

  7. headfirst设计模式(3)—装饰者模式

    序 好久没写设计模式了,自从写了两篇之后,就放弃治疗了,主要还是工作太忙了啊(借口,都是借口),过完年以后一直填坑,填了好几个月,总算是稳定下来了,可以打打酱油了. 为什么又重新开始写设计模式呢?学习 ...

  8. log4j的基本使用和参数设定

    1.简介 apache的一个开放源代码项目. 精确控制日志的输出,包括输出的格式,输出的目的地,输出的过滤(不同级别日志的输出)等. 配置简单,不需要在代码中配置环境,支持两种配置文件格式,XML和J ...

  9. java基础知识3--如何获取资源文件(Java中获取资源文件的url)

    java开发中,常见的resource文件有:.xml,.properties,.txt文件等,后台开发中经常用到读取资源文件,处理业务逻辑,然后返回结果. 获取资源文件的方法说明getResourc ...

  10. js对象详解(JavaScript对象深度剖析,深度理解js对象)

    js对象详解(JavaScript对象深度剖析,深度理解js对象) 这算是酝酿很久的一篇文章了. JavaScript作为一个基于对象(没有类的概念)的语言,从入门到精通到放弃一直会被对象这个问题围绕 ...