React Native导航栏遮挡动画:如何让动画显示在导航栏上方?
解决React Native动画显示在导航栏下方的问题
我懂你遇到的困扰——想让小球动画显示在导航标题栏上方,但调了zIndex也没效果,它还是稳稳待在标题栏下面。这其实是React Native StackNavigator的层级机制导致的:导航栏和屏幕内容属于不同的容器层级,默认导航栏的层级更高,所以你在屏幕组件里设置的zIndex根本影响不到它。
下面给你两种实用的解决方案:
方案一:自定义导航栏,把动画整合到Header里
既然导航栏层级更高,那直接把动画放到导航栏组件里就好了。修改你的FourthScreen代码,自定义navigationOptions的header部分:
import React, { Component } from 'react'; import {Text, Animated, View, StyleSheet} from "react-native"; class FourthScreen extends Component { constructor(props) { super(props); this.position = new Animated.ValueXY(0,0); } static navigationOptions = ({ navigation }) => { // 获取组件实例传递的动画对象 const position = navigation.getParam('position'); return { header: () => ( <View style={styles.headerContainer}> <Text style={styles.headerTitle}>Screen Title</Text> {/* 将动画嵌入导航栏 */} <Animated.View style={position ? position.getLayout() : {}}> <View style= {styles.ball} /> </Animated.View> </View> ) } } componentDidMount() { // 把动画对象传递给导航参数 this.props.navigation.setParams({ position: this.position }); Animated.spring(this.position, { toValue: {x: 0, y: -50} }).start(); } render() { return ( <View style={styles.screenContainer}> {/* 这里放你的屏幕内容 */} </View> ); } } const styles = StyleSheet.create({ headerContainer: { height: 60, justifyContent: 'center', alignItems: 'center', backgroundColor: '#fff', position: 'relative', }, headerTitle: { fontSize: 18, fontWeight: 'bold', }, ball: { height: 60, width: 60, borderRadius: 30, borderWidth: 30, borderColor: "black", position: "absolute", top: 0, left: '50%', marginLeft: -30, }, screenContainer: { flex: 1, justifyContent: 'center', alignItems: 'center', } }) export default FourthScreen;
这个方法的核心是让动画元素直接属于导航栏的一部分,自然就能显示在标题上方。
方案二:设置导航栏透明,让屏幕内容覆盖上去
另一种思路是把导航栏设为透明,让屏幕内容延伸到导航栏下方,这时zIndex就能生效了:
import React, { Component } from 'react'; import {Text, Animated, View, StyleSheet} from "react-native"; class FourthScreen extends Component { static navigationOptions = { title: "Screen Title", headerTitleStyle: { textAlign: "center", flex: 1 }, headerTransparent: true, // 关键:开启导航栏透明 } constructor(props) { super(props); this.position = new Animated.ValueXY(0,0); } componentWillMount(){ // 调整y值,让动画初始位置落在导航栏区域 Animated.spring(this.position, { toValue: {x: 0, y: 20} }).start(); } render() { return ( <View style={styles.screenContainer}> <Animated.View style={[this.position.getLayout(), {zIndex: 100, position: 'absolute'}]}> <View style= {styles.ball} /> </Animated.View> {/* 这里放你的屏幕内容 */} </View> ); } } const styles = StyleSheet.create({ ball: { height: 60, width: 60, borderRadius: 30, borderWidth: 30, borderColor: "black", }, screenContainer: { flex: 1, paddingTop: 60, // 给内容加padding,避免被导航栏遮挡 justifyContent: 'center', alignItems: 'center', } }) export default FourthScreen;
headerTransparent: true会让导航栏变成透明,同时屏幕内容会从屏幕顶部开始渲染,这时候给动画设置zIndex:100就能覆盖在透明导航栏上方了。记得给屏幕内容加paddingTop,不然内容会被导航栏挡住。
为什么之前的zIndex无效?
StackNavigator的导航栏是在独立的容器中,这个容器的默认层级比屏幕内容容器高,所以你在屏幕组件里设置再高的zIndex也突破不了这个层级限制,必须用上面两种方法之一来解决。
内容的提问来源于stack exchange,提问作者Sabin Bogati
相关产品推荐
相关产品推荐

