在不使用 3rd 方库的情况下,在反应本机中显示主屏幕之前显示启动屏幕

Posted

技术标签:

【中文标题】在不使用 3rd 方库的情况下,在反应本机中显示主屏幕之前显示启动屏幕【英文标题】:Show splash screen before show main screen in react native without using 3rd party library 【发布时间】:2018-02-26 14:56:39 【问题描述】:

我是 react native 的初学者,所以也许我的问题对所有专家来说都是愚蠢的。

但我正在努力实现一个我想要实现的基本功能,我想用启动屏幕启动我的应用程序,几秒钟后我想显示登录屏幕或主屏幕。

我检查了一些示例,但没有找到任何包含完整代码的示例,因此不知道如何在我的应用中使用这些代码 sn-ps。

我已尝试根据文档应用一些代码,但我的代码出错,请查看并帮助我。

下面是我的代码:

Index.android.js

/** * 示例 React Native 应用程序 * https://github.com/facebook/react-native * @流动 */ 从'react'导入反应,组件; 进口 应用注册, 样式表, 文本, 看法, 航海家 来自 'react-native'; 从'./Splash'导入Splash; 从'./Login'导入登录; 导出默认类 DigitalReceipt 扩展组件 使成为() 返回 ( if (route.sceneConfig) 返回 route.sceneConfig; 返回 Navigator.SceneConfigs.FloatFromRight; /> ); 渲染场景(路线,导航器) var routeId = route.id; if (routeId === 'Splash') 返回 ( ); if (routeId === '登录') 返回 ( ); 返回 this.noRoute(navigator); 常量样式 = StyleSheet.create( 容器: 弹性:1, justifyContent: '中心', alignItems:'中心', 背景颜色:'#F5FCFF', , 欢迎: 字体大小:20, textAlign: '居中', 边距:10, , 指示: textAlign: '居中', 颜色:'#333333', 边距底部:5, , ); AppRegistry.registerComponent('DigitalReceipt', () => DigitalReceipt);

Splash.js

从'react'导入反应,组件; 进口 应用注册, 看法, 文本, 样式表, 图片 来自 'react-native'; 从“反应导航”导入 StackNavigator ; 从'./Login'导入登录; 类飞溅扩展组件 组件WillMount() var navigator = this.props.navigator; 设置超时(()=> 导航('登录') , 1000); 使成为() 常量 导航 = this.props.navigation; 返回 ( 数字收据 由 React Native 提供支持 ); 常量 SplashApp = StackNavigator( 登录:屏幕:登录, 飞溅:屏幕:飞溅, ); 常量样式 = StyleSheet.create( 包装: 背景颜色:'#FFFFFF', 弹性:1, justifyContent: '中心', alignItems:'中心' , 标题: 颜色:'#2ea9d3', 字体大小:32, 字体重量:'粗体' , 字幕: 颜色:'#2ea9d3', 字体重量:'200', paddingBottom: 20 , 标题包装器: 弹性:1, justifyContent: '中心', alignItems:'中心' , 商标: 宽度:96, 身高:96 ); AppRegistry.registerComponent('SplashApp', () => SplashApp);

Login.js

从'react'导入反应,组件; 进口 应用注册, 看法, 文本, 样式表, 图片 来自 'react-native'; 从“反应导航”导入 StackNavigator ; 从'./Splash'导入Splash; 类登录扩展组件 静态导航选项 = 标题:“欢迎”, ; 使成为() 常量 导航 = this.props.navigation; 返回 ( 登录屏幕 ); const LoginApp = StackNavigator( 登录:屏幕:登录, 飞溅:屏幕:飞溅, ); 常量样式 = StyleSheet.create( 包装: 背景颜色:'#FFFFFF', 弹性:1, justifyContent: '中心', alignItems:'中心' , 标题: 颜色:'#2ea9d3', 字体大小:32, 字体重量:'粗体' ); AppRegistry.registerComponent('LoginApp', () => LoginApp);

请帮助我,如果您发现任何代码中的愚蠢错误,请见谅。

谢谢

【问题讨论】:

您不需要每次都在 stacknavigator 中声明屏幕,并且您甚至在创建它之前就访问了启动路径。不注册登录界面,默认导出即可。您正在混合导航器和堆栈导航器,两者都是不同的 您好,感谢您的回复。你能告诉我我需要在哪里声明屏幕,以及我应该使用什么来满足我的要求、导航器或堆栈导航器吗? Stack navigator 非常好用且易于使用。首先制作您的应用程序的流程,然后逐步进行。首先创建一个只有堆栈导航器屏幕声明的文件。将第一条路线作为启动。基于登录的启动后,您可以转到登录或主屏幕 感谢您的指导,让我尝试一下并实现它 只需添加 module.exports = SplashScreen;在启动画面类的底部。 【参考方案1】:

你可以试试这个例子。启动画面中不需要 stacknavigator

