Laya PageView组件简单实现

自己动手为Laya添加一个PageView组件

问题背景

Laya 1.x中没有PageView组件,就是一次滑动一整页的组件。

解决方法

替代方案是用List组件来实现一个。

方案要点

  1. 在触摸事件中处理翻页
  2. 利用List组件的成员scrollBar得到当前滑动的位置,然后计算出需要自动翻到第几页
  3. 利用List组件tweenTo方法来做翻页动画
  4. 翻页后发送翻页事件

代码

export class PageView extends Laya.List{
    constructor(){
        super();
    this.on(Laya.Event.MOUSE_UP, this, this.onMouseUp);
    this.on(Laya.Event.MOUSE_OUT, this, this.onMouseOut);

    this.renderHandler = Laya.Handler.create(this, this.renderItem);    
    
}

destroy(){
    this.off(Laya.Event.MOUSE_UP, this, this.onMouseUp);
    this.off(Laya.Event.MOUSE_OUT, this, this.onMouseOut);
}

onMouseUp(event){
    this._updatePage();
}

// onMouseMove(event){
//     console.info("PageView: mouse move => ", event);
// }

onMouseOut(event){
    // console.info("PageView: mouse out => ", event);
    this._updatePage();
}

private _currentPage:number = 0;
private _updatePage(){
    // 参考:https://gitee.com/hopher/layaair/blob/master/src/ui/src/laya/ui/List.as
    // this.tweenTo(0);
    // this.onScrollBarChange
    
    // 停止滚动
    this.scrollBar.stopScroll();
    // 滑行到下一页的位置
    // let length:number = this._array.length;
	// let totalPage = Math.ceil(length / (this.repeatX * this.repeatY));
    // let numX:number = this._isVertical ? this.repeatX : this.repeatY;
    // let numY:number = this._isVertical ? this.repeatY : this.repeatX; // 
    // let lineCount:number = Math.ceil(length / numX); // 总的行数
    let total = this._cellOffset > 0 ? this.totalPage + 1 : this.totalPage;

    let pageId = 0;
    if (total > 1) {
        pageId = Math.ceil((this.scrollBar.value - this._cellOffset - this._cellSize/2)/this._cellSize);
    } else {
        // this._scrollBar.setScroll(0, 0, 0);
        // this._scrollBar.target = this._content;
    }

    // console.info("Slider pos => ", this.scrollBar.slider.value);
    // console.info(`Neareast item id: ${pageId}`);
    this.tweenTo(pageId);
    this._currentPage = pageId;
    if(this._onPageChange){
        this._onPageChange(pageId);
    }
}

public get pageId(){
    return this._currentPage;
}

public set pageId(n:number){
    this._currentPage = n;
    this.tweenTo(n);
}

// onScrollBarChange(event){
//     super.onScrollBarChange(event);
    
//     console.info("ScrollBar Change => ", this.scrollBar.slider.value);
// }

private _onPageChange:(pageId:number)=>void = null;
public set onPageChangeHandler(handler:(pageId:number)=>void){
    this._onPageChange = handler;
}
public get onPageChangeHandler(){
    return this._onPageChange;
}

}