城市列表(八)02-精准城市列表定位——高亮索引跟随页面滚动-List组件onRowsRendered配置项-scrollToRow滚动 & 点击索引控制列表定位-scrollToAlignment城市置顶
- 滚动列表让对应索引高亮
- List组件onRowsRendered配置项
-
overscanStartIndex: number, // 表示额外渲染行的开始索引
-
overscanStopIndex: number, // 表示额外渲染行的结束索引
-
startIndex: number, // 表示List组件可视区域渲染行的起始索引
-
stopIndex: number // 表示List组件可视区域渲染行的结束索引
-
- List组件onRowsRendered配置项
onRowsRendered = ({ startIndex }) => {
// console.log('currentIndex:', startIndex)
if (this.state.currentIndex !== startIndex) {
this.setState({
currentIndex: startIndex
})
}
}
- 点击索引跳转
scrollToRow
是组件的公共方法(实例方法),参数:(index: number) 索引号
// 构造函数中添加
this.listRef = React.createRef()
// List组件标签中添加
ref={this.listRef}
onClick={() => {
// console.log('当前索引号:', index)
this.listRef.current.scrollToRow(index)
}}
- 精确调到顶部
- scrollToAlignment=“start”
- 解决 List 组件中 scrollToRow 方法,跳转到不可见行不准确的问题:
this.setState({
cityList: cityList,
cityIndex: cityIndex
}, () => {
this.listRef.current.measureAllRows()
})
实例
第五步:监听列表滚动行为
长列表属性:https://github.com/bvaughn/react-virtualized/blob/master/docs/List.md
滚动列表让对应索引高亮
- List组件onRowsRendered配置项
-
overscanStartIndex: number, // 表示额外渲染行的开始索引
-
overscanStopIndex: number, // 表示额外渲染行的结束索引
-
startIndex: number, // 表示List组件可视区域渲染行的起始索引
-
stopIndex: number // 表示List组件可视区域渲染行的结束索引
-
实例
onRowsRendered属性加入到list中
<AutoSizer>
{({height, width}) => {
// 只要数据获取到之后,才进行列表渲染,保证列表可以获取数据
if (cityList) {
return <List
ref={this.listRef}
width={width}
height={height}
scrollToAlignment="start"
onRowsRendered={this.onRowsRendered} //最好同名
rowCount={cityList.indexList.length}
rowHeight={this.calcRowHieght}
rowRenderer={this.rowRenderer}
/>
}
}}
</AutoSizer>
定义方法
//onRowsRendered = (params) => {
// console.log(params)
onRowsRendered = ({startIndex}) => {
// console.log({startIndex})
// 监控列表的渲染:需要判断startIndex是否发生变化
// console.log(this.state.currentIndex, startIndex)
if (this.state.currentIndex !== startIndex) {
// console.log(startIndex)
this.setState({
currentIndex: startIndex
})
}
}
打印params-List组件onRowsRendered配置项
打印{startIndex}——会触发多次startIndex
打印startIndex——触发一次startIndex,防止频繁更新列表
第六步:控制点击索引控制列表定位–click事件-字母
<li
key={index}
onClick={() => {
//console.log('index') 1 2 3 4
// 控制索引点击的列表定位
// 3.获取组件的实例对象,方便调用组件的实例方法
let list = this.listRef.current
// console.log(typeof list.scrollToRow) scrollToRow是个函数fuction
// 4.控制列表滚动到当前索引的位置
list.scrollToRow(index)
}}
className="city-index-item">
<span className={currentIndex===index?'index-active': ''}>
{item==='hot'?'热': item.toUpperCase()}
</span>
</li>
1.创建List组件的引用对象
constructor (props) {
super(props)
this.state = {
cityList: null,
currentIndex: 0 //默认索引为0
}
// 创建List组件的引用对象
this.listRef = React.createRef()
}
2.组件关联ref
<AutoSizer>
{({height, width}) => {
// 只要数据获取到之后,才进行列表渲染,保证列表可以获取数据
if (cityList) {
return <List
ref={this.listRef} //关联ref
width={width}
height={height}
scrollToAlignment="start"
onRowsRendered={this.onRowsRendered}
rowCount={cityList.indexList.length}
rowHeight={this.calcRowHieght}
rowRenderer={this.rowRenderer}
/>
}
}}
</AutoSizer>
此时,初步完成定位;点击右侧大写字母,可与左侧城市联动,但城市位置不确定在界面顶部
第七步:实现精准定位在页面顶部
1.在界面代码处添加滚动属性代码
<AutoSizer>
{({height, width}) => {
// 只要数据获取到之后,才进行列表渲染,保证列表可以获取数据
if (cityList) {
return <List
ref={this.listRef}
width={width}
height={height}
scrollToAlignment="start" //滚动属性
onRowsRendered={this.onRowsRendered}
rowCount={cityList.indexList.length}
rowHeight={this.calcRowHieght}
rowRenderer={this.rowRenderer}
/>
}
}}
</AutoSizer>
2.计算列表高度
// 更新数据
this.setState({
cityList: ret
}, () => {
// 提前计算列表的总高度,方便控制列表的精准定位
this.listRef.current.measureAllRows() //不加,列表短也可实现精准效果
})
// 隐藏提示效果
Toast.hide()
3.最终效果-精确顶部