版本:3.4.0

语言:TypeScript

环境: Mac

参考:

简介


ScrollView组件作为滚动容器来使用,它的实现通过ScrollBar组件来展示内容的位置和Mask组件显示指定区域,来保证有限的区域内显示更多的内容。

在cocosCreator中,滚动容器的实现主要是:ScrollView组件。层级管理器的节点如下:

构成主要有两部分:

  • scrollBar 滚动条相关,用于展示内容的位置,编译器默认垂直
  • view 内容显示相关,节点内增加了Mask遮罩显示指定区域,通过content增加item显示滚动区域

ScrollView节点属性:

属性 功能说明
Horizontal 布尔值,是否允许横向滚动
HorizontalScrollBar 节点引用,用来创建一个滚动条来显示 content 在水平方向上的位置
Vertical 布尔值,是否允许纵向滚动
VerticalScrollBar 节点引用,用来创建一个滚动条来显示 content 在垂直方向上的位置
Inertia 滚动的时候是否有加速度
Brake 滚动之后的减速系数,范围[0, 1]。 1 时立马停止滚动, 0时则会一直滚动到 content 的边界
Elastic 布尔值,是否回弹
BounceDuration 回弹所需要的时间,范围[0, 10]
Content 节点引用,所有的子节点放到此处,必须存在,否则滚动容器无法实现
ScrollEvents 可用于添加一个Target、Component、handler、 CutomEventData的回调事件
CancelInnerEvents 滚动行为是否会取消子节点上注册的触摸事件,默认为 true

在cocosCreator中, 滚动容器的使用主要就是:ScrollViewPageView

#mermaid-svg-vZGo9TrgWGdGPpNq {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-vZGo9TrgWGdGPpNq .error-icon{fill:#552222;}#mermaid-svg-vZGo9TrgWGdGPpNq .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-vZGo9TrgWGdGPpNq .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-vZGo9TrgWGdGPpNq .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-vZGo9TrgWGdGPpNq .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-vZGo9TrgWGdGPpNq .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-vZGo9TrgWGdGPpNq .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-vZGo9TrgWGdGPpNq .marker{fill:#333333;stroke:#333333;}#mermaid-svg-vZGo9TrgWGdGPpNq .marker.cross{stroke:#333333;}#mermaid-svg-vZGo9TrgWGdGPpNq svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-vZGo9TrgWGdGPpNq .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-vZGo9TrgWGdGPpNq .cluster-label text{fill:#333;}#mermaid-svg-vZGo9TrgWGdGPpNq .cluster-label span{color:#333;}#mermaid-svg-vZGo9TrgWGdGPpNq .label text,#mermaid-svg-vZGo9TrgWGdGPpNq span{fill:#333;color:#333;}#mermaid-svg-vZGo9TrgWGdGPpNq .node rect,#mermaid-svg-vZGo9TrgWGdGPpNq .node circle,#mermaid-svg-vZGo9TrgWGdGPpNq .node ellipse,#mermaid-svg-vZGo9TrgWGdGPpNq .node polygon,#mermaid-svg-vZGo9TrgWGdGPpNq .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-vZGo9TrgWGdGPpNq .node .label{text-align:center;}#mermaid-svg-vZGo9TrgWGdGPpNq .node.clickable{cursor:pointer;}#mermaid-svg-vZGo9TrgWGdGPpNq .arrowheadPath{fill:#333333;}#mermaid-svg-vZGo9TrgWGdGPpNq .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-vZGo9TrgWGdGPpNq .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-vZGo9TrgWGdGPpNq .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-vZGo9TrgWGdGPpNq .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-vZGo9TrgWGdGPpNq .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-vZGo9TrgWGdGPpNq .cluster text{fill:#333;}#mermaid-svg-vZGo9TrgWGdGPpNq .cluster span{color:#333;}#mermaid-svg-vZGo9TrgWGdGPpNq div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-vZGo9TrgWGdGPpNq :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}

滚动条
滚动视图
页面视图
ViewGroup
Component
ScrollBar
ScrollView
PageView

