My complete source code for this issue is posted as an Expo app: https://exp.host/@kevinoldlifeway/swipe-scrollview-of-webviews as well as on Github https://github.com/kevinold/swipe-scrollview-of-webviews
I am building a book view in React Native. Using a ScrollView, I would like to swipe left and right to navigate through the pages of a title that could have several hundred to several thousand.
Since that is the case, my goal is to only the minimal amount of data so that the user is able to swipe between pages, seeing the immediately previous and next pages.
I am loading a 3 element array like so:
[Previous, Current, Next]
That would be updated in the state by Redux (not used here to keep simple) and would re-render and refocus the list.
My goal is that my ScrollView
is always "centered" on the "Current" page.
Page scrolls to the previous and next page are handled by a handleScroll
method which loads the appropriate precomputed array so that the current page stays in focus, but the previous and next pages (offscreen) are updated appropriately.
handleScroll (event) {
//const x = event.nativeEvent.contentOffset.x;
const { activeIndex, scrollTimes } = this.state;
const windowWidth = Dimensions.get('window').width;
const eventWidth = event.nativeEvent.contentSize.width;
const offset = event.nativeEvent.contentOffset.x;
console.log('event width: ', eventWidth);
console.log('event offset: ', offset);
console.log('scrollTimes: ', scrollTimes);
//if (scrollTimes <= 1 ) return;
if (windowWidth + offset >= eventWidth) {
//ScrollEnd, do sth...
console.log('scrollEnd right (nextPage)', offset);
const nextIndex = activeIndex + 1;
console.log('nextIndex: ', nextIndex);
// Load next page
this.loadMore()
} else if (windowWidth - offset <= eventWidth) {
//ScrollEnd, do sth...
console.log('scrollEnd left (prevPage)', offset);
// Load prev page
this.loadPrev()
}
this.setState({ scrollTimes: scrollTimes + 1 });
}
I have tried to balance the "current" page using a combination of:
contentOffset={{ x: width, y: 0 }}
on ScrollView
And
componentDidMount() {
// Attempt to keep "center" element in array as focused "screen" in the horizontal list view
this.scrollView.scrollTo({ x: width, y: 0, animated: false });
}
I've also tried to scrollTo
in the callback after this.setState
, but have not had any luck.
I'm wondering if this "centering" could be accomplished by using Animated
.