我有一个显示时间表的应用程序。
当滚动包含计划的右ScrollView
时,我希望包含时间的左ScrollView
也可以滚动。
<ScrollView
ref={'leftScroll'} />
<ScrollView
ref={'rightScroll'}
scrollEventThrottle={1}
onScroll={(e) => this.refs.leftScroll.scrollTo({y: e.nativeEvent.contentOffset.y)}
onMomentumScroll={(e) => this.refs.leftScroll.scrollTo({y: e.nativeEvent.contentOffset.y)} />
我们设法以这种方式滚动它,但它很慢且不连贯。
有没有办法完全同步这两个ScrollView
的滚动?
这种设计的原因是时间需要始终固定在屏幕左侧,房间需要始终固定在顶部,这些需要根据滚动进行滚动在时间表中。
答案 0 :(得分:3)
我有类似于你描述的要求 - ScrollView在左边有时间,ScrollView有一些正确的信息。
我能够通过对上面代码的一些小改动来实现平滑滚动在react-native中工作(尽管我没有使用onMomentumScroll)。在文档中,他们在scrollTo方法上提到了一个动画属性:https://facebook.github.io/react-native/docs/scrollview.html#scrollto
onScroll={(e) => this.refs.timeScroll.scrollTo({y: e.nativeEvent.contentOffset.y, animated: false})}
重要的是要注意,scrollEventThrottle={16}
是必需的,否则再次滚动是不连贯的。 React-Native文档提到值1-16不明显 - 因此使用16。
编辑:
我以为我会来更新一下。我的上述解决方案在一定程度上起作用,但它仍然具有最小的延迟,最终会引人注意。
最后,我最终实现了Animated,因为它仅使用原生。
定义:
const yOffset = new Animated.Value(0);
const onScroll = Animated.event(
[{ nativeEvent: { contentOffset: { y: yOffset } } }],
{ useNativeDriver: true }
);
创建方法:
viewTranslate() {
return {
transform: [{
translateY: yOffset.interpolate({
inputRange: [0,1],
outputRange: [1,0]
})
}]
};
}
将样式指定给Animated.View:
<Animated.View style={this.viewTranslate()>...</Animated.View>
将事件分配给Animated.ScrollView:
<Animated.ScrollView scrollEventThrottle={1} onScroll={onScroll}>...</Animated.ScrollView>
答案 1 :(得分:2)
由于React Native目前的工作方式,我担心这很困难。
您的第一个ScrollView
收到主线程上的滚动事件,并相应地滚动。然后React Native接受事件并将其发送到JS线程,以便可以在JS端处理,并且onScroll
事件可以触发。
然后你的处理程序调用方法滚动你的第二个ScrollView
,这意味着从JS线程安排一个新的事件在主线程上运行,这样就可以进行程序化滚动。
因此,由于所有这些调度和消息在这些线程之间传递,您的第二个ScrollView将始终落后于您经历的。
因此,如果您真的希望让它们同步,那么您将不得不求助于本机实现(这意味着iOS的实现和Android的另一个实现)。
一种可能的方法如下(iOS详细说明):
reactTag
的{{1}} React.findNodeHandle(component)
ScrollView
ScrollView
的指针
UIScrollView *scrollView = [[[self bridge] uiManager] viewForReactTag:reactTag]
挂钩到didScroll事件,以便你可以添加自定义逻辑以保持它们同步。您可以调动或替换UIScrollView
(不要忘记将原始事件转发给原始代理)。我建议你仔细查看RCTScrollView
以找到最适合的地方。我希望你能得到这个想法;)这绝对不是一件轻而易举的事,你需要在iOS编程方面有丰富的经验。但这是学习新事物的好机会。
答案 2 :(得分:1)
我尝试了@adam_提出的Animated解决方案,但是我发现视图转换本身不允许剪切,因此最终不适用于具有固定标题和左列的表。动画将在这些动画上播放。
此外,当与平面列表一起使用时,由于它是纯视图转换,因此滚动时不会加载列,因此空白区域会滚动到屏幕上。
如果有人对此有任何线索,表示赞赏。