Search code examples
androidsplash-screennine-patch

Splash Screen strange Black Rectangle on screen


UPDATE: Finally find a little bit hacky solution. But it's not acceptable for me. All ideas can be useful.

I have a Splash Screen Activity and I do not use setContentView(). I set background from styles.xml with using android:windowBackground

When splash screen started, a black rectangle shows up from nowhere, located at left lower part of screen. Height is exact same height with NavigationBar, starts from left of the screen and ends at the center of screen.

This black rectangle only appears at devices, which have Navigation Bar. Not physical buttons. And also only visible when try to hide or show Navigation Bar at a FullScreen activity.

QUESTION: What can be the reason of this bug? How can I solve it?

You can see the whole event below. (Splash Screen to Login screen transition)

Here my splash activity style:

<style name="SplashTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
    <item name="android:windowBackground">@drawable/background_splash</item>
    <item name="windowNoTitle">true</item>
    <item name="windowActionBar">false</item>
    <item name="android:windowFullscreen">true</item>
    <item name="android:windowContentOverlay">@null</item>
</style>

background_splash.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    //Tried different colored layer at bottom level but did not affect
    <item>
        <shape android:shape="rectangle">
            <solid android:color="@color/grey_Dark"/>
        </shape>
    </item>

    //Background image
    <item
        android:drawable="@drawable/bg"
        android:gravity="center"/>

    //9-patch Logo at the center
    <item
        android:drawable="@drawable/splash_logo"
        android:gravity="center"/>

</layer-list>

ActivitySplash

public class ActivitySplash extends BaseActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        final View decorView = getWindow().getDecorView();
        decorView.setSystemUiVisibility(
            View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // hide nav bar
                    | View.SYSTEM_UI_FLAG_FULLSCREEN
                    | View.SYSTEM_UI_FLAG_IMMERSIVE);


        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                Intent intent = new Intent(ActivitySplash.this, ActivityLogin.class);
                startActivity(intent);
                finish();
            }
        }, 2000);

    }
}

Solution

  • Finally find a little bit hacky solution. But it's not acceptable for me. Any ideas can be useful.

    First, used Layout Inspector and get this result:

    enter image description here

    Under DecorView, there is an unwanted strange View is created after started the splash activity.

    It blinks in half of a second and disappears.

    After blinking, If user triggers screen for showing the Navigation Bar, this strange View appears again (permanently).

    Blinking view disappeared after adding

    <item name="android:windowIsTranslucent">true</item>
    

    to my activitty style.

    Other part is more complicated. Added a OnHierarchyChangeListener to DecorView of activity. Casted my DecorView into FrameLayout, and Override onChildViewAdded() callback to remove all children after adding to DecorView.

    final FrameLayout myDecorView = (FrameLayout) decorView;
    myDecorView.setOnHierarchyChangeListener(new ViewGroup.OnHierarchyChangeListener() {
        @Override
        public void onChildViewAdded(View parent, View child) {
            myDecorView.removeView(child);
        }
    
        @Override
        public void onChildViewRemoved(View parent, View child) {
    
        }
    });