scrollview 优化扩展
论坛上的关于scrollview的列表优化有很多文章,这边提供一个新思路,用于在子节点尺寸不同情况下的使用方案
先定义子节点组件一个虚函数 setVisible
@ccclass("ScrollViewExItem")
export abstract class ScrollViewExItem extends Component {
abstract setVisible(b: boolean);
}
定义scrollview扩展持有 子节点列表
@ccclass("ScrollViewEx")
@requireComponent(cc.ScrollView)
@menu("tools/ScrollViewEx")
export default class ScrollViewEx extends Component {
_scrollview: cc.ScrollView;
_skeList: ScrollViewExItem[] = [];
onLoad() {
this._scrollview = this.node.getComponent(cc.ScrollView);
}
walk<T extends ScrollViewExItem>(comp: new (...args: any[]) => T) {
this._skeList = [];
this._scrollview.content.walk(
(node: cc.Node) => {
let c_sp = node.getComponent(comp);
if (c_sp) {
this._skeList.push(c_sp);
}
},
(node: cc.Node) => {}
);
this.onScroll();
}
protected onEnable(): void {
this._scrollview.node.on(cc.ScrollView.EventType.SCROLLING, this.onScroll, this);
this.node.on(
cc.Node.EventType.SIZE_CHANGED,
() => {
this.scheduleOnce(() => {
this.onScroll();
});
},
this
);
}
protected onDisable(): void {
this._scrollview.node.off(cc.ScrollView.EventType.SCROLLING, this.onScroll, this);
}
onScroll() {
if (!cc.isValid(this._scrollview.node)) {
return;
}
let viewRect = cc.rect(
0,
-this._scrollview.node.getComponent(cc.UITransform).height / 2,
this._scrollview.node.getComponent(cc.UITransform).width,
this._scrollview.node.getComponent(cc.UITransform).height / 2
);
for (let skeNode of this._skeList) {
if (!cc.isValid(skeNode.node)) {
return;
}
let curPos = this._scrollview.node
.getComponent(cc.UITransform)
.convertToNodeSpaceAR(skeNode.node.getComponent(cc.UITransform).convertToWorldSpaceAR(cc.v3(0, 0)));
let curRect = cc.rect(
curPos.x - skeNode.node.getComponent(cc.UITransform).width / 2.0,
curPos.y - skeNode.node.getComponent(cc.UITransform).height / 2.0,
skeNode.node.getComponent(cc.UITransform).width,
skeNode.node.getComponent(cc.UITransform).height
);
skeNode.setVisible(viewRect.intersects(curRect));
}
}
onDestroy() {
this._skeList.length = 0;
}
}
目的是通过子节点的大小,用矩形检测来达到控制显隐的目的
子节点集成scrollviewExItem之后,重写setVisible 方法达到控制的目的
scrollViewEx 通过walk函数来激活 ,具体示例在游戏列表scrollViewEx中