You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在Expo React Native应用中实现启动页动画遇空白白屏问题

问题描述

在React Native Expo应用中尝试用expo-splash-screen库设置JSON格式的动画作为启动页,但启动后只显示空白白屏,而非预期动画。已确认JSON文件有效、路径正确,且将原GIF转为了JSON格式。

App.js 代码

import 'react-native-gesture-handler';
import React, { useCallback } from 'react'
import { StyleSheet, Text, View } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { MyStack } from './routes/homeStack';
import { useFonts } from 'expo-font';
import * as SplashScreen from 'expo-splash-screen'

export default function App() {

  const [ fontsLoaded ] = useFonts({
    'Sofia-Pro': require('./assets/Sofia_Pro_Regular.otf'),
    'Helvetica-Neue': require('./assets/HelveticaNeue-Medium.otf'),
    'NunitoSans': require('./assets/NunitoSans-Bold.ttf'),
    'LatoRegular': require('./assets/Lato-Regular.ttf')
  })

  const onLayoutRootView = useCallback(async () => {
    if (fontsLoaded) {
      await SplashScreen.preventAutoHideAsync();
      setTimeout(async () => {
        await SplashScreen.hideAsync();
      }, 3000);
    }
  }, [fontsLoaded]);

  if (!fontsLoaded) {
    return null;
  }

  return (
    <NavigationContainer onLayout={onLayoutRootView}>
      <MyStack/>
    </NavigationContainer>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

app.config.js 代码

import "dotenv/config";

export default {
  expo: {
    name: "Gig Fort",
    slug: "gig-fort",
    version: "3.0.0",
    orientation: "portrait",
    icon: "./assets/icon.png",
    userInterfaceStyle: "light",
    splash: {
      image: "./assets/gigFort_splash_animation.json",
      resizeMode: "contain",
      // backgroundColor: "#ffffff",
    },
    updates: {
      fallbackToCacheTimeout: 0,
    },
    assetBundlePatterns: ["**/*"],

    android: {
      googleServicesFile: "./google-services.json",
      icon: "./assets/icon.png",
      package: "******",
      config: {
        googleMaps: {
          apiKey: "******"
        }
      },
      versionCode: 3
    },
    web: {
      favicon: "./assets/favicon.png",
    },
    extra: {
      firebaseApiKey: process.env.FIREBASE_API_KEY,
      eas: {
        projectId: "******",
      },
    },
  },
};
问题排查与解决方案

1. 核心问题:Expo默认启动页不支持JSON动画

Expo的splash配置仅支持静态图片格式(PNG/JPG等),无法直接解析JSON格式的Lottie动画。你把JSON文件填到splash.image里,系统无法识别,自然显示空白。

2. 正确实现Lottie动画启动页的步骤

第一步:安装Lottie依赖

执行命令安装lottie-react-native:

npx expo install lottie-react-native

第二步:修改App.js,手动渲染动画

放弃依赖Expo默认启动页,在字体加载完成前自行渲染Lottie动画:

import 'react-native-gesture-handler';
import React, { useCallback } from 'react'
import { StyleSheet, View } from 'react-native';
import { NavigationContainer } from '@react-navigation/native';
import { MyStack } from './routes/homeStack';
import { useFonts } from 'expo-font';
import * as SplashScreen from 'expo-splash-screen'
import LottieView from 'lottie-react-native';

export default function App() {
  const [fontsLoaded] = useFonts({
    'Sofia-Pro': require('./assets/Sofia_Pro_Regular.otf'),
    'Helvetica-Neue': require('./assets/HelveticaNeue-Medium.otf'),
    'NunitoSans': require('./assets/NunitoSans-Bold.ttf'),
    'LatoRegular': require('./assets/Lato-Regular.ttf')
  });

  // 初始化时阻止启动页自动隐藏
  React.useEffect(() => {
    async function prepare() {
      await SplashScreen.preventAutoHideAsync();
    }
    prepare();
  }, []);

  const onLayoutRootView = useCallback(async () => {
    if (fontsLoaded) {
      setTimeout(async () => {
        await SplashScreen.hideAsync();
      }, 3000);
    }
  }, [fontsLoaded]);

  // 字体未加载时显示Lottie动画
  if (!fontsLoaded) {
    return (
      <View style={styles.splashContainer}>
        <LottieView
          source={require('./assets/gigFort_splash_animation.json')}
          autoPlay
          loop={false}
          resizeMode="contain"
        />
      </View>
    );
  }

  return (
    <NavigationContainer onLayout={onLayoutRootView}>
      <MyStack />
    </NavigationContainer>
  );
}

const styles = StyleSheet.create({
  splashContainer: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

第三步:调整app.config.js的splash配置

把原来的JSON文件换成一张静态占位图(比如动画的第一帧PNG),避免启动初期的短暂空白:

splash: {
  image: "./assets/splash_placeholder.png", // 静态占位图
  resizeMode: "contain",
  backgroundColor: "#ffffff",
},

3. 额外注意事项

  • 确保Lottie的JSON文件是标准Lottie格式,可以用Lottie预览工具验证。
  • 修改配置后重启Expo开发服务器,避免缓存干扰。
  • 如果动画播放异常,检查JSON文件路径是否正确(assetBundlePatterns: ["**/*"]已确保所有资源被打包)。

内容的提问来源于stack exchange,提问作者Josh Simon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 05:57:01