没有像cocos2d-x所谓的ListViewTableView 的实现,因此很多项目会对ScrollView进行二次封装,用于实现类似于TableView的功能,降低内存占用。

基本使用


使用ScrollView,需要注意:

  • scrollBar节点可选,可以通过Horizontal/HorizontalScrollBarVertical/VerticalScrollBar设置水平或垂直滚动条相关,如果不需要,可以去掉勾选或者直接删除节点
  • ScrollView节点内可以增加widget组件,用于排版使用
  • content节点内可增加Layout组件,用于设置水平,垂直,格子布局等,但注意: 不要同时使用Layout和Widget组件,以免产生不可预料的后果

针对于content下的布局组件Layout的设置,如下图:

注意设置:

  • Type 设置水平,垂直,格子布局类型
  • ResizeMode 一般设置为CONTAINER模式,它会自动计算布局的大小,用于滚动使用
  • SpacingX/SpacingY 设置item之间的间隔

设置结束后,在脚本中我们可编写如下代码完成ScrollView的基本使用:

@ccclass('UI_DemoLayer')
export class UI_DemoLayer extends Component {// 获取ScrollView组件@property(ScrollView) scroll: ScrollView = null;// 获取预制体item@property(Prefab) itemPrefab: Prefab = null;protected onLoad(): void {// 移除content下的子节点this.scroll.content.removeAllChildren();for (let i = 0; i < 10; ++i) {// 克隆并将节点添加到content中let itemNode = instantiate(this.itemPrefab);if (itemNode) {itemNode.parent = this.scroll.content;// 更新指定的itemlet itemScript = itemNode.getComponent(ScrollItem);itemScript.updateItem(i);}}}
}

在构建item前,建议调用content.removeAllChildren()接口,用于移除无效节点。

拓展

使用滚动容器,尤其在content节点内增加 Layout组件 可以很方便的设置滚动的各种类型。

下面的示例是通过脚本代码动态设置滚动视图的各种布局类型,示意图如下:

关于Toggle的使用,可参考博客: Toggle和ToggleContainer的使用。具体的实现代码:

// 布局类型
enum kLayoutType {HORIZONTAL = 0,        // 水平布局VERTICAL,              // 垂直布局GRID,                  // 格子布局
};/*
1. 预制体的大小会随着布局类型的改变而改变,主要用于Demo的实现
2. 为方便预览,水平或垂直布局item数量10个,格子布局为30个
*/
@ccclass('UI_ScrollEffecNormaltLayer')
export class UI_ScrollEffecNormaltLayer extends Component {// 滚动容器@property(ScrollView) scroll: ScrollView = null; // 预制体@property(Prefab) itemPrefab: Prefab = null; // 布局类型private _layoutType: kLayoutType = kLayoutType.HORIZONTAL;// 可视图大小private _scrollSize = null;protected start(): void {this._scrollSize = this.scroll.getComponent(UITransform).contentSize;this.refreshScroll();}// 更新scrollprivate refreshScroll() {let itemCount = 10;const content = this.scroll.content;const contentLayout = content.getComponent(Layout);const contentTransform = content.getComponent(UITransform);// 设置滚动if (this._layoutType === kLayoutType.VERTICAL) {this.scroll.horizontal = true;this.scroll.vertical = false;}else {this.scroll.horizontal = false;this.scroll.vertical = true;}// 设置布局相关if (this._layoutType === kLayoutType.VERTICAL) {contentLayout.horizontalDirection = Layout.HorizontalDirection.LEFT_TO_RIGHT;contentLayout.type = Layout.Type.HORIZONTAL;// 垂直布局固定可视区域的高度contentTransform.height = this._scrollSize.height;contentLayout.spacingX = 10;contentLayout.spacingY = 0;}else if (this._layoutType === kLayoutType.HORIZONTAL) {contentLayout.verticalDirection = Layout.VerticalDirection.TOP_TO_BOTTOM;contentLayout.type = Layout.Type.VERTICAL;// 水平布局固定可视区域的宽度contentTransform.width = this._scrollSize.width;contentLayout.spacingX = 0;contentLayout.spacingY = 10;}else if (this._layoutType === kLayoutType.GRID) {// 设置子节点排列方向contentLayout.verticalDirection = Layout.VerticalDirection.TOP_TO_BOTTOM;contentLayout.horizontalDirection = Layout.HorizontalDirection.LEFT_TO_RIGHT;// 设置布局类型contentLayout.type = Layout.Type.GRID;// 设置子节点间隔contentLayout.spacingX = 10;contentLayout.spacingY = 10;// 设置布局约束contentLayout.constraint = Layout.Constraint.FIXED_COL;// 设置布局约束的限定值contentLayout.constraintNum = 5;// 格子固定可视区域的宽度contentTransform.width = this._scrollSize.width;// 设置子节点数量itemCount = 30;}// 填充scrollcontent.removeAllChildren();for (let i = 0; i < itemCount; ++i) {let itemNode = instantiate(this.itemPrefab);this.refreshItem(i, itemNode);itemNode.parent = content;}// 更新布局contentLayout.updateLayout();}// 更新itemprivate refreshItem(index: number, itemNode: Node) {// 不同的布局item的大小会进行改变,用于演示const transform = itemNode.getComponent(UITransform);if (this._layoutType === kLayoutType.VERTICAL) {transform.setContentSize(60, this._scrollSize.height);}else if (this._layoutType === kLayoutType.HORIZONTAL) {transform.setContentSize(this._scrollSize.width, 60);}else if (this._layoutType === kLayoutType.GRID) {transform.setContentSize(70, 70);}// titleconst label = itemNode.getChildByName("title").getComponent(Label);label.string = index.toString();}
}

