Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are the layout bounds of a layer-list windowBackground different than an inflated layout?

Tags:

android

On an app I'm working on, we have a splash screen consisting of a RelativeLayout and a logo in the center (and some other stuff, like a loading spinner, etc):

fragment_splash_image.xml:

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_centerInParent="true"
    android:background="@drawable/loading_screen_bg"
    ... >
    <ImageView
        android:id="@+id/universal_loading_logo"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:src="@drawable/logo_large"
     ... />
    ... other stuff ...
</RelativeLayout>

To make sure there wasn't just a brief blank screen before our splash screen, we have a SplashTheme in styles.xml for the activity. Its android:windowBackground is just a layer-list with the logo in the center again, with the hopes that the logo would appear to stay in the middle of the screen while the other things in fragment_splash_image appear as well.

splash_placeholder.xml:

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" android:opacity="opaque">
<item android:drawable="@drawable/loading_screen_gradient"/>
<item>
    <bitmap
        android:gravity="center"
        android:src="@drawable/logo_large"/>
</item>
</layer-list>

Notice that @drawable/logo_large is the same logo in each, and centered on the screen in each. The intended behavior is that it shouldn't appear to move at all.

Anyway, fragment_splash_image is inflated in a class that extends from FrameLayout, in this method:

private void inflateContent() {
    final View splashImageFragment = LayoutInflater.from(getContext()).inflate(R.layout.fragment_splash_image, this, true);
    final ImageView brandLogo = (ImageView) splashImageFragment.findViewById(R.id.universal_loading_logo);
    final int statusBarHeight = ScreenUtils.getStatusBarHeight(getResources());
    final int navBarHeight = !ScreenUtils.hasSoftNavBar() ? 0 : ScreenUtils.getNavigationBarHeight(getResources());
    brandLogo.setPadding(0, 0, 0, statusBarHeight - navBarHeight);
}

Now, what's going on in there is that originally, we just inflated the fragment as-is. Unfortunately, this causes the logo in the splash fragment to jump up or down a small distance compared to the splash placeholder's logo, depending on the device tested on. On my Galaxy S6 phone, I figured that perhaps the placeholder splash screen included the status bar height, so I added it as padding to the bottom of the logo. Problem solved for that device. However, on a Nexus 7 which has a soft navigation bar, the logo still jumped very far up. I concluded that maybe it was also including the navbar height in the layout bounds, and wrote what you see above: bottom padding = statusBarHeight - navBarHeight, where navBarHeight is 0 for devices with hard navigation buttons.

This works for both devices...and then I tested on a Google Pixel. The logo jumps down. This only works on the Pixel if I set the bottom padding to 0, and the top padding to the status bar height.

I'm stumped. What the heck is determining the height of both layouts here? They are clearly different and I'm not sure how to ensure that the logo does not jump from one screen to the next on any devices. Thanks in advance!

like image 295
Emily Goetz Avatar asked May 03 '17 19:05

Emily Goetz


1 Answers

Adding <item name="android:windowDrawsSystemBarBackgrounds">false</item> on API 21+ may allow you to keep the same formula for all devices.

I am facing a similar issue, and thinking about going this route.

like image 132
Sajal Gupta Avatar answered Nov 18 '22 02:11

Sajal Gupta