React Native ListView: Prepend Items

2020-06-04 05:44发布

问题:

Is it possible to prepend items to React Native's ListView on an onTopReached event similar to the way one appends items on an onEndReached event? Currently, when I prepend rows to the list the ListView scrolls to the top.

The use case: I have an app with a feed the user can scroll down. When navigating away from the feed and then back to it I want to show the last seen row at the top. The user should then be able to scroll either up to see the previous rows she/he has scrolled passed and of course down to load new rows. Assuming I've already rendered the ListView starting from the last seen row a contrived example would look something like this:

  _onTopReached() {
    this._unshiftRows();
  },

  _unshiftRows() {
    var list = this.props.list; // The entire list
    var lastSeenRowIndex = this.props.lastSeenRowIndex;
    var prevRows = list.slice(0, i);  
    this._rows = prevRows.concat(this._rows);
    this.setState({
      dataSource: this.state.dataSource.cloneWithRows(this._rows)
    });
  },

In the example above I'm just prepending the first part of the list to the already rendered last part with _onTopReached firing right away because I'm already at the top. This however causes the ListView to re-render with the first row at the top of the screen rather than maintaining the previous position.

An alternative is to store the y offset of the last seen row and on navigating back to the ListView scroll to that position. However, that method requires every row before the current one to render which is time consuming. I've also not been able to get the correct offset with scrollWithoutAnimationTo or by setting contentOffSet. It does however scroll to the correct position if I use scrollTo or set a timeout before calling scrollWithoutAnimationTo and allow for the first rows to render in the mean time. But that's not very nice.

All help would be much appreciated. Thanks!

回答1:

You should use FlatList

Try adding the new items to the data source and use the 'scrolltoindex' method.

FlatList

scrollToIndex(params: object) Scrolls to the item at the specified index such that it is positioned in the viewable area such that viewPosition 0 places it at the top, 1 at the bottom, and 0.5 centered in the middle. viewOffset is a fixed number of pixels to offset the final target position.