List
列表组件。
样式
除支持 通用布局样式 和 通用视图样式 以外,还支持以下样式:
属性名 | 类型 | 默认值 | 说明 | 示例 |
---|---|---|---|---|
属性名 | 说明 | 取值类型 | 示例/可能取值 | |
mode | string | 'list' | 布局模式 | mode: 'list' | 'grid' | 'waterfall' |
scrollDirection | string | 'vertical' | 滚动方向(仅在list模式下生效) | scrollDirection: 'vertical' | 'horizontal' |
column | number | 2 | 列数(仅在 grid 和 waterfall 模式下生效) | column: 3 |
lineSpacing | number|string | 0dp(waterfall: 8dp) | 行距 | lineSpacing: 4 |
itemSpacing | number|string | 0dp(waterfall: 8dp) | 列距(仅在 grid 和 waterfall 模式下生效) | itemSpacing: 4 |
leftSpacing | number|string | 0dp | 列表最左边缘间距 | leftSpacing: 4 |
rightSpacing | number|string | 0dp | 列表右边缘间距 | rightSpacing: 4 |
topSpacing | number|string | 0dp | 列表最顶部边缘间距 | topSpacing: 4 |
bottomSpacing | number|string | 0dp | 列表最底部边缘间距 | bottomSpacing: 4 |
属性
除支持 通用视图属性 以外,还支持以下属性:
属性名 | 类型 | 默认值 | 说明 | 示例 |
---|---|---|---|---|
onRegister | (position: number) => number | 注册 cell 复用标识的回调 | this.onRegist = (position) => {return type;} | |
onCreate | (type: number) => View | 创建 cell 的回调 | this.onCreate = (type) => {return new Cell();} | |
onUpdate | (position: number, cell: View) => void | 更新 cell 的回调 | this.onUpdate = (position, cell) => {} | |
refreshView | View | 下拉刷新时展示的视图 | this.refreshView = new View(); | |
loadMoreView | View | 上拉加载更多时展示的视图 | 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: 无更多数据 | |
showScrollBar | boolean | false | 滑动时是否显示滚动条 | showScrollBar: true |
bounces | boolean | true | 滑动到边缘时是否有回弹效果 | bounces: false |
事件
事件名 | 类型 | 说明 |
---|---|---|
scroll | ScrollEvent | 滚动事件 |
方法
js
/**
* 刷新列表
* @param count 列数 cell 数量
*/
refresh(count: number);
js
/**
* 滚动到指定位置
* @param position 要滚动到的位置
*/
scrollToPosition(position: number);
js
/**
* 滚动到指定坐标(单位:dp/pt/hm/px)
*/
scrollTo(x: Object, y: Object);
js
/**
* 滚动一定距离(单位:dp/pt/hm/px)
*/
scrollBy(dx: Object, dy: Object);
js
/**
* 结束下拉刷新
*/
stopPullRefresh()
js
/**
* 设置上拉加载控件
* @param enable 下次能否继续触发加载更多
*/
stopLoadMore(enable: boolean)
示例
js
const TYPE_TITLE = 1;
const TYPE_ITEM = 2;
const ITEM_COUNT = 20;
class RootView extends View {
constructor() {
super();
this.style = {
width: '100%',
height: '100%',
};
this.listView = new List();
this.listView.style = {
width: '100%',
height: '100%',
mode: "list",
// mode: "grid",
// mode: "waterfall",
// column: 4,
// scrollDirection: "vertical",
// scrollDirection: "horizontal",
lineSpacing: 14,
itemSpacing: 7,
topSpacing: 10,
leftSpacing: 10,
rightSpacing: 10,
bottomSpacing: 10,
// showScrollBar: true,
};
this.listView.onRegister = position => {
console.log("TypeCallback: position = " + position);
if (position % 2 === 0) {
return TYPE_TITLE;
} else {
return TYPE_ITEM;
}
};
this.listView.onCreate = type => {
console.log("CreateCallback: type = " + type);
if (type === TYPE_TITLE) {
return new TitleCell();
} else {
return new ItemCell();
}
};
this.listView.onUpdate = (position, cell) => {
console.log("UpdateCallback: position = " + position + ", cell = " + cell);
if (cell instanceof ItemCell) {
cell.refresh(position);
}
};
// 下拉刷新和加载更多
this.page = 1;
let pullRefreshCell = new PullRefreshCell();
this.listView.refreshView = pullRefreshCell;
this.listView.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.listView.loadMoreView = loadMoreCell;
this.listView.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.listView.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.appendChild(this.listView);
this.loadData();
}
loadData() {
setTimeout(() => {
this.listView.refresh(ITEM_COUNT);
this.listView.stopPullRefresh();
}, 300);
}
loadMore() {
if (this.page < 1000) {
setTimeout(() => {
this.listView.refresh(ITEM_COUNT * this.page);
this.listView.stopLoadMore(true);
}, 300);
} else {
this.listView.stopLoadMore(false);
}
}
}
class TitleCell extends View {
constructor() {
super();
this.style = {
backgroundColor: '#dddddd',
};
var textView = new Text();
textView.style = {
height: 30,
};
textView.text = 'Title';
this.appendChild(textView);
}
}
class ItemCell extends View {
constructor() {
super();
this.style = {
backgroundColor: '#FF000022',
};
this.textView = new Text();
this.textView.style = {
height: 30,
textAlign: "center",
};
var lineView = new View();
lineView.style = {
width: '100%',
height: 0.3,
backgroundColor: '#999999',
};
this.appendChild(this.textView);
// this.appendChild(lineView);
}
refresh(position) {
this.textView.text = position.toString();
}
}
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());