如何通过Drawer.Navigator的DrawerItem实现ScrollView滚动到指定组件?
实现DrawerItem点击后滚动到Home页面的AboutUs组件位置
现有代码
导航页面
<Drawer.Navigator initialRouteName="Home" drawerContent={props => { return ( <DrawerContentScrollView {...props}> <DrawerItemList {...props} /> <DrawerItem label="Scroll to aboutus"/> </DrawerContentScrollView> )} }}> <Drawer.Screen options={{ drawerLabel: 'Home', title: '' }} name="Home" component={HomeScreen} /> </Drawer.Navigator>
Home页面
export default function Home() { return ( <ScrollView> <View> <Text>One</Text> </View> <View style={{marginTop:100}}> <Text>two</Text> </View> <View style={{marginTop:100}}> <Text>three</Text> </View> <View style={{marginTop:100}}> <Text>four</Text> </View> <AboutUs/> </ScrollView> ); }
实现方案
步骤1:给Home页面的ScrollView和AboutUs添加引用并暴露滚动方法
用useRef获取ScrollView和AboutUs容器的引用,实现滚动到目标位置的方法后,通过导航选项把方法传递出去:
import { useRef, useEffect } from 'react'; import { ScrollView, View, Text } from 'react-native'; import { useNavigation } from '@react-navigation/native'; export default function Home() { const scrollViewRef = useRef(null); // 把AboutUs包在View里,方便获取位置信息 const aboutUsContainerRef = useRef(null); const navigation = useNavigation(); // 滚动到AboutUs的核心方法 const scrollToAboutUs = () => { aboutUsContainerRef.current?.measure((_x, _y, _width, _height, _pageX, pageY) => { scrollViewRef.current?.scrollTo({ y: pageY, animated: true, // 开启平滑滚动 }); }); }; // 将滚动方法挂载到导航选项中 useEffect(() => { navigation.setOptions({ scrollToAboutUs, }); }, [navigation, scrollToAboutUs]); return ( <ScrollView ref={scrollViewRef}> <View> <Text>One</Text> </View> <View style={{marginTop:100}}> <Text>two</Text> </View> <View style={{marginTop:100}}> <Text>three</Text> </View> <View style={{marginTop:100}}> <Text>four</Text> </View> <View ref={aboutUsContainerRef}> <AboutUs/> </View> </ScrollView> ); }
步骤2:给DrawerItem添加点击事件,调用滚动方法
修改导航页面的DrawerItem,添加onPress事件,获取Home页面的滚动方法并执行,同时关闭抽屉:
<Drawer.Navigator initialRouteName="Home" drawerContent={props => { return ( <DrawerContentScrollView {...props}> <DrawerItemList {...props} /> <DrawerItem label="Scroll to aboutus" onPress={() => { // 找到Home页面的路由实例 const homeRoute = props.navigation.getParent()?.getState().routes.find(route => route.name === 'Home'); // 调用滚动方法 homeRoute?.params?.scrollToAboutUs?.(); // 点击后自动关闭抽屉 props.navigation.closeDrawer(); }} /> </DrawerContentScrollView> )} }}> <Drawer.Screen options={{ drawerLabel: 'Home', title: '' }} name="Home" component={HomeScreen} /> </Drawer.Navigator>
补充说明
measure方法用于获取组件在屏幕上的位置,pageY就是目标组件相对于ScrollView顶部的偏移量- 若不需要平滑滚动,可将
animated设为false - 如果页面结构复杂,也可以通过React Context共享滚动方法,替代导航传参的方式
内容的提问来源于stack exchange,提问作者SaFteiNZz
相关产品推荐
相关产品推荐

