De que se trata o artigo:

Construção de layouts complexos em Android, principais layouts disponíveis na plataforma, como aninhá-los para permitir que estruturas gráficas mais complexas sejam utilizadas e como estendê-los para dar mais expressividade gráfica às aplicações móveis.

Para que serve:

Possibilitar a utilização de layouts complexos em aplicações móveis em Android, permitindo assim a melhoria da usabilidade e enriquecimento do módulo de interface gráfica dos projetos criados para a plataforma.

Em que situação o tema é útil:

Quando determinado requisito funcional gráfico não puder ser satisfeito com a utilização apenas de estruturas simples de layouts.

 

A Interface Gráfica com o Usuário (GUI) é um dos aspectos essenciais em um Sistema de Informação, permitindo que o usuário final desfrute de forma fácil e muitas vezes intuitiva das funcionalidades fornecidas pelo software (graças aos seus widgets). Acompanhando sua evolução por meio das Eras da Computação (desde que os comandos eram realizados em uma tela de texto), percebemos que as Linguagens de Programação de alto nível têm enfatizado o seu uso e sua melhoria por meio de suas versões, sendo possível hoje em dia construirmos GUIs tão complexas quanto os requisitos exigidos pelo mundo real.

E quando o contexto é mobilidade, o desenvolvimento da mesma não pode ser adotado como é para Desktops ou Web, haja vista as restrições de recursos gráficos inerentes aos dispositivos móveis. Porém, esta realidade está mudando. Idealizadores de plataformas móveis vêm estudando novas formas de construção de interfaces gráficas para permitir mais flexibilidade e riqueza no desenvolvimento de aplicações móveis. E uma delas é Android, por meio de seus layouts que são totalmente definidos em XML.

Neste artigo, você aprenderá como construir layouts complexos em Android. Primeiramente, será descrito como a plataforma implementa a hierarquia de componentes de tela. Depois, serão explicadas as características dos principais layouts, que são: LinearLayout, FrameLayout, AbsoluteLayout, RelativeLayout e TableLayout. Finalmente, será mostrado como se criar layouts complexos e como estendê-los para que estruturas gráficas mais complexas possam ser desenvolvidas, sendo para isso utilizado uma aplicação que simula a previsão do tempo para cidades do Brasil.

Hierarquia de Views e ViewGroups

Em Android, todos os componentes de interface gráfica são representados por subclasses de android.view.View que representam os componentes gráficos (os chamados widgets) como TextView, Button , TextEdit, RadioButton, Checkbox, etc; e a classe android.view.ViewGroup, que representa um container de Views e também ViewGroups. Ela é a classe base para componentes de layouts, como LinearLayout, FrameLayout, AbsoluteLayout, RelativeLayout, TableLayout, etc.

O fato de um ViewGroup também ser composto por um ou mais ViewGroups é o fator que permite que layouts complexos (layouts aninhados) sejam desenvolvidos, como podemos observar na Figura 1.

 


Figura 1. Hierarquia de componentes de tela.

Respeitando os parâmetros de layouts

Para que os componentes possam ser acomodados de acordo com o layout de seu pai, os mesmos devem manter uma relação de obediência. Sendo assim, cada filho deve configurar os seus parâmetros de layouts, por meio da classe ViewGroup.LayoutParams, que permite que estes determinem suas propriedades de posição e tamanho referente ao layout de seus pais.

Portanto, todo layout deve possuir uma classe interna que obrigatoriamente estenda esta classe. Por exemplo, na Figura 2, podemos perceber que os filhos de LinearLayout (a raiz da árvore) possuem os seus parâmetros (LinearLayout.LayoutParams) para serem utilizados dentro de LinearLayout, como ocorre também para os filhos de RelativeLayout. Todo layout possui propriedades de largura e altura (atributos layout_width e layout_height, respectivamente), porém outros podem declarar aspectos de margens e bordas.

É possível que estas propriedades sejam ajustadas manualmente (informando o valor exato), porém, é desejável que elas sejam configuradas possibilitando que o componente preencha o espaço do seu pai ou se ajuste de acordo com o seu conteúdo (inserindo o valor fill_parent ou o valor wrao_content em android:layout_width ou android:layout_height, respectivamente).

