此问题的完整源代码已发布为Expo应用:https://exp.host/@kevinoldlifeway/swipe-scrollview-of-webviews以及Github https://github.com/kevinold/swipe-scrollview-of-webviews
我正在React Native中构建一个书籍视图。使用ScrollView,我想左右滑动以浏览可能有几百到几千的标题页面。
由于是这种情况,我的目标是只使用最少量的数据,以便用户能够在页面之间滑动,查看前一页和下一页。
我正在加载一个3元素数组,如下所示:
[Previous, Current, Next]
这将由Redux在状态下更新(此处不用于保持简单),并将重新呈现并重新聚焦列表。
我的目标是我的ScrollView
始终“居中”在“当前”页面上。
页面滚动到上一页和下一页由handleScroll
方法处理,该方法加载适当的预先计算的数组,以便当前页面保持焦点,但前一页和下一页(屏幕外)会相应更新。 / p>
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 });
}
我尝试使用以下组合平衡“当前”页面:
contentOffset={{ x: width, y: 0 }}
上的 ScrollView
和
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 });
}
我在scrollTo
之后的回调中尝试this.setState
,但没有运气。
我想知道是否可以使用Animated
完成这种“居中”。
答案 0 :(得分:1)
我给了他一个镜头,但我不完全确定我理解这个问题,我不确定这会有多好。
基本上我只是简单地简化了handleScroll功能。首先检查我们是否处于滚动完成状态,如果是这样,确定我们何时登陆该屏幕,它是“上一个”屏幕还是“下一个” - 如果它已经是中间屏幕则不执行任何操作。
我认为在您的代码中问题是,如果它是中间屏幕,它将触发并加载数据,而不仅仅是第一个或最后一个。因此,每次过渡都会发射两次。
这是我认为适合你的handleScroll。
handleScroll (event) {
const offset = event.nativeEvent.contentOffset.x;
const mod = offset % width;
if (mod === 0) { // only transition on scroll complete
if (offset === width * 2) { // last screen
console.log('load more')
this.loadMore();
this.scrollView.scrollTo({ x: width, y: 0, animated: false });
} else if (offset !== width) { // first screen
console.log('load prev')
this.loadPrev();
this.scrollView.scrollTo({ x: width, y: 0, animated: false });
}
}
}
一个Snack演示它。