在显示主屏幕之前显示启动画面以反应原生而不使用第三方库

时间:2017-09-18 06:43:34

标签: react-native react-navigation

我是初学者,因为我的问题似乎对所有专家都很愚蠢。

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

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

我已尝试按照文档应用某些代码,但我的代码出错了,请看看并帮助我。

以下是我的代码:

Index.android.js


    /**
     * Sample React Native App
     * https://github.com/facebook/react-native
     * @flow
     */

    import React, { Component } from 'react';
    import {
      AppRegistry,
      StyleSheet,
      Text,
      View,
      Navigator
    } from 'react-native';
    import Splash from './Splash';
    import Login from './Login';

    export default class DigitalReceipt extends Component {
      render() {
        return (
           {
            if (route.sceneConfig) {
              return route.sceneConfig;
            }
            return Navigator.SceneConfigs.FloatFromRight;
          }} />
        );
      }
      renderScene(route, navigator) {
        var routeId = route.id;
        if (routeId === 'Splash') {
          return (
            
          );
        }
        if (routeId === 'Login') {
          return (
            
          );
        }
        return this.noRoute(navigator);

      }
    }

    const styles = StyleSheet.create({
      container: {
        flex: 1,
        justifyContent: 'center',
        alignItems: 'center',
        backgroundColor: '#F5FCFF',
      },
      welcome: {
        fontSize: 20,
        textAlign: 'center',
        margin: 10,
      },
      instructions: {
        textAlign: 'center',
        color: '#333333',
        marginBottom: 5,
      },
    });

    AppRegistry.registerComponent('DigitalReceipt', () => DigitalReceipt);

Splash.js


    import React, { Component } from 'react';
    import { 
        AppRegistry,
        View,
        Text,
        StyleSheet,
        Image
    } from 'react-native';
    import { StackNavigator } from 'react-navigation';
    import Login from './Login';

    class Splash extends Component{
        componentWillMount() {
            var navigator = this.props.navigator;
            setTimeout(() => {
                navigate('Login')
            }, 1000);
          }

        render(){
            const { navigate } = this.props.navigation;
            return (
                
                     
                         
                        Digital Receipt  
                    
                    
                        Powered by React Native  
                     
                
            );
        }
    }
    const SplashApp = StackNavigator({
        Login: { screen: Login },
        Splash: { screen: Splash },
      });

    const styles = StyleSheet.create({
        wrapper: {
            backgroundColor: '#FFFFFF',
            flex: 1,
            justifyContent: 'center',
            alignItems: 'center'
        },
        title: {
            color: '#2ea9d3',
            fontSize: 32,
            fontWeight: 'bold'
        },
        subtitle:{
            color: '#2ea9d3',
            fontWeight: '200',
            paddingBottom: 20
        },
        titleWrapper:{
            flex: 1,
            justifyContent: 'center',
            alignItems: 'center'
        },

        logo:{
            width: 96,
            height: 96
        }
    });

    AppRegistry.registerComponent('SplashApp', () => SplashApp);

Login.js


    import React, { Component } from 'react';
    import { 
        AppRegistry,
        View,
        Text,
        StyleSheet,
        Image
    } from 'react-native';
    import { StackNavigator } from 'react-navigation';
    import Splash from './Splash';

    class Login extends Component{
        static navigationOptions = {
            title: 'Welcome',
          };
        render(){
            const { navigate } = this.props.navigation;
            return (
                
                    
                        Login Screen  
                     
                
            );
        }

    }
    const LoginApp = StackNavigator({
        Login: { screen: Login },
        Splash: { screen: Splash },
      });
    const styles = StyleSheet.create({
        wrapper: {
            backgroundColor: '#FFFFFF',
            flex: 1,
            justifyContent: 'center',
            alignItems: 'center'
        },
        title: {
            color: '#2ea9d3',
            fontSize: 32,
            fontWeight: 'bold'
        }
    });
    AppRegistry.registerComponent('LoginApp', () => LoginApp);

enter image description here

enter image description here

请帮助我,对不起代码中的愚蠢错误。

由于

6 个答案:

答案 0 :(得分:14)

您可以尝试这个例子。在启动画面中不需要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/>;
    }
}

答案 1 :(得分:2)

您可以随时使用本地方式:

Fisrt您需要用于在不同设备上显示启动画面的图像:

  • LDPI:
    • 肖像:200x320px
    • 风景:320x200px
  • MDPI:
    • 肖像:320x480px
    • 风景:480x320px
  • HDPI:
    • 肖像:480x800px
    • 风景:800x480px
  • XHDPI:
    • 肖像:720px1280px
    • 风景:1280x720px
  • XXHDPI:
    • 肖像:960px1600px
    • 风景:1600x960px
  • XXXHDPI:
    • 肖像:1280px1920px
    • 风景:1920x1280px

它们需要为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

答案 2 :(得分:1)

在反应中制作启动画面的正确方法是修改根路径。 Firstable你需要为你的应用程序创建图像。您可以通过在网站https://apetools.webprofusion.com/app/#/中上传图片来快速完成此操作,在该网站中它将创建一个包含iOs,windows和amp;的所有图像的包文件。 android并将它们放在每个设备的文件夹中。您需要将这些文件夹复制到每个设备的路径,以防您创建任何文件夹,替换它。 路线 {device}/app/src/main/res/{folder-name}

在路线{device}/app/src/main/res/drawable的可绘制文件夹中,您将拥有icon.png&amp; screen.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

中运行来重建您的应用

答案 3 :(得分:0)

只需遵循以下简单代码即可。

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;

希望这会有所帮助:)

答案 4 :(得分:0)

这就是我的方法:

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

    return (
       <>
          <SafeAreaView style={{ flex: 1 }}>
             <StatusBar/>
             <Navigator/>
          </SafeAreaView>
    
          <SplashScreen/>
       </>
    )
    
  2. 您的<SplashScreen />可能类似于:

    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
    
  3. 根据需要调整Animation params, backgroundColor, Image, Text

答案 5 :(得分:0)

function App() {
  const [isloading, setisloading] = useState(true);

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

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

<Loading />中做任何你想做的事情