问题背景

在Taro + react-native应用进行鸿蒙化上架时,AppGallery Connect自检发现转场动效时长过短,切换帧数仅为1帧,不符合要求。当前项目使用的是react-navigation-tabs创建的BottomTabNavigator,页面跳转缺乏动画效果。

在这里插入图片描述
在这里插入图片描述

原本使用的库是react-navigation 4.4+版本 以及 react-navigation-tabs 2.11版本

路由结构:

import { createAppContainer } from 'react-navigation';
import { createBottomTabNavigator } from 'react-navigation-tabs';

const TabNavigator = createBottomTabNavigator(
	{
		one:{},
		two:{}
		...
		//底部路由
	},
	{
		tabBarOptions: {} //路由配置项
	}
)


const AppContainer = createAppContainer(TabNavigator)
export { AppContainer as BottomNavigator }

解决方案

升级react-navigation至7+版本

由于react-navigation 4+的API在react-native-harmony框架中动画属性可能无法直接生效,建议将react-navigation升级到7+版本。7+版本对动画支持更完善,且提供了更灵活的配置选项。

npm install @react-navigation/native@7.x @react-navigation/stack@7.x @react-navigation/bottom-tabs@7.x
使用StackNavigator包裹BottomTabNavigator

为了在BottomTabNavigator中启用动画效果,可以通过StackNavigator包裹BottomTabNavigator的方式实现。这样可以在StackNavigator中配置页面切换动画。

import { createStackNavigator } from '@react-navigation/stack';
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
import { NavigationContainer } from '@react-navigation/native'

const Tab = createBottomTabNavigator();
const Stack = createStackNavigator();

function TabNavigator() {
  return (
    <Tab.Navigator>
      <Tab.Screen 
      	name="Home" 
      	component={HomeScreen} 
		options={{
          tabBarLabel: 'Home',
          transitionSpec: {
            animation: 'timing', //设置动画类型
            config: {
              duration: 300,  //设置动画时长
              easing: Easing.inOut(Easing.ease) //设置动画效果
            }
          },
        }}
		/>
      <Tab.Screen name="Settings" component={SettingsScreen} />
    </Tab.Navigator>
  );
}

export default function BottomNavigator() {
  return (
  	<NavigationContainer>
     <Stack.Navigator
        screenOptions={{
          headerShown: true,
          ...customSlideAnimation, // 应用自定义动画
          gestureEnabled: true, // 启用手势返回
          presentation: 'card', // 使用卡片式过渡
          detachPreviousScreen: false, // 保持前一个屏幕的状态
        }}
      >
        <Stack.Screen name="MainTabs" component={TabNavigatorComponent} options={{ headerShown: false }} />
        {dynamicRoutes.map((route) => (
          <Stack.Screen
            key={route.name}
            name={route.name}
            getComponent={route.path}
            options={route.options}
          />
        ))}
      </Stack.Navigator>
     </NavigationContainer>
  );
}
配置动画属性

createBottomTabNavigator()创建的容器里的的Tab.screen中,可以通过options里的transitionSpec属性配置动画时长和效果。设置duration为300ms,确保动画符合要求。

transitionSpec: {
    animation: 'timing', //设置动画类型
    config: {
      duration: 300,  //设置动画时长
      easing: Easing.inOut(Easing.ease) //设置动画效果
    }
},
验证动画效果

完成配置后,运行应用并检查页面切换时的动画效果。确保动画时长和帧数符合AppGallery Connect的要求。可以通过调试工具或录屏功能验证动画是否流畅。

其他问题
1.

当我从tab页面我的跳转到子页面A,从子页面A跳转到子页面B,再从B->A->我的的时候,发现设置的active样式和返回的页面不对,回到了职位页面

是因为Stack.Navigator里没有设置detachPreviousScreen属性为false,需要设置这个属性为false来保持前一个屏幕的状态
在这里插入图片描述

2.

页面一般都是比较多的,这里可以维护一个dynamicRoutes数组来进行动态渲染

export const dynamicRoutes = [
    { name: 'Index' , options:{ headerShown: false }, path: () => require('../pages/index/index').default },
    { name: 'Home' , options:{ headerShown: false }, path: () => require('../pages/home/index').default },
    ...//其他路由
]

注意事项

  • 升级react-navigation时,需检查项目中其他依赖是否兼容7+版本。
  • 如果项目中使用了自定义过渡动画,需根据新版本的API进行调整。
  • 在鸿蒙环境下,部分动画效果可能需要额外适配,建议在真机上进行测试。
Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