I am using the react native splash screen package(https://github.com/crazycodeboy/react-native-splash-screen), and am trying to implement a proper splash screen in Android, where a logo is displayed.
I originally found this article on it, which covered it pretty well: https://medium.com/handlebar-labs/how-to-add-a-splash-screen-to-a-react-native-app-ios-and-android-30a3cec835ae - however, i have the "jumping issue" the article explains, but in a way the author probably didn't expect.
Let explain: When the app first opens, a layer-list based splash screen is displayed on the launch activity, which transfers to the react-native-splash-screen activity(defined by launch_screen.xml
) when the app has loaded in memory. The problem is that while the theme on the startup activity fills the entire screen, the second stage of the splash screen defined in launch_screen.xml
does care about layout. Because of this, the "centered logo" is offset either 24dp up, or down, depending on if the android device has soft navigation buttons or not.
If it was a constant offset, i'd just use margin to offset the logo, but because of the navigation buttons, i'd need some kind of conditional in the xml, which can detect and react to the navigation bar existing.
Therefore, i would like to align an ImageView
in the center of the screen, not its parent container. That, or have the parent container somehow exist underneath the navigation bar when present.
Or, in other words, the issue is that the first-stage of the splash centers relative to the screen, while the second-stage centers relative to the usable space of the screen, and i'd like to match the two, in some way that works regardless of navigation bar existence
Is this possible?
Code
launch_screen.xml
(layout of the second stage of the splash)
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true"
android:background="@color/background">
<TextView android:text="App"
android:layout_alignParentBottom="true"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingBottom="20dp"
android:gravity="center"/>
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center">
<ImageView
android:layout_width="200dp"
android:layout_height="200dp"
android:src="@mipmap/logo"/>
</LinearLayout>
</RelativeLayout>
background_splash.xml
(Theme used in the first stage of the splash)
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:drawable="@color/background"/>
<item
android:width="200dp"
android:height="200dp"
android:drawable="@mipmap/logo"
android:gravity="center"
/>
</layer-list>
You can offset the launch screen programmatically with something like the following
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
ImageView image = view.findViewById(R.id.image_logo);
image.setTranslationY((getNavBarHeight() - getStatusBarHeight()) / 2.0f);
}
public int getStatusBarHeight() {
int result = 0;
int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
if (resourceId > 0) {
result = getResources().getDimensionPixelSize(resourceId);
}
return result;
}
public int getNavBarHeight(){
Resources resources = getResources();
int resourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android");
if (resourceId > 0) {
return resources.getDimensionPixelSize(resourceId);
}
return 0;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With