29
loading...
This website collects cookies to deliver better user experience
expo init first-config-plugin -t expo-template-blank-typescript
expo install expo-splash-screen
translucent
so that image can stretch under it.<StatusBar style="dark" translucent backgroundColor="transparent" />
"androidStatusBar": {
"backgroundColor": "#00000000",
"barStyle": "dark-content",
"translucent": true
}
expo run:android
or expo prebuild -p android
we can generate the Android folder with its configurations. If you don't know where the issue is coming from, you can use a simple strategy to see where changes are being made. Just stage all generated Android files (git add -A
), remove translucent: true
from app.json, and run expo prebuild -p android
to generate native files again.- <string name="expo_splash_screen_status_bar_translucent" translatable="false">true</string>
+ <string name="expo_splash_screen_status_bar_translucent" translatable="false">false</string>
- <item name="android:windowTranslucentStatus">true</item>
expo_splash_screen_status_bar_translucent
custom Expo property sounds exactly like something we are trying to influence and being previously true
we saw the status bar was really translucent during the splash screen. We also notice that android:windowTranslucentStatus
was set to true
which with some googling we realize was responsible for the status bar overlay. If you are in managed workflow, in the past you would feel trapped because you can't have one without the other to reach the behavior you wanted and the only option was to raise it in Expo issues. But now thanks to Expo config plugins you can take the solution in your hands.expo_splash_screen_status_bar_translucent
set to true
while keeping android:windowTranslucentStatus
as false
- which is the default therefore lets change only the Expo property. With expo run:android
you can actually change it in your Android native files yourself to prove the effect after a new build. Yet if we want to stay in managed workflow and away from native file changes, we need to write a custom plugin which will do the change for us during the prebuild.This means any native changes through plugins will be reflected in Expo development environment only using expo-dev-client - our custom Expo Go.
@expo/config-plugins
package is already part of Expo, so we don't need to install any new dependency. We will start by creating our plugin file in typescript, which is a recommended approach and can be useful not only for more advanced changes.withAndroidSplashScreen.ts
in the root folder:import type { ConfigPlugin } from '@expo/config-plugins'
import { withStringsXml } from '@expo/config-plugins'
const withAndroidSplashScreen: ConfigPlugin = (expoConfig) =>
withStringsXml(expoConfig, (modConfig) => {
return modConfig
})
export default withAndroidSplashScreen
yarn tsc withAndroidSplashScreen.ts --watch --skipLibCheck
withAndroidSplashScreen.js
file into app.json plugins
property for Expo to process it on a next build. Our changes look like this:{
"expo": {
...otherProps,
"androidStatusBar": {
"backgroundColor": "#00000000",
"barStyle": "dark-content"
},
"plugins": ["./withAndroidSplashScreen.js"]
}
}
expo prebuild -p android
to see effects of your plugin. Obviously, if you inspect our withAndroidSplashScreen
code it is not changing anything yet. It just returns whatever it receives. Our plugin is a simple function.expoConfig
which is basically content of app.json
and this object is passed to the withStringXml
mod. This particular mod (modifier) from Expo enables us to read contents of android/app/src/main/res/values/strings.xml and change them based on what config we return (all available mods can be found here). For each mod its content can be read from modConfig.modResults
- you can actually use console.log(JSON.stringify(config.modResults, null, 2));
to inspect the values during the prebuild
command. To apply our desired changes we need to modify modResults
.import type { ConfigPlugin } from '@expo/config-plugins'
import { AndroidConfig, withStringsXml } from '@expo/config-plugins'
const withAndroidSplashScreen: ConfigPlugin = (expoConfig) =>
withStringsXml(expoConfig, (modConfig) => {
modConfig.modResults = AndroidConfig.Strings.setStringItem(
[
{
_: 'true',
$: {
name: 'expo_splash_screen_status_bar_translucent',
translatable: 'false'
}
}
],
modConfig.modResults
)
return modConfig
})
export default withAndroidSplashScreen
modResults
what is returned from AndroidConfig helper method setStringItem
which accepts the value we want to add and then remaining file strings already existing. Inspecting type of setStringItem
and typescript in general should help you fill all needed properties correctly. After running prebuild
we should see a new configuration string:+ <string name="expo_splash_screen_status_bar_translucent" translatable="false">true</string>
prebuild
command is a part of EAS build so next time you build your project, you can be sure your plugin will take effect the same way you did it locally.