本文共 2751 字,大约阅读时间需要 9 分钟。
尊重版权,未经授权不得转载
本项目来自 文章来自江清清的技术专栏()
原文地址(需要翻墙):
在手机应用中,图片列表的滚动操作是非常常见的,而且这个功能一般用户的期望都比较高,需要很不错的用户体验。在上一篇文章中(),我们主要分享了如何实现React Native中的图片缓存,在本文中我将会给大家带来在图片列表滚动过程中如何进行优化ListView中的图片加载。
React Native交流10群:157867561,欢迎各位大牛,React Native技术爱好者加入交流!同时博客右侧欢迎微信扫描关注订阅号,移动技术干货,精彩文章技术推送!
例如:一个类似Instagram应用中的图片类目。当我们从服务器获取一页数据之后,刚开始当用户滚动列表到底部的时候,我们发送请求从服务器获取更多数据。其次,当一个图片项进入屏幕显示的时候,我们通过图片缓存模块获取并且显示图片。最终当该图片项滑出屏幕的时候,如果该图片还没有被显示与缓存,我们需要取消该图片下载来提供可见项处理优先级。
在下面的示例中,我们从firebase后端获取一页10条数据,当我们滑动列表到最底端的时候,我们通过触发onEndReached事件方法来获取新的一页数据。具体代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | export default class Feed extends Component<{}, void > { currentPage = 1 ; pageSize = 10 ; feed: ListViewDataSource = new ListView.DataSource({ rowHasChanged: (r1, r2) => r1.id !== r2.id }); loadPage() { firebase.database().ref( "/feed" ) .limitToFirst( this .pageSize * this .currentPage) .once( "value" ).then(snapshot => { this .currentPage++; this .feed = this .feed.cloneWithRows(snapshot.val()); }); } componentWillMount() { this .loadFeed(); } render() { const {store} = this .props; return <ListView dataSource={store.feed} renderRow={row => <View><CachedImage source={ { uri: row.uri }} /></View> } onEndReached={() => this .loadFeed()} />; } } |
现在我们可以使用onChangeVisibleRows()方法来只加载可见列表项图片。我们来创建一个带有visible属性的Row组件,通过ref()回调保证每一项显示的列表行数据保持最新,最后在onChangeVisibleRows()方法,进行更新列表中每一项的visible属性状态是可见或者不可见。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | export default class Feed extends Component<{}, void > { //Keep a reference of all mounted Rows rows: { [id: string ]: any } = {}; render() { return <ListView dataSource={store.feed} // We use ref to keep the reference of all mounted rows // The visible property will be set to true in onChangeVisibleRows() renderRow={row => <Row ref={el => this .rows[row.id] = el} visible={ false } row={row} />} onEndReached={() => this .loadFeed()} onChangeVisibleRows={(visibleRows, changedRows) => { _.forEach(changedRows[ "s1" ], (visible, index) => { // We get the reference of the mounted row //and set its property to true const id = this .feed.getRowData( 0 , index).id; this .rows[id].props.visible = visible; }); }} />; } } |
在Row组件中,我们可以通过visible属性来挂载/卸载图片控制该隐藏或者显示。我们通过react-native-img-cache包加载显示图片。
1 2 3 4 5 6 7 8 | export default class Row extends Component<RowProps, void > { render() { const {visible, row} = this .props; return <View> {visible && <CachedImage source={ { uri: row.pictureURI }} />} </View>; } } |
然后是最后一步,如果该Row变得不显示的时候,就会取消下载图片的HTPP请求。react-native-img-cache库依赖于react-native-fetch-blob库,可以同时实现下载图片功能和取消HTTP请求功能。具体实现如下:
1 2 3 | if (!visible) { ImageCache.get().cancel(row.uri); } |
React Native交流10群:157867561,欢迎各位大牛,React Native技术爱好者加入交流!同时博客右侧欢迎微信扫描关注订阅号,移动技术干货,精彩文章技术推送!