Skip to content
目录

Scroller

垂直滚动组件。

样式

支持 通用布局样式通用视图样式

属性

除支持 通用视图属性 以外,还支持以下属性:

属性名类型默认值说明示例
refreshViewView下拉刷新时展示的视图this.refreshView = new View();
loadMoreViewView上拉加载更多时展示的视图this.loadMoreView = new View();
onRefresh(state: number) => void下拉刷新时触发的回调this.onRefresh = (state) => {}

state取值:
0: 初始状态/结束刷新
1: 开始下拉
2: 正在刷新
onLoadMore(state: number) => void上拉加载时触发的回调this.onRefresh = (state) => {}

state取值:
0: 初始状态/结束加载
1: 正在加载
2: 无更多数据
showScrollBarbooleanfalse滑动时是否显示滚动条showScrollBar: true
bouncesbooleantrue滑动到边缘时是否有回弹效果bounces: false

事件

事件名类型说明
scrollScrollEvent滚动事件

方法

js
/**
 * 添加子视图
 * @param child 子视图
 */
appendChild(child: View);
js
/**
 * 移除子视图
 * @param child 子视图
 */
removeChild(child: View);
js
/**
 * 移除所有子视图
 */
removeAll();
js
/**
 * 在制定子视图前插入一个子视图
 *
 * @param child 新的子视图
 * @param existingChild 指定的子视图
 */
insertBefore(child: View, existingChild: View);
js
/**
 * 把指定的子视图替换成另一个子视图
 * 
 * @param newChild 新的子视图
 * @param oldChild 指定的子视图
 */
replaceChild(newChild: View, oldChild: View);
js
/**
 * 滚动到指定坐标(单位:dp/pt/hm/px)
 */
scrollTo(x: Object, y: Object);
js
/**
 * 滚动一定距离(单位:dp/pt/hm/px)
 */
scrollBy(dx: Object, dy: Object);
js
/**
 * 滚动到顶部
 */
scrollToTop();
js
/**
 * 滚动到底部
 */
scrollToBottom();
js
/**
 * 滚动到顶部事件监听
 */
setOnScrollToTopListener(callback: () => void);
js
/**
 * 滚动到底部事件监听
 */
setOnScrollToBottomListener(callback: () => void);
js
/**
 * 结束下拉刷新
 */
stopPullRefresh()
js
/**
 * 结束上拉加载更多
 * 
 * @param enable 下次能否继续触发加载更多
 */
stopLoadMore(enable: boolean)

示例

js
class RootView extends View {
    constructor() {
        super();
        this.style = {
            width: '100%',
            height: '100%',
        };

        this.scroll = new Scroller();
        this.scroll.style = {
            width: '100%',
            height: '100%',
//            showScrollBar: true,
        }

        for (let i = 0; i < 10; i++) {
            let item = new Text();
            item.text = "" + i;
            item.style = {
                height: 120,
                margin: 15,
                backgroundColor: '#FF000022',
                textAlign: 'center',
            };
            this.scroll.appendChild(item);
        }


        // 下拉刷新和加载更多
        this.page = 1;
        let pullRefreshCell = new PullRefreshCell();
        this.scroll.refreshView = pullRefreshCell;

        this.scroll.onRefresh = state => {
            console.log("PullRefresh: state = " + state);
            if (state == 1) {
                pullRefreshCell.setHint("下拉刷新");
            } else if (state == 2) {
                pullRefreshCell.setHint("加载中...");
                this.page = 1;
                this.loadData();
            } else {
                pullRefreshCell.setHint("加载完成");
            }
        };

        let loadMoreCell = new LoadMoreCell();
        this.scroll.loadMoreView = loadMoreCell;

        this.scroll.onLoadMore = state => {
             console.log("LoadMore: state = " + state);
             if (state == 1) {
                 loadMoreCell.setHint("加载中...");
                 this.page++;
                 this.loadMore();
             } else if (state == 2) {
                 loadMoreCell.setHint("没有更多数据");
             } else {
                 loadMoreCell.setHint("加载完成");
             }
        };

        this.scroll.addEventListener('scroll', (event) => {
            console.log('state = ' + event.state);
            console.log('offsetX = ' + event.offsetX);
            console.log('offsetY = ' + event.offsetY);
            console.log('dx = ' + event.dx);
            console.log('dy = ' + event.dy);
        })
        this.scroll.setOnScrollToTopListener(() => {
            console.log('ScrollToTop!');
        })
        this.scroll.setOnScrollToBottomListener(() => {
            console.log('ScrollToBottom!');
        })

        this.appendChild(this.scroll);


        // 底部操作按钮
        let btnLayout = new View();
        btnLayout.style = {
            position: 'absolute',
            flexDirection: 'row',
            alignSelf: 'center',
            width: 200,
            bottom: 0,
        };

        let btn1 = new Button();
        btn1.style = {
            height: 50,
            flexGrow: 1,
        };
        btn1.text = "滑到顶部";
        btn1.addEventListener("tap", event => {
             this.scroll.scrollToTop();
        });

        let btn2 = new Button();
        btn2.style = {
            height: 50,
            flexGrow: 1,
        };
        btn2.text = "滑到底部";
        btn2.addEventListener("tap", event => {
             this.scroll.scrollToBottom();
        });

        btnLayout.appendChild(btn1);
        btnLayout.appendChild(btn2);
        this.appendChild(btnLayout);
    }

    loadData() {
        setTimeout(() => {
            // do something
            this.scroll.stopPullRefresh();
        }, 300);
    }

    loadMore() {
        if (this.page < 1000) {
            setTimeout(() => {
                this.scroll.stopLoadMore(true);
                // do something
            }, 300);
        } else {
            this.scroll.stopLoadMore(false);
        }
    }
}

class PullRefreshCell extends View {
    constructor() {
        super();
        this.style = {
            width: '100%',
            height: 50,
            justifyContent: 'center',
            alignItems: 'center',
            backgroundColor: '#FFFF00',
        };

        this.textView = new Text();
        this.textView.text = 'PullRefreshCell';

        this.appendChild(this.textView);
    }

    setHint(hint) {
        this.textView.text = hint;
    }
}

class LoadMoreCell extends View {
    constructor() {
        super();
        this.style = {
            width: '100%',
            height: 30,
            justifyContent: 'center',
            alignItems: 'center',
            backgroundColor: '#00FF00',
        };

        this.textView = new Text();
        this.textView.text = 'LoadMoreCell';

        this.appendChild(this.textView);
    }

    setHint(hint) {
        this.textView.text = hint;
    }
}

Hummer.render(new RootView());