Skip to content

ScrollView 组件 ​

ScrollView 是一种带滚动功能的容器,它提供一种方式可以在有限的显示区域内浏览更多的内容。通常 ScrollView 会与 Mask 组件 配合使用,同时也可以添加 ScrollBar 组件 来显示浏览内容的位置。

  • 图 2

点击 属性检查器 下面的 添加组件 按钮,然后选择 UI/ScrollView 即可添加 ScrollView 组件到节点上

ScrollView 属性 ​

属性功能说明
content它是一个节点引用,用来创建 ScrollView 的可滚动内容,通常这可能是一个包含一张巨大图片的节点。
Horizontal布尔值,是否允许横向滚动。
Vertical布尔值,是否允许纵向滚动。
Inertia滚动的时候是否有加速度。
Brake浮点数,滚动之后的减速系数。取值范围是 0-1,如果是 1 则立马停止滚动,如果是 0,则会一直滚动到 content 的边界。
Elastic布尔值,是否回弹。
BounceDuration浮点数,回弹所需要的时间。取值范围是 0-10。
HorizontalScrollBar它是一个节点引用,用来创建一个滚动条来显示 content 在水平方向上的位置。
VerticalScrollBar它是一个节点引用,用来创建一个滚动条来显示 content 在垂直方向上的位置
ScrollEvents列表类型,默认为空,用户添加的每一个事件由节点引用,组件名称和一个响应函数组成。详情见下方的 ScrollView 事件
CancelInnerEvents如果这个属性被设置为 true,那么滚动行为会取消子节点上注册的触摸事件,默认被设置为 true。

ScrollView 事件 ​

ScrollView 的事件回调有两个参数,第一个参数是 ScrollView 本身,第二个参数是 ScrollView 的事件类型。

ScrollBar 设置 ​

ScrollBar 是可选的,你可以选择只设置 Horizontal ScrollBar 或者 Vertical ScrollBar,当然也可以两者都设置。建立关联可以通过在 层级管理器 里面拖拽一个带有 ScrollBar 组件的节点到 ScrollView 的相应字段完成。

详细说明 ​

ScrollView 组件必须有指定的 content 节点才能起作用,通过指定滚动方向和 content 节点在此方向上的长度来计算滚动时的位置信息,Content 节点也可以通过添加 Widget 设置自动 resize,也可以通过添加 Layout 来完成子节点布局,但是这两个组件不应该同时添加到一个节点上以避免产生不可预料的后果。

通常一个 ScrollView 的节点树如下图:

这里的 view 用来定义一个可以显示的滚动区域,所以通常 Mask 组件 会被添加到 view 上。可以滚动的内容可以直接放到 content 节点或者添加节 content 的子节点上。

通过脚本代码添加回调 ​

方法一 ​

这种方法添加的事件回调和使用编辑器添加的事件回调是一样的,都是通过代码添加。首先需要构造一个 EventHandler 对象,然后设置好对应的 target、component、handler 和 customEventData 参数。

ts
import { _decorator, Component, ScrollView, EventHandler } from "cc";
const { ccclass, property } = _decorator;

@ccclass("example")
export class example extends Component {
  onLoad() {
    const scrollViewEventHandler = new EventHandler();
    scrollViewEventHandler.target = this.node; // 这个 node 节点是你的事件处理代码组件所属的节点
    scrollViewEventHandler.component = "example"; // 这个是脚本类名
    scrollViewEventHandler.handler = "callback";
    scrollViewEventHandler.customEventData = "foobar";

    const scrollview = this.node.getComponent(ScrollView);
    scrollview.scrollEvents.push(scrollViewEventHandler);
  }

  callback(scrollview, eventType, customEventData) {
    // 这里 scrollview 是一个 Scrollview 组件对象实例
    // 这里的 eventType === ScrollView.EventType enum 里面的值
    // 这里的 customEventData 参数就等于你之前设置的 'foobar'
  }
}

方法二 ​

通过 scrollview.node.on('scroll-to-top', ...) 的方式来添加

ts
// 假设我们在一个组件的 onLoad 方法里面添加事件处理回调,在 callback 函数中进行事件处理:
import { _decorator, Component, ScrollView } from "cc";
const { ccclass, property } = _decorator;

@ccclass("example")
export class example extends Component {
  @property(ScrollView)
  scrollview: ScrollView | null = null;
  onLoad() {
    this.scrollview.node.on("scroll-to-top", this.callback, this);
  }

  callback(scrollView: ScrollView) {
    // 回调的参数是 ScrollView 组件,注意这种方式注册的事件,无法传递 customEventData
  }
}

同样的,你也可以注册 scrolling、touch-up、scroll-began 等事件,这些事件的回调函数的参数与 scroll-to-top 的参数一致。

实战 ​

注意 ​

  • view 和 ScrollView 高度一样 ,但是宽度要比 ScrollView 宽度小

  • view/content content 的高度一定要设置比 view 高度大,否则不会出滚动条

  • content 里面添加一个 layout 组件.

  • 预制体换成 Button 这样预制体绑定点击事件.能传递值

代码 ​

ts
import {
  _decorator,
  Component,
  instantiate,
  Node,
  Prefab,
  find,
  Label,
  UITransform,
  Layout,
} from "cc";
const { ccclass, property } = _decorator;

@ccclass("ScrollView")
export class ScrollView extends Component {
  @property(Prefab)
  itemPrefab: Prefab = null;
  start() {
    this.init();
  }

  update(deltaTime: number) {}

  init() {
    const parent = find("view/content", this.node);
    for (let i = 0; i < 30; i++) {
      const node = instantiate(this.itemPrefab);
      console.log(node);
      console.log(node.getChildByName("Label"));
      node.getChildByName("Label").getComponent(Label).string =
        "我就是测试第一个数据看看滚动没有" + i.toString();
      node.setParent(parent);
    }
    // 40 高度 + 间距
    parent.getComponent(UITransform).setContentSize(460, 31 * 60);
    parent.getComponent(Layout).updateLayout();
  }
  handleClick(e) {
    console.log(e.target);
    let node = e.target;
    let result = node.getChildByName("Label").getComponent(Label).string;
    console.log(result);
  }
}