如何滚动到反应原生 scrollView 层次结构中的特定视图
how to scroll to a particular view inside react native scrollView hierarchy
为了在 ScrollView 层次结构中获得视图的 Y 偏移量,我们需要使用 onLayout 并继续添加每个父视图的 Y 偏移量(需要相对于 ScrollView 的偏移量)直到我们到达滚动视图。这个过程在大型组件层次结构中是乏味的。我正在尝试围绕 React Native 的 ScrollView 编写一个包装器,它将公开一个名为 scrollIntoView 的方法,该方法引用您需要滚动到的视图并滚动到该视图。
为此,我正在寻找一些方法从给定视图的引用开始并开始遍历给定视图的祖先,并继续添加由 onLayout 回调提供的 Y 偏移值。但我不知道该怎么做。
任何帮助将不胜感激。
注意:onLayout 给出了相对于父组件的 Y 偏移量,因此我们需要对每个视图的祖先进行求和,以计算视图相对于 ScrollView 的 Y 偏移量
没有优雅的解决方案。一个想法是获取 View
在页面级别的位置,然后用 ScrollView
中的第一个 child 偏移它。使用第一个 child 的原因是因为 ScrollView
可以有一个初始滚动值,我们需要适当地偏移它。
将 ref 分配给 ScrollView
并插入一个虚拟 View
作为第一个 child 以测量滚动位置。还要为要滚动到的视图分配一个 ref
<ScrollView ref={scrollViewRef}>
{/* collapsable={false} needed for measure to work properly on Android devices */}
<View ref={topViewRef} collapsable={false} />
{/* View you want to scroll to.
It could be inside a nested component */}
<Text ref={labelRef} collapsable={false}>Scroll here</Text>
</ScrollView>
然后调用这个函数,传入ScrollView Ref,Initial view Ref和你要滚动到的View。
export function scrollTo(scrollViewRef, topViewRef, viewToScrollToRef, offset = 0) {
const scrollView = scrollViewRef.current;
const topView = topViewRef.current;
const viewToScrollTo = viewToScrollToRef.current;
if (!scrollView || !topView || !viewToScrollTo) {
//Throw an error or something
return;
}
topView.measure((_ox, _oy, _width, _height, _px, topViewY) => {
viewToScrollTo.measure((_ox2, _oy2, _width2, _height2, _px2, viewToScrollToY) => {
scrollView.scrollTo({
x: 0,
y: viewToScrollToY - topViewY + offset,
animated: true,
});
});
});
}
为此,我正在寻找一些方法从给定视图的引用开始并开始遍历给定视图的祖先,并继续添加由 onLayout 回调提供的 Y 偏移值。但我不知道该怎么做。
任何帮助将不胜感激。
注意:onLayout 给出了相对于父组件的 Y 偏移量,因此我们需要对每个视图的祖先进行求和,以计算视图相对于 ScrollView 的 Y 偏移量
没有优雅的解决方案。一个想法是获取 View
在页面级别的位置,然后用 ScrollView
中的第一个 child 偏移它。使用第一个 child 的原因是因为 ScrollView
可以有一个初始滚动值,我们需要适当地偏移它。
将 ref 分配给 ScrollView
并插入一个虚拟 View
作为第一个 child 以测量滚动位置。还要为要滚动到的视图分配一个 ref
<ScrollView ref={scrollViewRef}>
{/* collapsable={false} needed for measure to work properly on Android devices */}
<View ref={topViewRef} collapsable={false} />
{/* View you want to scroll to.
It could be inside a nested component */}
<Text ref={labelRef} collapsable={false}>Scroll here</Text>
</ScrollView>
然后调用这个函数,传入ScrollView Ref,Initial view Ref和你要滚动到的View。
export function scrollTo(scrollViewRef, topViewRef, viewToScrollToRef, offset = 0) {
const scrollView = scrollViewRef.current;
const topView = topViewRef.current;
const viewToScrollTo = viewToScrollToRef.current;
if (!scrollView || !topView || !viewToScrollTo) {
//Throw an error or something
return;
}
topView.measure((_ox, _oy, _width, _height, _px, topViewY) => {
viewToScrollTo.measure((_ox2, _oy2, _width2, _height2, _px2, viewToScrollToY) => {
scrollView.scrollTo({
x: 0,
y: viewToScrollToY - topViewY + offset,
animated: true,
});
});
});
}