Splash Screen criando uma tela de abertura no Android
Vamos entender como implementar desde o design à lógica por de trás dos panos da criação de uma tela de abertura no Android (Splash Screen) de uma App que eu estou desenvolvendo para a Alura.
Recentemente, adicionei uma tela para autenticação nessa App, onde armazeno os cursos que realizei:
E agora essa tela é a minha LAUNCHER, ou seja, a tela inicial quando abro a minha App. Entretanto, em diversas Apps do nosso dia-a-dia, quando abrimos temos uma tela de abertura, como por exemplo:
Conhecendo as Splash Screens
Essas telas de aberturas, tecnicamente conhecidas como Splash Screens, são telas que são apresentadas ao usuário no primeiro instante em que ele abre a App, justamente para apresentarmos uma marca, ou então realizarmos algum tipo de pré prossamento que exige alguns segundos.
Criando o layout da Splash Screen
Ao invés de apresentar logo de cara a tela de login para o usuário, eu gostaria de exibir uma splash screen. Então criei o arquivo activity_splash_screen.xml
que representa a splash screen para a minha App:
<?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="#000" android:orientation="vertical">
<ImageView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_marginTop="150dp" android:src="@drawable/logoalura" />
<TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:text="meus cursos" android:textColor="#fff" android:textSize="30dp" />
</LinearLayout>
Temos o seguinte resultado:
Adicionando a Activity para representar a Splash Screen
Teoricamente, basta apenas criarmos a activity SplashScreenActivity
que representará a splash screen, então, settamos a View
com o setContentView()
, e por fim, chamamos a LoginActivity
que representa a tela de login.
Então vamos implementar o código:
public class SplashScreenActivity extends AppCompatActivity {
@Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash_screen);
mostrarLogin();
}
private void mostrarLogin() {
Intent intent = new Intent(SplashScreenActivity.this, LoginActivity.class);
startActivity(intent);
finish();
}
}
Rodando a App temos o seguinte resultado:
Ué, a splash screen não apareceu... Por que isso aconteceu?
Observe que na SplashScreenActivity
, primeiramente, chamamos a View
da splash screen, porém, logo em seguida, fazemos uma chamada para a LoginActivity
que, internamente, faz a chamada da View
de login. Então vem a questão:
- Quanto tempo demora entre a transição da
SplashScreenActivity
e aLoginActivity
?
Não sabemos precisamente quanto tempo é gasto, porém, sabemos que todo esse processo é realizado em menos de 1 segundo, ou seja, na casa dos milissegundos. Isso significa que acontece de imediato! É justamente por isso que não conseguimos visualizar...
Então como podemos resolver isso?
Precisamos, de alguma maneira, fazer com que tenha um delay, isto é, um intervalo de tempo de espera antes de chamar a LoginActivity
, por exemplo, um atraso de 2 segundos.
Inserindo delay na Splash Screen com o Handler do Android
Temos diversas formas de solucionar esse problema utilizando a linguagem Java, como por exemplo, pelo uso de Threads e as diversas APIs que a própria linguagem nos fornece.
Entretanto, o próprio Android nos oferece a classe Handler que, internamente, trabalha com Threads
assim como no Java, porém, nos provê alguns métodos capazes de nos ajudar nessa situação. Portanto, vamos instânciá-la:
public class SplashScreenActivity extends AppCompatActivity {
@Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash_screen);
Handler handle = new Handler();
mostrarLogin();
}
//restante do código }
Para executarmos uma thread com delay no Handler
, utilizamos o método [postDelayed()](https://developer.android.com/reference/android/os/Handler.html#postDelayed(java.lang.Runnable, long)) que recebe dois parâmetros:
- 1º parâmetro: uma interface
Runnable
que é justamente aThread
que será executada após o tempo de delay. - 2º parâmetro: tempo de delay em millisegundos.
Então o nosso código fica da seguinte forma:
Handler handle = new Handler();
handle.postDelayed(new Runnable() {
@Override public void run() {
mostrarLogin();
}
}, 2000);
Pronto! Criamos a nossa thread que rodará com um delay. Portanto, vamos executar a App novamente e verificar o resultado:
Maravilha! Agora está funcionando conforme esperado. Entretanto, observe que a nossa splash screen ainda exibe o horário, notificações e amActionBar. Em outras palavras, seria legal se a nossa splash screen fosse full screen, ou seja, tela cheia, por exemplo:
Como será que podemos fazer isso?
Ajustando o tema para tela cheia
No arquivo AndroidManifest.xml
, podemos definir temas para cada Activity
por meio do atributo android:theme
. Existem diversos temas disponíveis, porém, nesse caso, utilizaremos um tema existente chamado Theme.AppCompat.NoActionBar
:
<activity android:name=".SplashScreenActivity" android:theme="@style/Theme.AppCompat.NoActionBar">
<intent-filter> <action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter> </activity>
Poderíamos utilizar outros temas para tirar a ActionBar
, mas porque utilizamos esse em específico? É justamente pelo motivo de estarmos estendendo da classe AppCompatActivity
Vejamos o resultado:
Melhorando o visual da Splash Screen
Já melhorou bastante comparando com o resultado anterior, porém, ainda não está em full screen... E agora? Como podemos fazer isso mantendo a AppCompatActivity
? Podemos criar um tema personalizado no arquivo res > values > styles.xml
:
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
</resources>
Então vamos criar um tema nosso chamado AppCompat.TelaCheia
:
<style name="AppCompat.TelaCheia"> </style>
Criamos o tema, mas e agora? O que podemos fazer?
Precisamos utilizar as mesmas propriedades do tema Theme.AppCompat.NoActionBar
, porém, com uma configuração extra para deixar full screen. Será que é possível?
Da mesma forma que fazemos com as classes do Java, podemos estender de temas já existentes! Como, por exemplo, fazer com que o nosso AppCompat.TelaCheia
herde do Theme.AppCompat.NoActionBar
a partir do atributo parent
:
<style name="AppCompat.TelaCheia" parent="Theme.AppCompat.NoActionBar"> </style>
Então, adicionamos o item necessário para deixar full screen, que é o android:windowFullscreen
:
<resources>
<!-- Outros temas -->
<style name="AppCompat.TelaCheia" parent="Theme.AppCompat.NoActionBar">
<item name="android:windowFullscreen">true</item>
</style>
</resources>
Por fim, basta apenas utilizarmos esse tema para a nossa SplashScreenActivity
:
<activity android:name=".SplashScreenActivity" android:theme="@style/AppCompat.TelaCheia">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
Vamos rodar a nossa App e verificar o resultado:
Bem mais bonito né? E aí? Gostou de criar uma splash screen?
Que tal aprender a desenvolver a sua App Android desde o zero? Aqui na Alura, temos uma formação Android onde ensinamos você a desenvolver sua primeira App com os principais conceitos do início ao fim.