接上一节内容: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. Python 进程与线程小随笔

    Process 涉及模块:multiprocessing Process p = Process() p.start() p.join() from multiprocessing import Pr ...

  2. oop学习 计算器类的规划

    类的学习 题目要求 采取面向对象的方法,四则运算自动出题软件,根据需求可以划分为几个类?每个类具有什么属性?每个类具有什么行为? 类与类之间是如何进行协作的?谁给谁发送消息?谁持有谁的引用? 该自动出 ...

  3. 【集美大学1411_助教博客】个人作业3——个人总结(Alpha阶段) 成绩

    写在前面的话 大家都在总结中说自己学到了很多,那大家都学到了什么呢?如果你不写出来,你真的知道自己学到了什么吗?在自我总结阶段一般写得比较具体的同学,我都给了高分,比如出现了什么具体问题,我们是使用了 ...

  4. 201521123106《java程序设计》第一周学习总结

    1.本章学习总结 认识了java语言,了解了java的历史,学习了各种java相关文件的使用,能够进行基本的程序操作,学会了使用博客.码云. 2.书面作业 1.为什么java程序可以跨平台运行?执行j ...

  5. 12个Sublime Text应用技巧和诀窍

    本文为您提供Sublime Text编辑器的12个技巧和诀窍,深入挖掘这个看似简洁的代码编辑器,背后所隐藏的实现各种高级功能的无限可能. 1) 选择 以下是一些Sublime Text选择文本的快捷键 ...

  6. 201521123056 《Java程序设计》第11周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多线程相关内容. 2. 书面作业 本次PTA作业题集多线程 1. 互斥访问与同步访问 完成题集4-4(互斥访问)与4-5(同步访问) ...

  7. 201521123003《Java程序设计》第11周学习总结

    1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多线程相关内容. 2. 书面作业 本次PTA作业题集多线程 1.互斥访问与同步访问 完成题集4-4(互斥访问)与4-5(同步访问) ...

  8. 编程从入门到提高,然后放弃再跑路(Java)

    1.Java入门篇 1.1 基础入门和面向对象 1.1.1 编程基础 [01] Java语言的基本认识 [02] 类和对象 [03] 类的结构和创建对象 [04] 包和访问权限修饰符 [05] 利用p ...

  9. Exception in thread "main" org.hibernate.MappingException: You may only specify a cache for root

    如果出现类似下面的错误: Exception in thread "main" org.hibernate.MappingException: You may only speci ...

  10. hadoop2.0的数据副本存放策略

    在hadoop2.0中,datanode数据副本存放磁盘选择策略有两种方式: 第一种是沿用hadoop1.0的磁盘目录轮询方式,实现类:RoundRobinVolumeChoosingPolicy.j ...