Mostrar SplashScreen mientras se carga la aplicación en Android

publicado por: Anonymous

Tengo implementado una splashcreen mediante una activity que se infla de su layout con una imagen centrada, pero lo que me encuentro que si es la primera vez que se instala la app, durante la carga/compilación se muestra una pantalla en blanco, más o menos 6 segundos, la segunda vez que inicias la app inicia directamente con la SplashScreen.

Graficamente así

La Primera vez que se ejecuta la app despues de instalación o borrar datos del menú configuración

(click abrir app)…………………….(splashscreen)——(listo)

La segunda vez que se abre la app

(click abrir app)(splashscreen)——(listo)

Mi pregunta si hay alguna forma de poner una splashcreen durante ese periodo de pre-carga de Android.

Manifest.xml

<activity
    android:name=".SplashActivity"
    android:configChanges="keyboardHidden|orientation|screenSize"
    android:theme="@style/AppTheme.SplashTheme">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>

Estilo AppTheme.SplashTheme del Tema que hereda la activity

<style name="AppTheme.SplashTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="windowActionBar">false</item>
    <item name="windowNoTitle">true</item>
    <item name="android:windowFullscreen">true</item>
    <item name="android:windowEnterAnimation">@android:anim/fade_in</item>
</style>

Layout XML splash_screen.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/colorSplashScreen">

    <LinearLayout
        android:id="@+id/splashscreen"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center_vertical|center_horizontal">

        <ImageView
            android:layout_width="wrap_content"
            android:contentDescription="@string/about.alt_logo"
            android:layout_height="wrap_content"
            android:src="@mipmap/ic_launcher"
            android:layout_gravity="center"/>

        <TextView android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/app_name"
            android:layout_marginTop="8dp" />

    </LinearLayout>

</LinearLayout>

SplashActivity.java

import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.widget.LinearLayout;

/*
config_longAnimTime   = 400
config_mediumAnimTime = 300
config_shortAnimTime  = 150
*/
public class SplashActivity extends AppCompatActivity {

    private String TAG = "SplashActivity";


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        final int SPLASH_DISPLAY_LENGTH = 1200;
        final int SPLASH_DISPLAY_OFFSET = getResources().getInteger(android.R.integer.config_shortAnimTime);;

        super.onCreate(savedInstanceState);
        setContentView(R.layout.splash_screen);

        Log.d(TAG, "onCreate() called with: " + "savedInstanceState = [" + savedInstanceState + "]");
        final Handler handler = new Handler();

        handler.postDelayed(new Runnable() {
            @Override
            public void run() {


                final LinearLayout img = (LinearLayout) SplashActivity.this.findViewById(R.id.splashscreen);

                Animation fadeOut = new AlphaAnimation(1, 0);
                fadeOut.setInterpolator(new AccelerateInterpolator());
                fadeOut.setDuration(getResources().getInteger(android.R.integer.config_longAnimTime));

                fadeOut.setAnimationListener(new Animation.AnimationListener()
                {
                    public void onAnimationEnd(Animation animation)
                    {
                        img.setVisibility(View.GONE);

                        handler.postDelayed(new Runnable() {
                            @Override
                            public void run() {
                                //Create an intent that will start the main activity.
                                Intent mainIntent = new Intent(SplashActivity.this, MainActivity.class);
                                SplashActivity.this.startActivity(mainIntent);

                                //Apply splash exit (fade out) and main entry (fade in) animation transitions.
                                overridePendingTransition(R.anim.zoom_enter, android.R.anim.fade_out);

                                //Finish splash activity so user cant go back to it.
                                SplashActivity.this.finish();

                            }
                        }, SPLASH_DISPLAY_OFFSET);

                    }
                    public void onAnimationRepeat(Animation animation) {}
                    public void onAnimationStart(Animation animation) {}
                });

                img.startAnimation(fadeOut);

                Log.d(TAG, "finish SplashScreen: " + SPLASH_DISPLAY_LENGTH);

            }
        }, SPLASH_DISPLAY_LENGTH);

    }

}

Actualización:
Se muestra la pantalla blanca porque hereda del tema light, porque si añado el estilo del tema, se muestra negra la pantalla.

    <item name="android:background">#FF000000</item>
    <item name="android:colorBackground">#FF000000</item>

Creo que la solución recae en implementar dibujar el icono mediante la carga del tema antes de usar un layout xml, abrir app —> se aplica tema —-> carga layout en la interfaz.

solución

Update
Leyendo ese post Un splashscreen eficiente (en)
Añado lo opaque

Definir el fondo del splashscreen en un drawable background_splash.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="@color/colorSplashScreen"/>
    <item android:top="-48dp">
        <bitmap
            android:gravity="center"
            android:src="@mipmap/ic_launcher"/>
    </item>
</layer-list>

Aplico un desplazamiento superior para ajustar bien la transición de la pantalla pre-carga hacia el splashscreen

Asignar como fondo el drawable creado en styles.xml

<style name="AppTheme.SplashTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <item name="windowActionBar">false</item>
    <item name="windowNoTitle">true</item>
    <item name="android:windowFullscreen">true</item>
    <item name="android:windowEnterAnimation">@android:anim/fade_in</item>
    <item name="android:windowBackground">@drawable/background_splash</item>
</style>

De paso elimino la idea de tener texto que aparece debajo del icono de la app, porque no encontrado como hacerlo directamente como un drawable.

layout splash_screen.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    android:background="@color/colorSplashScreen">

    <LinearLayout
        android:id="@+id/splashscreen"
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center_vertical|center_horizontal">

        <ImageView
        android:layout_width="wrap_content"
        android:contentDescription="@string/about.alt_logo"
        android:layout_height="wrap_content"
        android:src="@mipmap/ic_launcher"
        android:layout_gravity="center"/>

</LinearLayout>

Código opcional para cambiar el tema al vuelo, en caso de no hacer un splascreen con un activity intermedio:

public class MyMainActivity extends AppCompatActivity {
 @Override
  protected void onCreate(Bundle savedInstanceState) {

    setTheme(R.style.Theme_MyApp); //Tu Tema general
    super.onCreate(savedInstanceState);
    // ...
  }
}
Respondido por: Anonymous

Leave a Reply

Your email address will not be published. Required fields are marked *