constructor(props)
    super(props);
    this.state = 
        timePassed: false,
    ;


componentDidMount() 
    setTimeout( () => 
        this.setTimePassed();
    ,1000);


setTimePassed() 
    this.setState(timePassed: true);


render() 
    if (!this.state.timePassed) 
        return <SplashScreen/>;
     else 
        return <Login/>;
    

【讨论】:

这是最简单的方法,您可以保留一个指示加载过程结束的变量,然后显示原始屏幕。确保使用 setState,因为它会重新渲染视图。可用加载器 - github.com/joinspontaneous/react-native-loading-spinner-overlay【参考方案2】:

你总是可以用原生方式来做:

首先,您需要在不同设备上显示启动画面的图像:

低密度脂蛋白: 纵向:200x320 像素 横向:320x200px MDPI: 纵向:320x480 像素 横向:480x320px HDPI: 纵向:480x800 像素 横向:800x480 像素 XHDPI: 纵向:720px1280px 横向:1280x720px XXHDPI: 纵向:960px1600px 横向:1600x960 像素 XXXHDPI: 纵向:1280px1920px 横向:1920x1280 像素

它们需要是png 格式,然后将它们放在android/app/src/main/res/drawable 并创建一个以每个图像的分辨率命名的文件夹。例如:drawable/drawable-hdpi

然后在drawable文件夹中创建一个名为background_splash.xml的文件并放入如下内容:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">

    <item>
        <bitmap
            android:gravity="fill"
            android:src="@drawable/screen"/>
    </item>
</selector>

之后你必须在android/app/res/values/styles.xml中添加一个新样式

<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <!-- Customize your theme here. -->
    </style>

    <style name="SplashTheme" parent="Theme.AppCompat.NoActionBar">
        <item name="android:windowBackground">@drawable/background_splash</item>
    </style>

</resources>

更新您的AndroidManifest.xml 文件,添加一个名为SplashActivity 的新活动并添加android:theme="@style/SplashTheme"。现在创建一个名为MainActibity 的空活动。你的AndroidManifest.xml 应该是这样的:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.exampleapp"
    android:versionCode="1"
    android:versionName="1.0">

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>

    <uses-sdk
        android:minSdkVersion="23"
        android:targetSdkVersion="26" />

    <application
      android:name=".MainApplication"
      android:allowBackup="true"
      android:label="@string/app_name"
      android:icon="@mipmap/ic_launcher"
      android:theme="@style/AppTheme">
        <activity
            android:name=".SplashActivity"
            android:label="@string/app_name"
            android:theme="@style/SplashTheme">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".MainActivity" 
            android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
            android:windowSoftInputMode="adjustResize"
            android:exported=”true”
        />
      <activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
    </application>

</manifest>

现在我们需要告诉 SplashActivity 转到 MainActivity,它代表我们的实际应用程序。为此,您需要创建一个名为 SplashActivity 的新 Java 类。

package com.exampleapp; // change to the name of your app.

import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;

public class SplashActivity extends AppCompatActivity 
    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);

        Intent intent = new Intent(this, MainActivity.class);
        startActivity(intent);
        finish();
    

现在您应该会看到一个启动画面。

https://medium.com/handlebar-labs/how-to-add-a-splash-screen-to-a-react-native-app-ios-and-android-30a3cec835ae

【讨论】:

【参考方案3】:

在 react 中制作 Splash Screen 的正确方法是修改根路由。 首先,您需要为您的应用程序创建图像。您可以通过将图像上传到站点https://apetools.webprofusion.com/app/#/ 来快速完成此操作,它将创建一个包含 iO、Windows 和 android 的所有图像的捆绑文件,并将它们放在每个设备的文件夹中。您需要将这些文件夹复制到每个设备的路由中,如果您创建了任何文件夹,请将其替换。 路线 device/app/src/main/res/folder-name

在路由device/app/src/main/res/drawable 的drawable 文件夹中,您将拥有icon.pngscreen.png 并创建一个名为

splash_background.xml 在这个文件中添加下一个文本

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
  <item>
    <bitmap
      android:gravity="fill"
      android:src="@drawable/screen"
    />
  </item>
</selector>

在路由device/app/src/main/java/com/name-of-project添加一个名为SplashActivity.java的文件

在这个文件SplashActivity.java添加下一个:

package com.prework;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;

public class SplashActivity extends AppCompatActivity 
  @Override
  protected void onCreate(Bundle savedInstanceState) 
    super.onCreate(savedInstanceState);

    Intent intent = new Intent(this, MainActivity.class);
    startActivity(intent);
    finish();
  

device/app/src/main/res/values/styles.xml路由中修改如下:

<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <!-- Customize your theme here. -->
    </style>
    <style name="SplashTheme" parent="Theme.AppCompat.NoActionBar">
        <item name="android:windowBackground">@drawable/splash_background</item>
    </style>

