O que seriam das aplicações Android se não existissem os layouts? A resposta é bem simples: as aplicações não teriam nenhuma interface de comunicação com o usuário, perdendo o que se propõem a fazer, que nada mais é do que facilitar a vida das pessoas que utilizam aplicativos em seus dispositivos móveis.
Ao desenvolver um aplicativo para Android, o layout é uma das principais preocupações que o desenvolvedor deve ter, pois ele será o cartão de visita de seu aplicativo, dando a primeira impressão de como ele é.
Existem duas formas de se programar um layout no Android: via XML ou via código Java. É muito recomendado que se faça o layout em XML e o referencie dentro de sua aplicação, pois o Android Studio já fornece ferramentas visuais para a construção de layouts que geram os códigos XML, mas mesmo assim é interessante que se saiba como o XML funciona.
Para iniciar, na Figura 1 vemos o editor de layouts do Android Studio e alguns componentes que podem ser utilizados no menu do lado esquerdo. Com base neles é que vamos trabalhar.
Para usar os componentes que vimos basta apenas clicar sobre o desejado e arrastá-lo para a tela. Assim, o código XML é automaticamente gerado, como mostra a Listagem 1.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Hello World"
android:id="@+id/textView2"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
</RelativeLayout>
O código apresentado define um Relative Layout (tipo de layout utilizado para posicionar os elementos em relação a outro, e que veremos mais a frente) e dentro dele é definido o componente de tela TextView, que mostrará a mensagem Hello World. Notem que as propriedades mais importantes que devem ser utilizadas quando um layout é definido são android:layout_width e android:layout_height porque elas definirão a altura e a largura do layout em questão de três formas:
- match_parent: Em versões anteriores ao Android 2.2, essa notação tinha o nome de fill_paret, e isso significa que o componente deve ocupar o tamanho definido pelo seu parente (pai). Deve ser utilizada sempre que o layout ocupar toda a tela;
- wrap_content: Essa notação diz que o componente deve ocupar apenas o seu tamanho, sem nenhum tipo de refatoração;
- Definição manual: Essa é uma das formas utilizadas para definir um tamanho, mas deve-se tomar muito cuidado, pois as telas dos aparelhos móveis possuem vários tamanhos e isso pode tornar seu aplicativo incompatível com alguns tamanhos de tela.
Nas próximas seções vamos estudar os tipos de layout que estão no menu da Figura 1.
Relative Layout
O Relative Layout é o tipo de layout utilizado no Android para se posicionar os elementos em relação a outro. Por exemplo, se temos um Text View e o desenvolvedor posicionar o botão a sua esquerda, no XML pode-se fazer referência a esse para que o elemento de tela seja posicionado em um determinado lugar de acordo com sua posição.
A Figura 2 mostra o Relative Layout em ação, com os elementos de tela devidamente alinhados.
Notem quem o Primeiro Text View está no topo e o segundo logo abaixo dele: isso é feito utilizando a notação XML android:layout_below, que significa para posicionar o elemento abaixo de outro que já está definido na tela, que nesse caso, é o primeiro Text View da tela. Já o terceiro Text View está posicionado ao lado direito do segundo Text View: a notação para completar isso é a android:layout_toRightOfe juntamente com o ID do elemento que se deseja alinhar. A Listagem 2 mostra o código completo da tela demonstrada na Figura 2.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Ola Primeiro"
android:id="@+id/textView4"
android:layout_marginTop="41dp"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Ola Segundo"
android:id="@+id/textView5"
android:layout_below="@+id/textView4"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginTop="74dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Ola Terceiro"
android:id="@+id/textView6"
android:layout_alignTop="@+id/textView5"
android:layout_toRightOf="@+id/textView5"
android:layout_toEndOf="@+id/textView5"
android:layout_marginLeft="138dp"
android:layout_marginStart="138dp" />
</RelativeLayout>
O código mostra claramente os componentes e como eles são alinhados. Destaca-se o exemplo do segundo TextView, onde a notação android:layout_below está claramente dizendo que ele ficará abaixo do componente referenciado, que é o textView4.
Pode-se observar em outros elementos de tela o mesmo comportamento, mas com funcionalidades diferentes, como o android:layout_alignTop, que faz o componente alinhar-se seguindo o topo do referenciado.
Linear Layout
O linear layout é um dos tipos de layouts mais utilizados no desenvolvimento com Android, pois possibilita organizar seus componentes de duas formas: alinhados horizontalmente ou alinhados verticalmente.
Para decidir qual será a orientação do seu Linear Layout deve-se trabalhar com a notação android:orientation. Utilizando o Android Studio pode-se criar esse layout clicando com o botão direito na pasta layout e depois new. Quando abrir o Drop down, clique em Layout Resource File e preencha conforme mostra a Figura 3.
Repare que o layout é criado vazio, portanto o desenvolvedor deve colocar os componentes. A Figura 4 mostra uma tela criada com dois componentes TextView para demonstrar como eles serão alinhados.
Notem que o layout está alinhando os componentes verticalmente, graças a tag android:orientation, que recebe como valor “vertical”. A Listagem 3 mostra o código da tela apresentada.
<?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="vertical">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Ola DevMedia"
android:id="@+id/textView" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Tudo bem?"
android:id="@+id/textView3" />
</LinearLayout>
Agora, para termos o layout da Figura 5, onde os componentes foram alinhados horizontalmente, basta usarmos o código da Listagem 4.
<?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">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Ola DevMedia"
android:id="@+id/textView" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Tudo bem?"
android:id="@+id/textView3" />
</LinearLayout>
Reparou que a tag de orientação sumiu? Por padrão do Linear Layout, o Android, quando não encontra a tag de orientação, assume que a orientação será horizontal.
Table Layout
O Table Layout é uma especialização do Linear Layout e é muito utilizado para criar formulários e telas de login. Para criá-lo deve-se seguir os mesmos passos da Listagem 4, mas o root element deve ser mudado para TableLayout, assim, ao criar sua tela estará vazia, como mostra o código da Listagem 5.
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent">
</TableLayout>
Na Figura 6 vemos um exemplo de linhas e colunas criadas utilizando o Table Layout. Seu código é apresentado na Listagem 6.
<TableLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:shrinkColumns="*" android:stretchColumns="*"
android:background="#ffffff">
<!-- Linha 1 com uma coluna-->
<TableRow
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:gravity="center_horizontal">
<TextView
android:id="@+id/TextView00"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="20dp"
android:text="Linha 1"
android:layout_span="3"
android:padding="18dip"
android:background="#FF0000"
android:textColor="#000"/>
</TableRow>
<!-- Linha 2 com 2 colunas -->
<TableRow
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:gravity="center_horizontal">
<TextView
android:id="@+id/TextView01"
android:text="Linha 2 Coluna 1"
android:layout_weight="1"
android:background="#00AF00"
android:textColor="#000000"
android:padding="18dip"
android:gravity="center"/>
<TextView
android:id="@+id/TextView02"
android:text="Linha 2 Coluna 2"
android:layout_weight="1"
android:background="#00FF00"
android:textColor="#000000"
android:padding="18dip"
android:gravity="center"/>
</TableRow>
<!-- Linha 2 com 3 colunas -->
<TableRow
android:id="@+id/tableRow1"
android:layout_height="wrap_content"
android:layout_width="match_parent">
<TextView
android:id="@+id/TextView03"
android:text="Linha 3 Coluna 1"
android:layout_weight="1"
android:background="#0000FF"
android:textColor="#000000"
android:padding="20dip"
android:gravity="center"/>
<TextView
android:id="@+id/TextView04"
android:text="Linha 3 Coluna 2"
android:layout_weight="1"
android:background="#0000CF"
android:textColor="#000000"
android:padding="20dip"
android:gravity="center"/>
<TextView
android:id="@+id/TextView05"
android:text="Linha 3 Coluna 3"
android:layout_weight="1"
android:background="#0000AF"
android:textColor="#000000"
android:padding="20dip"
android:gravity="center"/>
</TableRow>
</TableLayout>
Notem que o código apresentado é muito parecido com as definições de tabelas do HTML. Primeiro, o TableLayout é definido como um componente interno. A seguir definimos um TableRow e dentro deste os elementos de tela desejados são colocados alinhados horizontalmente dentro da linha declarada. Lembre-se que todos os elementos de tela devem estar definidos dentro de um TableRow se quiser que eles estejam alinhados na interface gráfica, já que tudo o que estiver dento dele fará parte de uma mesma linha.
Combinação de Layouts
Outra prática interessante que pode ser feita é a combinação entre layouts, onde em uma parte da tela você precise de um tipo de alinhamento e em outra parte um outro tipo. O que pode ser feito, por exemplo, é colocar um Linear Layout dentro de um Relative Layout. A Figura 7 mostra um exemplo bem básico dessa combinação de layouts.
Notem que a tela está diferenciada e foi alinhada de acordo com seus respectivos layouts. A Listagem 7 mostra o código XML que deu origem a essa tela.
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="98dp"
android:id="@+id/linearLayout">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Linear1"
android:id="@+id/textView" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Linear2"
android:id="@+id/textView3" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Linear3"
android:id="@+id/textView2" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Linear4"
android:id="@+id/textView5" />
</LinearLayout>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Botao Relative"
android:id="@+id/button"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="Relative"
android:id="@+id/textView4"
android:layout_alignBottom="@+id/button"
android:layout_toRightOf="@+id/button"
android:layout_toEndOf="@+id/button"
android:layout_marginLeft="58dp"
android:layout_marginStart="58dp" />
</RelativeLayout>
O desenvolvedor pode se perguntar: se existem dois tipos de layouts com suas peculiaridades, como o Android sabe o que é de quem? A resposta é bem simples: os elementos específicos têm que estar contidos dentro das tags relativas ao seu layout, ou seja, se está contido dentro de é um componente linear aceito, e o mesmo deve acontecer com os demais layouts utilizados.
Ao fazer essa combinação entre dois tipos de layouts deve-se tomar muito cuidado, pois é um processo muito custoso quando se vai renderizar essa tela no dispositivo. O método onCreate do Java, ao fazer a invocação do método setContentView(R.layout.<referencia_nosso_layout>), vai inflar o layout criado, ou seja, ele irá localizar a referência passada e pegar o layout em questão e recursivamente irá converter o XML para o objeto Java. Após essa conversão ele está apto a mostrar na tela o layout desenvolvido.
Para saber mais sobre como criar o layout diretamente no Java, acompanhe a seção a seguir.
Criando Layout em Java
No Android, os layouts podem também ser criados em Java dentro da Activity, mas esse não é um processo muito recomendado, pois o desenvolvedor pode perder muito tempo criando um layout via código, enquanto já existem ferramentas que fazer isso sem o menor esforço, como vimos nos exemplos anteriores.
Vamos usar o exemplo da Figura 4 e a Listagem 3, que foi escrita em XML, agora é escrita em Java, como mostra a Listagem 8.
package br.com.devmedia.appdevmedia;
import android.app.Activity;
import android.os.Bundle;
import android.widget.LinearLayout;
import android.widget.TextView;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LinearLayout layout = new LinearLayout(this);
layout.setOrientation(LinearLayout.VERTICAL);
layout.setLayoutParams(new LinearLayout
.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT,
LinearLayout.LayoutParams.FILL_PARENT));
TextView titleView = new TextView(this);
LinearLayout.LayoutParams lparams = new
LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
titleView.setLayoutParams(lparams);
titleView.setText("Ola DevMedia");
layout.addView(titleView);
TextView titleView2 = new TextView(this);
LinearLayout.LayoutParams lparams2 = new
LinearLayout.LayoutParams(
LinearLayout.LayoutParams.WRAP_CONTENT,
LinearLayout.LayoutParams.WRAP_CONTENT);
titleView2.setLayoutParams(lparams2);
titleView2.setText("Tudo bem?");
layout.addView(titleView2);
setContentView(layout);
}
}
As Listagens 3 e 8 têm a mesma função, mas a codificação em Java permite que o layout seja definido dentro da própria Activity.
Observe que é um código simples, mas muito trabalhoso para se desenvolver, mas imagine em uma aplicação onde se trabalha com muitas Activities: o código ficaria praticamente ilegível e, além do mais, sempre que quiséssemos ver como está a tela, teria que recompilar e exibir no emulador, enquanto o Android Studio já fornece um renderizador de XML para poder mostrar em tempo real como está o layout que o programador está desenvolvendo.
Com isso, concluímos que é muito mais fácil trabalhar com o XML do que o Java. Deixe que a conversão do XML seja feita automaticamente, afinal de contas, é uma das principais vantagens de se trabalhar com o Android Studio.
E não perca tempo usando um layout para definir outro. Cada um tem suas propriedades e não adianta reescrever o código, pois é perda de tempo.
E como vimos, cuidado com a combinação de layouts, pois é muito fácil, mas precisamos de atenção para não referenciar um elemento dentro do layout errado.