A seguir, serão descritos os principais layouts e suas características. Um aviso ao leitor: daqui por diante neste artigo, todos os layouts que serão explicados, serão definidos em arquivos XML separados (linearlayout.xml, framelayout.xml, etc). Dessa maneira, não é preciso sobrescrever o layout anterior para ver como ele se comporta na tela do emulador, sendo somente necessário alterar a referência (R.layout.main) no método setContentView(), de acordo com o layout a ser visualizado (R.layout.linearlayout, por exemplo). Isso nos permite construir vários layouts para serem utilizados em nossos projetos Android.


Figura 2. Os componentes respeitando os parâmetros de layouts dos seus pais.

LinearLayout

Este layout (criado por padrão no arquivo main.xml quando construímos um projeto) é utilizado para dispor seus componentes em uma única direção (por meio do atributo android:layout_orientation): vertical ou horizontal (Figura 3). Sendo assim, sua aplicação conterá somente uma lista de componentes caso estes sejam dispostos na vertical (Figura 4), passando o valor “vertical” para o atributo android:orientation de <LinearLayout>, ou uma única linha de componentes localizada na parte de cima do layout caso estes sejam dispostos na horizontal (Figura 5), atribuindo a este atributo o valor “horizontal”. Este layout respeita as margens entre os seus filhos e alinhamento (ao centro, à esquerda ou à direita. Em Android, chamamos este atributo de gravity).

É possível também atribuir, individualmente, pesos (Figura 6) para os componentes para que estes possam ocupar o restante do espaço do layout, evitando que pequenos objetos deixem espaço desnecessário no layout. Por padrão, todos os componentes adicionados possuem peso igual a 0. Porém, caso mais de um objeto utilize peso (Figura 7), então os componentes serão ajustados para preencherem igualmente o espaço de seu pai. Para ver isto na prática, basta você adicionar o atributo android:layout_weight=”1” para um ou mais Views e garantir que android:orientation de <LinearLayout> está com o valor “vertical”. A Listagem 1 mostra um exemplo de LinearLayout em XML.


Figura 3. Adicionando componentes em uma única direção com LinearLayout.

 


Figura 4. Exemplificando LinearLayout na direção vertical.

 


Figura 5. Exemplificando LinearLayout na direção horizontal.

 


Figura 6. Atribuindo peso a um componente.

 


Figura 7. Atribuindo peso a mais de um componente.

 

Listagem 1. Linearlayout.xml

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

         android:orientation="vertical" android:layout_width="wrap_content"

         android:layout_height="fill_parent">

         <EditText android:layout_width="fill_parent"

                   android:layout_height="wrap_content"

                   android:text="Texto1" />

         <EditText android:layout_width="fill_parent"

                   android:layout_height="wrap_content"

                   android:text="Texto2" />

</LinearLayout>

 

FrameLayout

O FrameLayout arranja seus filhos de acordo com uma pilha de componentes que são adicionados, sendo que o topo da pilha contém o objeto que foi adicionado por último, como podemos perceber na pilha ao lado de FrameLayout (Figura 8), em que o primeiro componente na pilha é um View de cor azul e o do topo, de cor roxa. Podemos utilizá-lo quando, por exemplo, queremos usar várias imagens, onde uma é trocada (sobreposta) pela outra (como um slide de imagens) conforme vão sendo adicionadas.

O tamanho total de um FrameLayout é definido pelo seu maior filho mais o espaçamento (padding) e todos os componentes são agrupados no canto superior esquerdo do layout. Porém, a sua utilização comumente dá-se a partir de suas subclasses, como ImageSwitcher, ViewAnimator, ViewSwitcher, ScrollView, TabHost, etc (para maiores detalhes confira a referência desta classe em http://code.google.com/android/reference/android/widget/FrameLayout.html). A Listagem 2 mostra como este layout é implementado em XML e a Figura 9, exibe como ele é visualizado na tela do emulador.


Figura 8. Criando uma pilha de componentes com FrameLayout.

 


Figura 9. Sobreposição de componentes com FrameLayout.

 

Listagem 2. framelayout.xml

<?xml version="1.0" encoding="utf-8"?>

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"

         android:orientation="vertical" android:layout_width="fill_parent"

         android:layout_height="fill_parent">

         <EditText android:layout_width="120px"

                   android:layout_height="wrap_content" android:text="Texto1"

                   android:layout_weight="1" />

...

Quer ler esse conteúdo completo? Tenha acesso completo