这个示例一般不会发生在实际的项目开发中,但对于理解ScrollView代码很有帮助!

回调事件


ScrollView滚动视图的事件回调函数主要在scrollEvents中,它的事件类型主要有:

export enum cocos_ui_scroll_view_EventType {// 滚动视图滚动到顶部边界事件SCROLL_TO_TOP = "scroll-to-top",// 滚动视图滚动到底部边界事件SCROLL_TO_BOTTOM = "scroll-to-bottom",// 滚动视图滚动到左边界事件SCROLL_TO_LEFT = "scroll-to-left",// 滚动视图滚动到右边界事件SCROLL_TO_RIGHT = "scroll-to-right",// 滚动视图滚动开始时发出的事件SCROLL_BEGAN = "scroll-began",// 滚动视图滚动结束的时候发出的事件SCROLL_ENDED = "scroll-ended",// 滚动视图滚动到顶部边界并且开始回弹时发出的事件BOUNCE_TOP = "bounce-top",// 滚动视图滚动到底部边界并且开始回弹时发出的事件BOUNCE_BOTTOM = "bounce-bottom",// 滚动视图滚动到左边界并且开始回弹时发出的事件BOUNCE_LEFT = "bounce-left",// 滚动视图滚动到右边界并且开始回弹时发出的事件BOUNCE_RIGHT = "bounce-right",// 滚动视图正在滚动时发出的事件SCROLLING = "scrolling",// 滚动视图自动滚动快要结束的时候发出的事件SCROLL_ENG_WITH_THRESHOLD = "scroll-ended-with-threshold",// 当用户松手的时候会发出一个事件TOUCH_UP = "touch-up"
}

事件的回调主要有三种:

  1. 通过编译器的ScrollEvents设定
  2. 通过脚本代码的scrollview.node.on 设定
  3. 通过脚本代码定义EventHandler对象设定

这里,我们使用第二种方式编写示例:

protected onEnable(): void {this.scroll.node.on(ScrollView.EventType.SCROLLING, this.scrolling, this);
}protected onDisable(): void {this.scroll.node.off(ScrollView.EventType.SCROLLING, this.scrolling, this);
}// 此种方式的回调,参数只会有一个为ScrollView组件
private scrolling(scrollView: ScrollView) {console.log("------ ScrollView 滚动中")}

注意:使用编译器设定ScrollEvents或创建EventHandler对象,支持参数为三个

public scrollEvent(scroll: ScrollView, eventType: any, customData: any) {// 返回三个参数,分别对应ScrollView组件,事件类型,自定义数据
}

