reactjs React原生&博览会,如何控制启动画面?

epggiuax  于 2023-01-17  发布在  React
关注(0)|答案(2)|浏览(169)

我在expo中使用了内置的闪屏,你在app.json中添加了这个闪屏作为一个简单的测试应用,但是我注意到我的开始屏幕在默认模式下 Flink 了1毫秒,然后才显示我用AsyncStorage添加的资产。
我试过使用expo中的splash-screen包,但是我发现它有点混乱。有没有一种相当简单的方法可以在我的App.js中添加以下逻辑:
显示一个闪屏,当所有资产都加载后,加载这个设置(使用我的上下文和屏幕),或者只是增加从expo中加载闪屏的时间(因为我假设它加载的是正在获取的资产?)

const App = () => {

  const [selectedTheme, setSelectedTheme] = useState(themes.light)

  const changeTheme = async () =>{
    try {
      const theme = await AsyncStorage.getItem("MyTheme")
      if (theme === "dark"){
      setSelectedTheme(themes.nightSky)} 
      else if (theme === "light") {
        setSelectedTheme(themes.arctic)
        }
    } catch (err) {alert(err)}
  }
  
  useEffect(()=> {
    changeTheme()
  },[])

  return (
    <ThemeContext.Provider value={{selectedTheme, changeTheme}}>
         <NavigationContainer>
            <Stack.Navigator screenOptions={{headerShown:false, presentation: 'modal'}}>
              <Stack.Screen name="Home" component={home}/>
            </Stack.Navigator>
          </NavigationContainer>
    </ThemeContext.Provider>

  );
};
k97glaaz

k97glaaz1#

第一种溶液

您可以使用Expo中的SplashScreen模块。下面是如何使用它的概述:

expo install expo-splash-screen
import * as SplashScreen from "expo-splash-screen";
import React, { useCallback, useEffect, useState } from "react";
import { Text, View } from "react-native";

export default function App() {
  const [appIsReady, setAppIsReady] = useState(false);

  useEffect(() => {
    async function prepare() {
      // Keep the splash screen visible
      await SplashScreen.preventAutoHideAsync();
      // Do what you need before the splash screen gets hidden
      console.log("I'm a task that gets executed before splash screen disappears");
      // Then tell the application to render
      setAppIsReady(true);
    }
    prepare();
  }, []);

  const onLayoutRootView = useCallback(async () => {
    if (appIsReady) {
      // Hide the splash screen
      await SplashScreen.hideAsync();
    }
  }, [appIsReady]);

  if (!appIsReady) {
    return null;
  }

  return (
    <View onLayout={onLayoutRootView} style={{ flex: 1, justifyContent: "center", alignItems: "center" }}><Text>Hello Word!</Text> </View>
  );
}

第二种溶液

还有Expo中的AppLoading组件,但它似乎已被弃用。但它可以工作,下面是如何使用它的概述:
一个二个一个一个

另一个

以下部分是使用AppLoading回答上述问题的特殊用例。

import AppLoading from "expo-app-loading";
import {View} from "react-native"

const App = () => {

  const [selectedTheme, setSelectedTheme] = useState(themes.light)
  const [isChecking, setIsChecking] = useState(true);

  const changeTheme = async () =>{
    try {
      const theme = await AsyncStorage.getItem("MyTheme")
      if (theme === "dark"){
      setSelectedTheme(themes.nightSky)} 
      else if (theme === "light") {
        setSelectedTheme(themes.arctic)
        }
    } catch (err) {alert(err)}
  }
  
  if (isChecking) {
    return (
      <AppLoading
        startAsync={() =>   changeTheme()}
        onFinish={() => setIsChecking(false)}
        onError={console.warn}
      />
    );
  }
  
  return (
    <ThemeContext.Provider value={{selectedTheme, changeTheme}}>
         <NavigationContainer>
            <Stack.Navigator screenOptions={{headerShown:false, presentation: 'modal'}}>
              <Stack.Screen name="Home" component={home}/>
            </Stack.Navigator>
          </NavigationContainer>
    </ThemeContext.Provider>

  );
};
neskvpey

neskvpey2#

我也遇到过同样的问题,但在我的例子中,我创建了一个带有初始导航屏幕的expo项目。当你用这个设置创建一个项目时,app.tsx文件将包含钩子useCachedResources。

import { StatusBar } from 'expo-status-bar';
import { SafeAreaProvider } from 'react-native-safe-area-context';
import useCachedResources from './src/hooks/useCachedResources';
import Navigation from './src/navigation';
  
export default function App() {
  const isLoadingComplete = useCachedResources();
  if (!isLoadingComplete) {
    return null;
  } else {
    return (
      <SafeAreaProvider>
        <Navigation />
        <StatusBar />
      </SafeAreaProvider>
    );
  }
}

当检查钩子时,我们可以看到有一段代码在加载字体时保持启动画面,所以我们只需要在SplashScreen.hideAsync()之前的finally块上添加超时。

import { FontAwesome } from '@expo/vector-icons';
import * as Font from 'expo-font';
import * as SplashScreen from 'expo-splash-screen';
import { useEffect, useState } from 'react';

SplashScreen.preventAutoHideAsync();

export default function useCachedResources() {
  const [isLoadingComplete, setLoadingComplete] = useState(false);
  useEffect(() => {
    async function loadResourcesAndDataAsync() {
      try {
        await Font.loadAsync({
          ...FontAwesome.font,
          'space-mono': require('../assets/fonts/SpaceMono-Regular.ttf'),
        });
      } catch (e) {
        console.warn(e);
      } finally {
        await new Promise(resolve => setTimeout(resolve, 2000));
        setLoadingComplete(true);
        SplashScreen.hideAsync();
      }
    }
    loadResourcesAndDataAsync();
  }, []);
  return isLoadingComplete;
}

相关问题