使用 Expo Assets 预加载资源

问题描述 投票:0回答:1

我试图在渲染主布局之前预加载图像,但我仍然看到图像背景的闪烁,我已将其设置为红色以进行调试。这是我的代码。

function RootLayout() {
  const colorScheme = useColorScheme();
  const { user, userLoading } = useAuth();
  const { languageLoading, getStoredLanguage } = useLanguage();
  const { cityLoading, getStoredCity } = useCity();
  const [assetsLoading, setAssetsLoading] = useState(true);

  useEffect(() => {
    const loadAssets = async () => {
      try {
        await Asset.loadAsync([require("./assets/images/onboard.jpg")]);
      } catch (error) {
        console.error(error);
      } finally {
        setAssetsLoading(false);
      }
    };
    loadAssets();
  }, []);

  function initializeLayout() {
    Promise.all([getStoredLanguage(), getStoredCity()]).catch((error) => {
      console.log(error);
    });
  }

  useEffect(() => {
    initializeLayout();
  }, []);

  if (userLoading || languageLoading || cityLoading || assetsLoading) {
    return <Splash />;
  }

  return (
    <NavigationContainer theme={colorScheme === "light" ? DefaultTheme : DarkTheme}>
      {user ? <SignedInLayout /> : <AuthLayout />}
    </NavigationContainer>
  );
}

RootLayout 在其他提供程序之间的 App 组件中呈现。

这是我的 AuthLayout 屏幕;

return (
    <View style={{ flex: 1, paddingBottom: insets.bottom }}>
      <ImageBackground
        source={require("../../../assets/images/onboard.jpg")}
        style={{ flex: 1, backgroundColor: "red" }}
        contentFit="cover"
      /> ...
javascript react-native expo
1个回答
0
投票

您实际上并没有使用预加载的值;

Asset.loadAsync
返回预加载的值,您永远不会访问它。您需要将此值存储在状态中并将其传递给 AuthLayout。
useAssets
钩子为您处理此状态创建:

function RootLayout() {
  const colorScheme = useColorScheme();
  const { user, userLoading } = useAuth();
  const { languageLoading, getStoredLanguage } = useLanguage();
  const { cityLoading, getStoredCity } = useCity();
  const [assets, error] = useAssets([require("./assets/images/onboard.jpg")]
  // if there's no error and no assets then assets are loading
  const assetsLoading = !error && Boolean(assets)


  function initializeLayout() {
    Promise.all([getStoredLanguage(), getStoredCity()]).catch((error) => {
      console.log(error);
    });
  }

  useEffect(() => {
    initializeLayout();
  }, []);

  if (userLoading || languageLoading || cityLoading || assetsLoading) {
    return <Splash />;
  }

  return (
    <NavigationContainer theme={colorScheme === "light" ? DefaultTheme : DarkTheme}>
      {user ? <SignedInLayout /> : <AuthLayout backgroundImage={assets[0].localUri}/>}
    </NavigationContainer>
  );
}

验证布局:

return (
    <View style={{ flex: 1, paddingBottom: insets.bottom }}>
      <ImageBackground
        source={backgroundImage}
        style={{ flex: 1, backgroundColor: "red" }}
        contentFit="cover"
      /> ...
© www.soinside.com 2019 - 2024. All rights reserved.