视图滚动


在项目的开发中,针对于某些功能我们可能需要将视图滚动到指定的位置。

官方为此提供了一些接口用于这些功能的实现,主要有:

/*
@func: 视图内容将在指定时间滚动到底部、顶部、左侧、右侧、左上、右上、左下、右下
@param: timeInSecond 滚动时间,以秒为单位。如果超时,则立即跳到指定边界
@param: attenuated 滚动速度是否衰减,默认为true
*/
scrollToBottom(timeInSecond?: number, attenuated?: boolean): void;
scrollToTop(timeInSecond?: number, attenuated?: boolean): void;
scrollToLeft(timeInSecond?: number, attenuated?: boolean): void;
scrollToRight(timeInSecond?: number, attenuated?: boolean): void;
scrollToTopLeft(timeInSecond?: number, attenuated?: boolean): void;
scrollToTopRight(timeInSecond?: number, attenuated?: boolean): void;
scrollToBottomLeft(timeInSecond?: number, attenuated?: boolean): void;
scrollToBottomRight(timeInSecond?: number, attenuated?: boolean): void;// 视图滚动到指定的偏移位置
scrollToOffset(offset: math.Vec2, timeInSecond?: number, attenuated?: boolean): void;
// 获取当前滚动偏移量
getScrollOffset(): math.Vec2;
// 获取最大可滚动偏移量
getMaxScrollOffset(): math.Vec2;// 视图是否滚动指定的百分比位置
scrollTo(anchor: math.Vec2, timeInSecond?: number, attenuated?: boolean): void;
scrollToPercentVertical(percent: number, timeInSecond?: number, attenuated?: boolean): void;
scrollToPercentHorizontal(percent: number, timeInSecond: number, attenuated: boolean): void;
// 是否滚动中
isAutoScrolling(): boolean;
// 停止滚动
stopAutoScroll(): void;

简单的示例:

/*
@func: 视图滚动到底部, 如果在滚动中则停止
@param: duration 持续时间,以秒为单位
@param isAttenuate 滚动速度是否衰减
*/
private scrllToBottom(duration: number, isAttenuate:boolean) {// 检测视图是否滚动中if (this.scroll.isAutoScrolling()) {// 如果视图滚动中,则停止滚动this.scroll.stopAutoScroll();return;}this.scroll.scrollToBottom(duration, isAttenuate);
}/*
@func: 视图滚动到指定的索引位置
@param: 目标索引
@notice: 假设可视区域item最大显示三个,如果索引<3则停止滚动
*/
private scrollToIndex(targetIndex: number) {if (targetIndex < 3) {return;}// 获取content大小let contentSize = this.scroll.content.getComponent(UITransform).contentSize;console.log("contentSize:", contentSize.height);// 获取布局垂直间隔let layout = this.scroll.content.getComponent(Layout);let spaceY = layout.spacingY;// 获取item大小let itemNode = this.scroll.content.children[0];let itemSize = itemNode.getComponent(UITransform).contentSize;// 获取滚动偏移量并进行设置const curOffset = this.scroll.getScrollOffset();const offsetY = targetIndex * (itemSize.height + spaceY);this.scroll.scrollToOffset(new Vec3(0, offsetY, 0));
}

最后祝大家学习生活愉快!

