Expo中react-navigation头部折叠动画实现及相关示例适配咨询
通用场景下react-navigation头部动画实现方案
react-navigation本身支持完全自定义header组件,你可以搭配React Native原生Animated API或者第三方动画库实现滚动联动动画,核心逻辑是将列表滚动的偏移量和header的样式属性(高度、透明度、translateY等做绑定:
- 第一步:在页面组件中创建Animated值跟踪滚动位置
- 第二步:自定义header组件,将Animated值映射为header的样式参数
- 第三步:将滚动组件的
onScroll事件绑定到Animated值的更新逻辑
简单示例代码如下:
import { Animated, ScrollView, Text, View } from 'react-native'; import { useNavigation } from '@react-navigation/native'; const CustomScreen = () => { const navigation = useNavigation(); const scrollY = new Animated.Value(0); // 自定义header样式映射,比如滚动时header背景从透明变纯色 const headerBackgroundColor = scrollY.interpolate({ inputRange: [0, 100], outputRange: ['transparent', '#fff'], extrapolate: 'clamp' }); const headerOpacity = scrollY.interpolate({ inputRange: [0, 100], outputRange: [0, 1], extrapolate: 'clamp' }); // 配置自定义header React.useLayoutEffect(() => { navigation.setOptions({ headerTransparent: true, headerBackground: () => ( <Animated.View style={{ flex: 1, backgroundColor: headerBackgroundColor, opacity: headerOpacity }} /> ), headerTitle: () => ( <Animated.Text style={{ opacity: headerOpacity, fontWeight: '600' }}> 页面标题 </Animated.Text> ) }); }, [navigation, scrollY]); return ( <ScrollView scrollEventThrottle={16} onScroll={Animated.event( [{ nativeEvent: { contentOffset: { y: scrollY } }], { useNativeDriver: false } )} > {/* 页面内容,高度超过一屏即可看到动画效果 */} <View style={{ height: 1000, paddingTop: 100 }}> <Text>测试内容</Text> </View> </ScrollView> ); };
Coinbase示例与react-navigation整合方案
Coinbase的TabView示例核心是实现了跟随滚动切换的头部交互,和react-navigation整合的逻辑很简单:
直接关闭当前页面的react-navigation默认header,复用Coinbase示例中的自定义头部组件,只需要在自定义头部中添加导航需要的返回按钮、标题等元素,通过useNavigation hook拿到导航实例实现跳转、返回等逻辑即可,两者没有额外的兼容问题。
react-navigation-collapsible搭配使用示例
下面是最小可运行的整合代码:
import { ScrollView, Text, View } from 'react-native'; import { createStackNavigator } from '@react-navigation/stack'; import { collapsibleScreenOptions, useCollapsibleHeader } from 'react-navigation-collapsible'; import Animated from 'react-native-reanimated'; const Stack = createStackNavigator(); const TestScreen = () => { const { paddingTop, scrollIndicatorInsetTop, onScroll } = useCollapsibleHeader(); return ( <Animated.ScrollView onScroll={onScroll} scrollIndicatorInsets={{ top: scrollIndicatorInsetTop }} > <View style={{ paddingTop, padding: 16 }}> {Array(20).fill(0).map((_, i) => ( <Text key={i} style={{ paddingVertical: 12, fontSize: 16 }}> 列表项 {i+1} </Text> ))} </View> </Animated.ScrollView> ); }; const AppNavigator = () => { return ( <Stack.Navigator> <Stack.Screen name="Test" component={TestScreen} options={{ ...collapsibleScreenOptions({ header: { title: '可折叠头部', headerStyle: { backgroundColor: '#fff' } } }) }} /> </Stack.Navigator> ); };
react-navigation-collapsible默认已经处理了和react-navigation的适配逻辑,不需要自己手动绑定滚动事件和header动画的映射关系,只需要调用对应的hook和配置options即可实现类似Twitter的头部折叠效果。
内容的提问来源于stack exchange,提问作者Mehmet Kaplan
相关产品推荐
相关产品推荐

