如果是老项目会发现在新的原生系统上打开,比如模拟器上,总是会先出现一个icon+白色或者黑色背景色,随后出现我们自己的Splash屏幕。国内的设备大部分没有强制使用,所以不影响,不过有其他Splash问题本文也会给出解决方案,比如全屏幕,透明状态栏,避免home(主页)短暂的闪烁,一般是空的Header或者自定义了Header会出现这个问题。
修复双重Splash的思路关于双重启动Splash可以参考安卓官方发布:将启动画面实现迁移到 Android 12 及更高版本,由于Expo53以前使用的还是老的自定义Activity作为Splash启动,所以加上新SDK的默认Splash就出现两次Splash。新的API不再使用Activity,而是由系统接管,我们只需要配置style即可,也能更好的适配夜间模式切换。
如果你的项目暂时不考虑大版本跨度升级,我们可以想办法配置系统的启动画面为透明状态,这样可以做到无缝过渡到自定义Splash的状态。有一个其他的方案就是将系统Splash配置设置和自定义的一样,但是这里有个问题就是:如过你的自定义是个广告屏幕或者不是纯色,就很麻烦。比如渐变色的,这个时候状态栏就会很不和谐,很突兀(后面会给出代码,让状态栏后面能够渲染Splash。既然方向确定了,开始写代码。
非Expo项目如果你是原生的ReactNative项目,在你的android文件目录,打开如下文件编辑:
src…..res….values…
xml
代码语言:javascript复制
设置好Styles后我们要去改系统的默认启动Splash颜色
xml
代码语言:javascript复制
Expo Prebuild项目 & Expo Bare项目如果你是Expo的项目,并且使用了Prebuild,那么需要按照上面RN原生方案改的基础上再修改如下配置,因为Expo Prebuild后会按照app.json配置生成Android目录配置文件,如果你没设置,则是默认的:
xml
代码语言:javascript复制
由于我们在上面已经将系统Splash设置了透明,所以启动后会无缝过渡到自定义的Splash,同时设置“translucent”,实现FullScreen。如果你使用Expo的app.json配置,有个很可惜的配置项就是Splash背景色不支持设置android的透明格式,Eas会报错,所以Bare工作流需要使用下面的插件自动替换修复这个色值。
在App.config.js or app.json
json
代码语言:javascript复制 {
"expo":{
/// ...
"android":{
"statusbar": {
"barStyle": "dark-content",//黑色文字
"translucent": true,//zindex层级:支持Splash在下面,等效上面的values/xml配置
}
}
}
}为了方面Bare流的开发,我写了一个插件在构建打包的时候同步修改更新,使用这个插件后,不再需要修改prebuild后的文件,也不需要Android目录:
js
代码语言:javascript复制// expo-plugin-transparent-statusbar.js
const {
withAndroidStyles,
AndroidConfig,
withStringsXml,
} = require("@expo/config-plugins");
const { Styles, Strings } = AndroidConfig;
function withTransparentStatusBar(config) {
// 修改 styles.xml
config = withAndroidStyles(config, (config) => {
let styles = config.modResults;
// 覆盖 AppTheme 中已有的 statusBarColor
styles = Styles.assignStylesValue(styles, {
add: true,
parent: { name: "AppTheme" },
name: "android:statusBarColor",
value: "@android:color/transparent",
});
// 添加 Theme.App.SplashScreen 中的 windowIsTranslucent
styles = Styles.assignStylesValue(styles, {
add: true,
parent: { name: "Theme.App.SplashScreen" },
name: "android:windowIsTranslucent",
value: "true",
});
// 添加 Theme.App.SplashScreen 中的 windowLightStatusBar
styles = Styles.assignStylesValue(styles, {
add: true,
parent: { name: "Theme.App.SplashScreen" },
name: "android:windowLightStatusBar",
value: "true",
});
config.modResults = styles;
return config;
});
// 修改 strings.xml
config = withStringsXml(config, (config) => {
config.modResults = Strings.setStringItem(
[
{
$: {
name: "expo_splash_screen_status_bar_translucent",
translatable: "false",
},
_: "true",
},
],
config.modResults,
);
return config;
});
return config;
}
module.exports = withTransparentStatusBar;插件用法和其他expo插件一样的写法
json
代码语言:javascript复制// app.json > expo > plugins
plugins: [
//...
"./fix-transparent-statusbar.js", //处理android Splash 问题
]修复导航头Header/自定义Header闪烁这个问题的解决其实很取巧,不需要代码演示,其实闪烁的原因就是因为Splash过快关闭,在计算自定义的Header高度或者隐藏header的时候有个延迟,只需要将Splash延迟关闭500ms-600ms即可。
本文章著作权归作者所有,任何形式的转载都请注明出处。