Is there a way to update a react-native ListView DataSource in place so it doesn't reset scroll position?
Asked Answered
H

2

9

I have a ListView that gets an initial DataSource. The user can then run a search which will update the ListView with a new DataSource. Unfortunately when this happens, the scroll position gets reset, which isn't ideal.

I tried reusing the same ListView.DataSource object instead of creating a new one, but that gave me the same results:

...

dataSource: new ListView.DataSource({
  rowHasChanged: (r1, r2) => r1 !== r2
}),

componentWillReceiveProps(nextProps) {
this.setState({
  dataSource: this.dataSource.cloneWithRowsAndSections({...});
}

...

I tried using scrollTo on the ListView after the dataSource is changed, but this cases the app to jump around a lot...not a good experience. Is there a ListView setting or a different way to update the dataSource that will prevent the scroll position from resetting?

The ListView has 2 sticky headers, the top header has 2 rows a page description and a redux container that renders a 3 image grid. The second section is a list of up to 50 components that are somewhat heavy to render: a square image, some text and a few SVGs. My current method works using onContentSizeChange to force the scroll position, but this causes scroll position jumpiness and it looks amateur.

UPDATE: Digging into the documentation and source code for ListView it ultimately just renders a ScrollView. I can use contentOffset to set the initial scroll position, but it doesn't seem to help when the ListView DataSource updates; even hardcoding contentOffset doesn't help. I also tried setting scrollEnabled to false, which did indeed prevent user driven scrolling, but the ListView scroll position is still reset when it's DataSource is updated :s

UPDATE 2: I have done some further debugging and discovered that the suggested rowHasChange and sectionHeaderHasChanged functions do a pretty good job of only rendering rows/section headers that need to be rendered.

Husband answered 1/11, 2016 at 20:39 Comment(0)
H
0

You can save your scroll position and after setting new props to ListView — make scrollTo without animation

Hazelhazelnut answered 18/11, 2016 at 21:49 Comment(4)
I tried this stereodenis and it "works" but the UX isn't acceptable. The view bounces around a lot, flickers and sometimes ends up in slightly offset places.Husband
I will try to make a smooth example and then will update my answer. Maybe you should add loaders or other element, which shows to user, that data is changingHazelhazelnut
Check this or HereSunnysunproof
Sadly, I do that but after the loader hides itself the scroll position jumps around...still doesn't look good. I'm able to achieve this just fine on the web and our Android Developer has it working great there and our old native iOS app does this fine. It's technically possible, but might not be implemented correctly in the current react-native ListView :(Husband
Y
0

What I would do in your case is to show a kind of overlay with a loading spinner to hide the bouncing effect and then hide the overlay once the scroll has been set, can't tell how to achieve it since I'm pretty new to RN but surely its possible

Ybarra answered 20/3, 2017 at 19:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.