cocosCreator 之 ScrollView的基本使用相关推荐

  1. CocosCreator无尽循环列表,长列表优化drawcall,scrollview列表优化

    我这里只实现纵向滑动列表,横向的话直接修改一下就好 cocos creator 2.4.4 参考链接 CocosCreator无尽循环列表,ScrollView优化_zakerhero的博客-CSDN ...

  2. unity3d 动态合批设置_【CocosCreator】突破动态合图

    1. 动态合图的默认规则 引擎中对动态合图的描述如下: 它能在项目运行时动态的将贴图合并到一张大贴图中.当渲染一张贴图的时候,动态合图系统会自动检测这张贴图是否已经被合并到了图集(图片集合)中,如果没 ...

  3. CocosCreator | 微信小游戏排行榜 微信开放域

    更多笔记和源码请关注:[微信公众号] CocosCreator笔记 演示 技术摘要 主域工程 微信授权 创建子域节点 向子域发送消息 子域工程 读写用户云托管数据 接收主域发送的消息 构建运行 实现 ...

  4. CocosCreator重复滚动列表

    重复滚动列表的核心策略就是循环使用缓存池中的节点,在滚动列表滑动时刷新子节点位置和内容,避免单次新建太多节点导致的问题. 使用scrolling监听滚动列表. this.scrollView.node ...

  5. HarmonyOS ScrollView 使用

    ScrollView 介绍 ScrollView是一种带滚动功能的组件,它采用滑动的方式在有限的区域内显示更多的内容. 本来很简单的不打算记录,但是各种坑啊,哎.现在学习大致了解就行, ScrollV ...

  6. HarmonyOS ScrollView 不滑动的问题

    HarmonyOS ScrollView 本来就是看看文档,然后想着写一下看看, 结果泪崩了,弄了2个小时啊,阿西吧, 就是不滑动,最后睡觉前把宽高的属性设置了以下 就好了 不滑动的原因就是 把加载字 ...

  7. Android ScrollView 滑动指定的距离

    使用到的方法为:scrollTo(x,y) 里面的x和y轴 scrollView = findViewById(R.id.scrollview);findViewById(R.id.btn).setO ...

  8. 微信小程序scroll-view的使用

    这边博客主要是对微信小程序文档的的使用心得 官网地址 demo效果 一些属性 scroll-top 和属性,设置竖向滚动条的位置,就是第一次进来的时候,还没有滑动的时候view的位置 假如不设置默认在 ...

  9. ScrollView can host only one direct child 问题处理

    出现这个的原因是由于ScrollView内部同时出现2个不并列的布局 ScrollView内部只能有一个子元素,即不能有并列的布局 如果想要多个并列的布局,可以把并列的布局放到ScrollView的一 ...

  10. iOS-禁止scrollview垂直方向滚动,只允许水平方向滚动;或只允许垂直方向滚动...

    禁止UIScrollView垂直方向滚动,只允许水平方向滚动 scrollview.contentSize =  CGSizeMake(你要的长度, 0);  禁止UIScrollView水平方向滚动 ...

最新文章

  1. cron计划任务使用
  2. 混合高斯模型(Mixtures of Gaussians)和EM算法
  3. Eclipse中怎样安装数据库建模工具ERMaster插件
  4. 分享WEBAPP利用纯HTML5实现拨打电话,打开相册,打开摄像头源码
  5. Python 21 Django 实用小案例1
  6. LeetCode 439. 三元表达式解析器
  7. jQuery源码研究分析学习笔记-回调函数(11)
  8. 杭电1978 How many ways
  9. python, numpy
  10. nginx虚拟目录支持PHP,nginx设置虚拟目录
  11. 数据库建表设计规范及原则
  12. 手把手教你搭建FastDFS集群(下)
  13. OpenCV Shi-Tomasi角点检测以及goodFeatureToTrack()源码分析
  14. OSError: [Errno 28] inotify watch limit reached
  15. 面向对象期末第三阶段
  16. 【题解】[NOIP2018 提高组] 填数游戏
  17. c语言实现单链表逆序算法,C语言解字符串逆序和单向链表逆序问题的代码示例...
  18. 计算机英语总结250字,英语作文范文 250字
  19. UVa-10474-大理石在哪
  20. Javaweb中web.xml配置文件编写方式

热门文章

  1. 数据结构 > 什么是数据结构?
  2. 支持动态调频,AXP228电源管理,预留锂电池接口,内置充放电电路及电量计iTOP-4418开发板...
  3. 《被讨厌的勇气》读书个人感悟总结
  4. Android studio添加阿里云Aliyun Maven仓库
  5. biostar handbook学习:第一周任务
  6. Android Studio常用的插件
  7. 记一次二B的错误:BindingException: Invalid bound statement (not found):
  8. 软件招标测试包含哪些测试?对软件项目起到什么作用?
  9. Java学习_day11_(抽象类、多态)
  10. android的BuildConfig学习