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

React Native WebView如何设置Splash Image时长解决启动白屏

React Native 闪屏自定义时长+白屏问题修复方案

实现逻辑

核心采用双阶段闪屏承接方案,无需修改原生代码、无需引入第三方依赖:

  • 原生默认闪屏自动消失后,由JS层渲染的、与原生闪屏视觉完全一致的全屏覆盖层立刻承接,完全阻断白屏露出路径
  • 支持自定义闪屏最小展示时长,仅当「WebView页面加载完成」、「达到预设最小闪屏时长」两个条件同时满足时,才隐藏闪屏层展示WebView内容
  • 同步修复原代码中重复声明App组件、未导入View组件、冗余测试代码的语法问题

可配置项

  • 修改MIN_SPLASH_DURATION参数值即可自定义闪屏最短显示时长,单位为毫秒,例如设置为3000即最少显示3秒
  • 将闪屏覆盖层的背景色、图片资源替换为与原生端Splash Image完全一致的资源,即可做到原生闪屏与JS闪屏切换无视觉断层

修正后的完整app.js代码

import React, { useRef, useState, useCallback, useEffect } from "react";
import { BackHandler, Platform, StyleSheet, ActivityIndicator, View, Image } from "react-native";
import { WebView } from "react-native-webview";

// 闪屏最小显示时长(单位:毫秒),按需修改即可
const MIN_SPLASH_DURATION = 2500;
// 替换为项目内实际的闪屏图资源,需和原生端闪屏图保持一致
const SPLASH_IMAGE = require("./splash.png");

export default function App() {
  const webView = useRef();
  // 记录应用启动时间,用于计算闪屏实际显示时长
  const appLaunchTime = useRef(Date.now());
  const [canGoBack, setCanGoBack] = useState(false);
  // 控制闪屏覆盖层的显示状态
  const [splashVisible, setSplashVisible] = useState(true);

  const handleBack = useCallback(() => {
    if (canGoBack && webView.current) {
      webView.current.goBack();
      return true;
    }
    return false;
  }, [canGoBack]);

  useEffect(() => {
    BackHandler.addEventListener("hardwareBackPress", handleBack);
    return () => {
      BackHandler.removeEventListener("hardwareBackPress", handleBack);
    };
  }, [handleBack]);

  // WebView加载完成回调,校验是否满足闪屏隐藏条件
  const handleWebViewLoadEnd = useCallback(() => {
    const currentTime = Date.now();
    const timePassed = currentTime - appLaunchTime.current;
    // 已达到最小显示时长则直接隐藏闪屏,否则等待剩余时长后再隐藏
    if (timePassed >= MIN_SPLASH_DURATION) {
      setSplashVisible(false);
    } else {
      const remainTime = MIN_SPLASH_DURATION - timePassed;
      setTimeout(() => {
        setSplashVisible(false);
      }, remainTime);
    }
  }, []);

  const platformStyles = StyleSheet.create({
    webView: Platform.OS === 'ios' 
      ? { marginTop: 30, marginBottom: 40, flex: 1 }
      : { marginTop: 30, flex: 1 }
  });

  return (
    <View style={styles.rootContainer}>
      <WebView
        ref={webView}
        source={{ uri: "https://www.talesrunnerbestguild.co.kr/" }}
        style = {platformStyles.webView}
        onLoadProgress={(event) => setCanGoBack(event.nativeEvent.canGoBack)}
        onLoadEnd={handleWebViewLoadEnd}
        // 闪屏隐藏前WebView设为全透明,避免渲染过程露白
        opacity={splashVisible ? 0 : 1}
      />
      {/* 自定义闪屏覆盖层 */}
      {splashVisible && (
        <View style={styles.splashContainer}>
          <Image source={SPLASH_IMAGE} style={styles.splashImage} resizeMode="cover" />
          {/* 如需显示加载指示器可放开下方注释,不需要可直接删除 */}
          {/* <ActivityIndicator size="large" color="#0000ff" style={styles.loadingIndicator} /> */}
        </View>
      )}
    </View>
  );
}

const styles = StyleSheet.create({
  rootContainer: {
    flex: 1,
  },
  splashContainer: {
    ...StyleSheet.absoluteFillObject,
    backgroundColor: '#ffffff', // 替换为和原生闪屏一致的背景色
    justifyContent: 'center',
    alignItems: 'center',
    zIndex: 999,
  },
  splashImage: {
    width: '100%',
    height: '100%',
  },
  loadingIndicator: {
    position: 'absolute',
    bottom: 100,
  }
});

使用说明

  • 请将代码中SPLASH_IMAGE的路径替换为项目内实际的闪屏图资源,修改splashContainer的背景色与原生闪屏背景色完全一致,保证切换过程无感知
  • 闪屏显示时长直接修改MIN_SPLASH_DURATION数值即可,例如需要显示5秒则改为5000
  • 不需要加载指示器直接删除对应代码块即可,不影响核心逻辑运行

内容的提问来源于stack exchange,提问作者김준석

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 09:45:38