版本:3.4.0
参考:ScrollView组件
简介
ScrollView
组件作为滚动容器来使用,它的实现通过ScrollBar组件来展示内容的位置和Mask组件显示指定区域,来保证有限的区域内显示更多的内容。
它的构成部分:
-
ScrollBar
滚动条相关, 编译器默认为垂直滚动条,在列表容器中一般active
设为false
-
view
表示可见区域,它的节点下有个Mask
组件遮罩;在该节点下可以添加一个Widget
组件,设置自动resize, 一般上下左右拉伸均为0且锁定 -
content
表示滚动区域,如果为列表,可以增加Layout
组件,设置水平,垂直,格子布局等,并将Layout
组件的ResizeMode
设为CONTAINER模式,允许对容器的大小进行改变注意: 不要同时使用
Layout
和Widget
,以免产生不可预料的后果。
它的属性部分:
属性 | 功能说明 |
---|---|
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,表示滚动行为会取消子节点上注册的触摸事件 |
使用
在脚本中使用,最多的情况是作为列表动态添加item相关。需要注意的是:
- ScrollView的子节点ScrollBar可设置为取消激活状态,即
active = false
- content节点下添加Layout组件,设置自动布局模式
注意设置type, ResizeMode, SpacingY即可。
添加item相关,我们会通过**@Property**来获取ScrollView
和对应的Prefab
,然后通过instantiate
克隆将item节点添加到ScrollView
的content节点中。
import { _decorator,Component, instantiate, Prefab, ScrollView} from 'cc';
const { ccclass, executeInEditMode, property } = _decorator;
@ccclass('UI_DemoLayer')
@executeInEditMode(true)
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 item = instantiate(this.itemPrefab);
item.parent = this.scroll.content;
}
}
}
官方提供了一些接口支持视图内容进行滚动:
/*
@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;
视图滚动到底部的实例:
// 设置视图10秒后滚动到底部
this.scroll.scrollToBottom(10, true);
// 检测视图是否滚动中
if (this.scroll.isAutoScrolling()) {
// 如果视图滚动中,则停止滚动
this.scroll.stopAutoScroll();
}
视图滚动到指定索引位置的实例:
// item有10个,目标索引从0开始
private scrollToIndex(targetIndex: number) {
// 可视区域内可显示3个,故此可以return调
if (targetIndex <= 2) {
return;
}
// 获取content大小
let transform = this.scroll.content.getComponent(UITransform);
let contentSize = transform.getBoundingBox().size;
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).getBoundingBox().size;
//
const curOffset = this.scroll.getScrollOffset();
const offsetY = targetIndex * (itemSize.height + spaceY);
this.scroll.scrollToOffset(new Vec2(0, offsetY), 0);
}
// 添加滚动事件,可用于检测滚动偏移量
onEnable() {
this.scroll.node.on(ScrollView.EventType.SCROLLING, this.Scrolling, this);
}
private Scrolling() {
// 注意:如果滚动区域小于可见区域,所有的都为0
console.log("当前滚动偏移量:", this.scroll.getScrollOffset());
console.log("最大可滚动偏移量:", this.scroll.getMaxScrollOffset());
}
事件
滚动视图的事件类型主要放置在ScrollView.EventType
中,主要有:
类型名 | 内容 |
---|---|
SCROLL_TO_TOP | 滚动视图滚动到顶部边界事件。 |
SCROLL_TO_BOTTOM | 滚动视图滚动到底部边界事件。 |
SCROLL_TO_LEFT | 滚动视图滚动到左边界事件。 |
SCROLL_TO_RIGHT | 滚动视图滚动到右边界事件。 |
SCROLL_BEGAN | 滚动视图滚动开始时发出的事件。 |
SCROLL_ENDED | 滚动视图滚动结束的时候发出的事件。 |
BOUNCE_TOP | 滚动视图滚动到顶部边界并且开始回弹时发出的事件。 |
BOUNCE_BOTTOM | 滚动视图滚动到底部边界并且开始回弹时发出的事件。 |
BOUNCE_LEFT | 滚动视图滚动到左边界并且开始回弹时发出的事件。 |
BOUNCE_RIGHT | 滚动视图滚动到右边界并且开始回弹时发出的事件。 |
SCROLLING | 滚动视图正在滚动时发出的事件。滚动视图正在滚动时发出的事件。 |
SCROLL_ENG_WITH_THRESHOLD | 滚动视图自动滚动快要结束的时候发出的事件。 |
TOUCH_UP | 当用户松手的时候会发出一个事件。 |
脚本中使用on
创建的简单实例:
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);
}
private scrolling(scrollView: ScrollView) {
// 此种方式的回调,参数只会有一个为ScrollView组件
}
编译器中使用ScrollEvents
设定事件,注意设置一个即可
public ScrollEvent_1(scroll: ScrollView, eventType: any, customData: any) {
// 返回三个参数,分别对应ScrollView组件, 事件类型,自定义数据
}
拓展
性能优化相关…