在不使用 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.png
和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
来重建您的应用程序
【讨论】:
【参考方案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/>
</>
)
您的<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
根据您的需要调整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>
);
在<Loading />
做任何你想做的事
【讨论】:
以上是关于在不使用 3rd 方库的情况下,在反应本机中显示主屏幕之前显示启动屏幕的主要内容,如果未能解决你的问题,请参考以下文章
如何在不使用 3rd-party API 的情况下用 C# 压缩文件?