</resources>

并在device/app/src/main/res/AndroidManifest.xml 的路线中更改如下

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.prework">

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>

    <application
      android:name=".MainApplication"
      android:label="@string/app_name"
      android:icon="@drawable/icon"
      android:allowBackup="false"
      android:theme="@style/AppTheme">

      <activity
        android:name=".SplashActivity"
        android:label="@string/app_name"
        android:theme="@style/SplashTheme"
        android:configChanges="keyboard|keyboardHidden|orientation|screenSize">

        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
      </activity>

      <activity
        android:name=".MainActivity"
        android:label="@string/app_name"
        android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
        android:windowSoftInputMode="adjustResize">
      </activity>

      <activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
    </application>

</manifest>

现在通过在命令行中运行 react-native run-android 来重建您的应用程序

【讨论】:

【参考方案4】:

只需遵循这个简单的代码。

App.js

import  createStackNavigator,createAppContainer  from "react- 
navigation";
import Splash from "./Controller/Splash";
import Login from "./Controller/Login";
import Register from "./Controller/Register";

 const Navigator = createStackNavigator (
 main:  screen: Splash ,
 LoginScreen:  screen : Login ,
 );

const AppNavigator = createAppContainer(Navigator);

  export default class App extends Component 
  render() 
  return <AppNavigator />;
  
 

Splash.js

import React,  Component  from "react";
import View, Text  from "react-native";

export class Splash extends Component 

 componentDidMount() 
    setTimeout(() => 
       this.load();
          , 4000);
    

   load = () => 
        this.props.navigation.push("LoginScreen");
    ;

    render() 
        return (
     <View >
       <Text style=styles.myText>Splash Screen</Text>
  </View>
  );
 

 export default Splash;

希望这会有所帮助:)

【讨论】:

【参考方案5】:

我就是这样做的:

    为您的初始屏幕创建一个组件并将其放置在 App.js 的底部,例如:

    return (
       <>
          <SafeAreaView style= flex: 1 >
             <StatusBar/>
             <Navigator/>
          </SafeAreaView>
    
          <SplashScreen/>
       </>
    )
    

    您的&lt;SplashScreen /&gt; 可以是:

    import React,  useEffect, useState  from 'react'
    import  Image, StatusBar, Text, Animated  from 'react-native'
    
    const SplashScreen = ( ) => 
       const [done, setdone] = useState(false)
       const animationOpacity = React.useRef(new Animated.Value(1)).current
       const animationScale = React.useRef(new Animated.Value(1)).current
    
       if (done) return null
    
       function hideAnimation() 
            Animated.parallel([
                Animated.timing(animationOpacity, 
                   toValue: 0,
                   delay: 1000,
                   duration: 400,
                   useNativeDriver: true
               ),
               Animated.timing(animationScale, 
                   toValue: 10,
                   delay: 1000,
                   duration: 400,
                   useNativeDriver: true
               )
            ]).start(() => setdone(true))
        
    
        hideAnimation()
    
        return (
            <Animated.View style=
                backgroundColor: 'black',
                ...StyleSheet.absoluteFill,
                justifyContent: 'center',
                alignItems: 'center',
                opacity: animationOpacity,
            >
    
                <StatusBar
                    backgroundColor=COLOR.PRIMARY
                    barStyle='light-content'
                />
    
                <Animated.View 
                    style=
                        justifyContent: 'center',
                        alignItems: 'center',
                        opacity: animationOpacity,
                        transform: [ scale: animationScale ]
                    
                >
                    <Image /> // some image or icon
                    <Text>Some text</Text>
                </Animated.View>
    
            </Animated.View>
        )
    
    
    export default SplashScreen
    

    根据您的需要调整Animation params, backgroundColor, Image, Text

【讨论】:

【参考方案6】:
function App() 
  const [isloading, setisloading] = useState(true);

  useEffect(() => 
    setTimeout(() => 
      setisloading(!isloading);
    , 3000);
  , []);

  return (
    <AuthContextProvider>
      <Provider theme=theme>
        <NavigationContainer>
          isloading ? <Loading /> : <Select />
        </NavigationContainer>
      </Provider>
    </AuthContextProvider>
  );

&lt;Loading /&gt;做任何你想做的事

【讨论】:

以上是关于在不使用 3rd 方库的情况下,在反应本机中显示主屏幕之前显示启动屏幕的主要内容,如果未能解决你的问题,请参考以下文章

如何在不使用 3rd-party API 的情况下用 C# 压缩文件?

如何发布使用外部 3rd 方库的 iPhone 应用程序?

带有 3rd 方库的 Grails Asset-Pipeline 系统

请建议 Fiddler Core 3rd 方库的替代方案

QT 未定义对 3rd 方库的引用

Firebase Cloud Messaging 令牌在没有第三方库的情况下本机反应