1AndroidConstruindo layouts complexos emAndroidRamon Ribeiro Rabelloramon.rabello@gmail.comÉ graduado em Ciência da Comput...
2possível hoje em dia construirmos GUIs tão complexas quanto os requisitos exigidos pelomundo real.      E quando o contex...
3raiz da árvore) possuem os seus parâmetros (LinearLayout.LayoutParams) para seremutilizados dentro de LinearLayout, como ...
4para um ou mais Views e garantir que android:orientation de <LinearLayout> está com ovalor “vertical”. A Listagem 1 mostr...
5Figura 5. Exemplificando LinearLayout na direção horizontal.Figura 6. Atribuindo peso a um componente.
6Figura 7. Atribuindo peso a mais de um componente.Listagem 1. Linearlayout.xml<?xml version="1.0" encoding="utf-8"?><Line...
7Figura 8. Criando uma pilha de componentes com FrameLayout.Figura 9. Sobreposição de componentes com FrameLayout.Listagem...
8posição (0,0). Este layout deve ser utilizado com cautela, pois, além dos objetos seremsobrepostos (como podemos ver os V...
9Figura 12. Problema que pode ocorrer em dispositivos com resoluções de tela diferente.Listagem 3. absolutelayout.xml<?xml...
10somente necessário se em algum local de seu layout este componente será referenciado. AListagem 4 mostra um exemplo de t...
11         <EditText android:id="@+id/etSenha"             android:layout_width="250px" android:layout_height="wrap_conten...
12Figura 16. Exemplo de TableLayout no emulador.Listagem 5. tablelayout.xml<?xml version="1.0" encoding="utf-8"?><TableLay...
13Figura 17. Aninhando layouts para construir layouts complexos.Figura 18. Reproduzindo layouts complexos.Listagem 6. comp...
14                             android:layout_x="120px" android:layout_y="12px" />                     <Button android:lay...
15parâmetros de layout para cada objeto utilizando LinearLayout.LayoutParams,começando primeiramente para a cidade (cidade...
16passaremos para ClimaAdapter mais à frente. Agora, instanciamos e adicionamos na lista(climas) vários objetos Clima, pas...
17package android.clima.adapter;/* imports */public class ClimaAdapterView extends LinearLayout {    public ClimaAdapterVi...
18           climas.add(w);           w = new Clima("Recife", 18, StatusClima.CHUVOSO);           climas.add(w);          ...
19vimos na seção anterior, a plataforma permite que componentes gráficos (Views eViewGroups) sejam criados via código, cas...
Upcoming SlideShare
Loading in...5
×

Layout complexos

190

Published on

PDF - Layouts em java

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
190
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
10
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Transcript of "Layout complexos"

  1. 1. 1AndroidConstruindo layouts complexos emAndroidRamon Ribeiro Rabelloramon.rabello@gmail.comÉ graduado em Ciência da Computação pela Universidade da Amazônia (UNAMA). Trabalha coma tecnologia Java há 4 anos e já desenvolveu projetos utilizando as linguagens Delphi, C e C++.Possui experiência nas três especificações Java: JSE, JEE e JME.Trabalhou com desenvolvimentode aplicações móveis comerciais (M-Commerce / M-Payment) e publicou artigos científicos sobreaspectos referentes à plataforma JME. Atualmente é mestrando da Universidade Federal dePernambuco (UFPE) na área de Engenharia de Software. De que se trata o artigo: Construção de layouts complexos em Android, principais layouts disponíveis na plataforma, comoaninhá-los para permitir que estruturas gráficas mais complexas sejam utilizadas e como estendê-lospara 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, permitindoassim a melhoria da usabilidade e enriquecimento do módulo de interface gráfica dos projetoscriados para a plataforma. Em que situação o tema é útil: Quando determinado requisito funcional gráfico não puder ser satisfeito com a utilizaçãoapenas de estruturas simples de layouts. A Interface Gráfica com o Usuário (GUI) é um dos aspectos essenciais em um Sistemade Informação, permitindo que o usuário final desfrute de forma fácil e muitas vezesintuitiva das funcionalidades fornecidas pelo software (graças aos seus widgets).Acompanhando sua evolução por meio das Eras da Computação (desde que os comandoseram realizados em uma tela de texto), percebemos que as Linguagens de Programação dealto nível têm enfatizado o seu uso e sua melhoria por meio de suas versões, sendo
  2. 2. 2possível hoje em dia construirmos GUIs tão complexas quanto os requisitos exigidos pelomundo real. E quando o contexto é mobilidade, o desenvolvimento da mesma não pode seradotado como é para Desktops ou Web, haja vista as restrições de recursos gráficosinerentes aos dispositivos móveis. Porém, esta realidade está mudando. Idealizadores deplataformas móveis vêm estudando novas formas de construção de interfaces gráficaspara permitir mais flexibilidade e riqueza no desenvolvimento de aplicações móveis. Euma 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 componentesde 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 estruturasgráficas mais complexas possam ser desenvolvidas, sendo para isso utilizado umaaplicaçã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 porsubclasses de android.view.View que representam os componentes gráficos (os chamadoswidgets) como TextView, Button , TextEdit, RadioButton, Checkbox, etc; e a classeandroid.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 é ofator que permite que layouts complexos (layouts aninhados) sejam desenvolvidos, comopodemos 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 seupai, os mesmos devem manter uma relação de obediência. Sendo assim, cada filho deveconfigurar 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 aolayout de seus pais. Portanto, todo layout deve possuir uma classe interna que obrigatoriamente estendaesta classe. Por exemplo, na Figura 2, podemos perceber que os filhos de LinearLayout (a
  3. 3. 3raiz da árvore) possuem os seus parâmetros (LinearLayout.LayoutParams) para seremutilizados dentro de LinearLayout, como ocorre também para os filhos de RelativeLayout.Todo layout possui propriedades de largura e altura (atributos layout_width elayout_height, respectivamente), porém outros podem declarar aspectos de margens ebordas. É possível que estas propriedades sejam ajustadas manualmente (informando o valorexato), porém, é desejável que elas sejam configuradas possibilitando que o componentepreencha o espaço do seu pai ou se ajuste de acordo com o seu conteúdo (inserindo o valorfill_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 aoleitor: daqui por diante neste artigo, todos os layouts que serão explicados, serão definidosem 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 doemulador, sendo somente necessário alterar a referência (R.layout.main) no métodosetContentView(), de acordo com o layout a ser visualizado (R.layout.linearlayout, porexemplo). Isso nos permite construir vários layouts para serem utilizados em nossosprojetos 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 umprojeto) é utilizado para dispor seus componentes em uma única direção (por meio doatributo android:layout_orientation): vertical ou horizontal (Figura 3). Sendo assim, suaaplicaçã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 dolayout caso estes sejam dispostos na horizontal (Figura 5), atribuindo a este atributo ovalor “horizontal”. Este layout respeita as margens entre os seus filhos e alinhamento (aocentro, à esquerda ou à direita. Em Android, chamamos este atributo de gravity). É possível também atribuir, individualmente, pesos (Figura 6) para os componentespara que estes possam ocupar o restante do espaço do layout, evitando que pequenosobjetos deixem espaço desnecessário no layout. Por padrão, todos os componentesadicionados possuem peso igual a 0. Porém, caso mais de um objeto utilize peso (Figura7), então os componentes serão ajustados para preencherem igualmente o espaço de seupai. Para ver isto na prática, basta você adicionar o atributo android:layout_weight=”1”
  4. 4. 4para um ou mais Views e garantir que android:orientation de <LinearLayout> está com ovalor “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.
  5. 5. 5Figura 5. Exemplificando LinearLayout na direção horizontal.Figura 6. Atribuindo peso a um componente.
  6. 6. 6Figura 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 quesã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 primeirocomponente na pilha é um View de cor azul e o do topo, de cor roxa. Podemos utilizá-loquando, 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 oespaçamento (padding) e todos os componentes são agrupados no canto superioresquerdo do layout. Porém, a sua utilização comumente dá-se a partir de suas subclasses,como ImageSwitcher, ViewAnimator, ViewSwitcher, ScrollView, TabHost, etc (paramaiores detalhes confira a referência desta classe emhttp://code.google.com/android/reference/android/widget/FrameLayout.html). AListagem 2 mostra como este layout é implementado em XML e a Figura 9, exibe como eleé visualizado na tela do emulador.
  7. 7. 7Figura 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" /> <EditText android:layout_width="90px" android:layout_height="wrap_content" android:text="Texto2" android:layout_weight="1" /> <EditText android:layout_width="60px" android:layout_height="wrap_content" android:text="Texto3" /></FrameLayout>AbsoluteLayout Este tipo de layout organiza seus componentes de forma a implementar um planocartesiano, no qual as suas posições x e y devem ser definidas para que estes possam serposicionados de forma absoluta (Figura 10), sendo que os valores da coordenada xcrescem da esquerda para a direita e da coordenada y, de cima para baixo. Caso oscomponentes não declarem as suas posições explicitamente, eles serão dispostos na
  8. 8. 8posição (0,0). Este layout deve ser utilizado com cautela, pois, além dos objetos seremsobrepostos (como podemos ver os Views na posição (x4,y4) e (x7,y7)) caso as suasposições sejam informadas incorretamente, o layout da sua aplicação pode não secomportar como esperado caso ela seja desenvolvida para rodar em dispositivos comresoluções de telas diferentes (Figura 11 e Figura 12). Para simularmos este efeito, mudaremos o skin do emulador, que é por padrão oHVGA-P 320x420 em formato retrato (vermelho), para o skin Q-VGA 240x320 em formatoretrato (branco). Para isso, clicamos com botão direito do mouse em cima do projeto evamos em Open Run Dialog....Depois, do lado direito, clicamos na aba Target e em ScreenSize selecionamos QVGA-P. Rodamos a aplicação e podemos agora ver, que algunscomponentes são posicionados quase fora da tela do dispositivo. A Listagem 3 exibe olayout em XML que foi utilizado nas figuras anteriores.Figura 10. Utilizando o AbsoluteLayout.Figura 11. Dispondo os componentes de forma absoluta com AbsoluteLayout.
  9. 9. 9Figura 12. Problema que pode ocorrer em dispositivos com resoluções de tela diferente.Listagem 3. absolutelayout.xml<?xml version="1.0" encoding="utf-8"?><AbsoluteLayout 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="wrap_content" android:layout_height="wrap_content" android:text="Texto1" android:layout_x="45px" android:layout_y="87px" /> <EditText android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Texto2" android:layout_x="90px" android:layout_y="12px" /> <EditText android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Texto 3" android:layout_x="90px" android:layout_y="250px" /></AbsoluteLayout>RelativeLayout Neste layout, os componentes são ajustados através de relacionamentos entre si ouao seu pai. A Figura 13 exibe quatro componentes: um TextView, um EditText e doisButtons. Perceba que o EditText com id textEntry possui um atributo below, informandoque o mesmo deve ser posicionado embaixo do TextView label1. O mesmo ocorre com oButton okButton, onde este é ajustado em baixo do EditText textEntry e também éalinhado à direita referente ao seu pai. Um detalhe importante: caso um componentereferencie (por meio da propriedade below, por exemplo) algum outro componente, esteprimeiro deve obrigatoriamente ser definido antes (definindo um nome no atributoandroid:id), caso contrário ocorrerá um erro em sua estrutura de layout. Porém, nem todoscomponentes precisam definir um id (como podemos ver o Button Cancel), sendo isso
  10. 10. 10somente necessário se em algum local de seu layout este componente será referenciado. AListagem 4 mostra um exemplo de tela de autenticação que utiliza RelativeLayout.Figura 13. Utilizando componentes relativamente com RelativeLayout.Figura 14. Ajustando os componentes relativamente com RelativeLayout.Listagem 4. relativelayout.xml<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="wrap_content" android:layout_height="fill_parent"> <TextView android:id="@+id/tvLogin" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:text="Usuário:" /> <EditText android:id="@+id/etLogin" android:layout_width="250px" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:text="usuario" android:layout_below="@id/tvLogin" /> <TextView android:id="@+id/tvSenha" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:text="Senha:" android:layout_below="@id/etLogin" />
  11. 11. 11 <EditText android:id="@+id/etSenha" android:layout_width="250px" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:text="Texto2" android:password="true" android:layout_below="@id/tvSenha" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Logar" android:layout_centerHorizontal="true" android:layout_below="@+id/etSenha" /></RelativeLayout>TableLayout O TableLayout comporta seus filhos em linhas e colunas. Cada filho é representadopelo componente TableRow (que também é uma espécie de LinearLayout restrito nadireção horizontal) que permite que uma ou mais células sejam adicionadoshorizontalmente, sendo que cada célula pode conter somente um único View (Figura 15). O número de colunas é definido pela linha que tiver mais células. Este layout nãomostra as linhas utilizadas para dividir TableRows, colunas ou células (mostradas emlinhas tracejadas vermelhas). Conforme uma TableRow for sendo adicionado, o próximoserá adicionado abaixo da anterior e assim sucessivamente. As células podem ser vazias eas colunas podem ser ocultadas, podem ser marcadas para preencherem o espaço restanteda tela ou para que sejam compressíveis para forçar que estas sejam ajustadas até quecompletem o espaço restante da tela. Caso o atributo android:layout_width eandroid:layout_height não sejam declarados, este layout irá forçar para que a largura decada componente seja automaticamente FILL_PARENT e a altura WRAP_CONTENT. AListagem 5 exibe o arquivo XML definido para TableLayout e a Figura 16 exibe este layoutno emulador.Figura 15. Representação de tabela como layout para componentes com TableLayout.
  12. 12. 12Figura 16. Exemplo de TableLayout no emulador.Listagem 5. tablelayout.xml<?xml version="1.0" encoding="utf-8"?><TableLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="wrap_content" android:layout_height="fill_parent"> <TableRow> <TextView android:text="Nome:" /> <EditText android:text="Ramon Rabello" /> </TableRow> <TableRow> <TextView android:text="Data Nasc.:" /> <EditText android:text="21/03/1986" /> </TableRow> <TableRow> <Button android:text="Cadastrar" /> </TableRow></TableLayout>Criando layouts complexos Agora, reunindo tudo que foi aprendido até esta etapa, podemos construiraninhamentos de layouts para desenvolvermos nossas interfaces gráficas mais ricas ecomplexas, como mostra a Figura 17, na qual mais externamente temos um TableLayoutque possui um TableRow que possui dois filhos: do lado esquerdo um AbsoluteLayout edo outro lado, um LinearLayout com direção vertical, ambos comportando Views. Percebaque, mesmo com esse nível de complexidade, todos os filhos (tantos os Views quanto osViewGroups) se comportam especificamente de acordo com o layout pai graças às suaspropriedades de parâmetros de layout (definidas nas subclasses deViewGroup.LayoutParams). Às vezes, construir layouts pode se tornar uma atividadecansativa, haja vista o número de variáveis que deverão ser ajustadas manualmente noarquivo XML. Pensando nisso, foi desenvolvida uma ferramenta Open Source chamadaDroidDraw que facilita o desenvolvimento não só destes layouts mas também doswidgets. Ela pode ser carregada tanto como um Applet ou em modo Standalone(executando um jar). Para baixá-la e maiores informações, acesse o linkhttp://droiddraw.org. A Listagem 6 mostra como definimos esta estrutura no arquivoXML de layout e a Figura 18 mostra este layout no emulador.
  13. 13. 13Figura 17. Aninhando layouts para construir layouts complexos.Figura 18. Reproduzindo layouts complexos.Listagem 6. complexlayout.xml<?xml version="1.0" encoding="utf-8"?><TableLayout android:layout_width="fill_parent" android:layout_height="fill_parent" xmlns:android="http://schemas.android.com/apk/res/android"> <TableRow> <AbsoluteLayout android:layout_width="fill_parent" android:layout_height="fill_parent"> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="View" android:layout_x="10px" android:layout_y="123px" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="View" android:layout_x="10px" android:layout_y="12px" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="View" android:layout_x="66px" android:layout_y="67px" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="View"
  14. 14. 14 android:layout_x="120px" android:layout_y="12px" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="View" android:layout_x="120px" android:layout_y="123px"> </Button> </AbsoluteLayout> <LinearLayout android:orientation="vertical"> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="View" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="View" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="View" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="View" /> </LinearLayout> </TableRow></TableLayout>Estendendo layouts Android não possui somente os componentes de layouts que foram explicados emseções anteriores. Eles são os principais e a plataforma ainda disponibiliza uma gama delayouts que utilizaram como base estes. A Tabela 1 mostra alguns exemplos desteslayouts. Porém, caso nenhum destes se enquadrem nas especificações gráficas da suaaplicação, a plataforma possui um framework que permite que layouts sejam estendidospara suprir as necessidades do seu projeto. Para exemplificarmos, criaremos uma aplicação simples que permite simular(utilizando mocks) a previsão do tempo das cidades do Brasil. Para isso, será utilizadauma lista que, em vez de ser representada por um simples ListView (que é o componenteque visualiza uma listagem de Views - por padrão, este componente exibe TextViews emsua listagem), conterá elementos que representam um layout, que mostrará o nome dacidade, a temperatura e uma imagem representando o status do clima. Achouinteressante? Então vamos à prática! Criaremos um novo projeto e definiremos as nossasclasses que serão utilizadas no novo layout. A seguir serão descritas cada classe. Primeiramente, definiremos uma Enumeration (Listagem 7) que representará ospossíveis status do clima: que no nosso exemplo será somente chuvoso, ensolarado ounublado. Depois definimos uma classe (Listagem 8) que será o bean (modelo) responsávelpela representação dos dados climáticos. Foi criado também o método utilitáriogetStatusClimaResource(), que será utilizado para referenciar as imagens (que estão nodiretório res/drawable/) de acordo com a classe R.java, os quais representarão os statusdo clima, sendo carregada uma imagem padrão já disponível na plataforma(android.R.drawable.unknown_image) caso nenhuma imagem possa ser carregada. Seguindo, criamos outra classe, ClimaAdapterView, (Listagem 9) que irá estenderLinearLayout. Tivemos que estendê-la, pois em Android não existe (ainda) umcomponente que exiba, em uma única linha da lista, tanto textos como imagens. Então, definimos o construtor desta classe passando como parâmetro um Context(Interface que permite funionalidades de um ambiente de aplicação, como carregamentode Activities, disparo de Intents, etc), que será a nossa ListActivity (subclasse indireta deContext) que será explicada futuramente (Listagem 11). Outro parâmetro é uma referênciapara o bean Clima que contém os dados climáticos encapsulados. Chamamos o construtor de LinearLayout (super(context)) e passamos o context.Agora, ajustamos a direção deste layout para horizontal, por meio do métodosetOrientation() (equivalente ao atributo android:layout_orientation) e configuramos os
  15. 15. 15parâmetros de layout para cada objeto utilizando LinearLayout.LayoutParams,começando primeiramente para a cidade (cidadeParams). Em LinearLayout.Params, passamos no seu construtor as informações de largura(100) e altura (LayoutParams.WRAP_CONTENT) e depois, no métodos setMargins()ajustamos as margens (todos com valor 1) da esqueda, de cima, da direita e de baixo desteobjeto, respectivamente. Instanciamos o TextView tvCidade, passamos ao seu construtorum context, setamos seu texto utilizando o bean clima, o tamanho do texto (14f), a cor(Color.WHITE) e o tipo da fonte como negrito (Typeface.DEFAULT_BOLD). Adicionamoseste TextView com os parâmetros de layout ao nosso layout chamando o métodoaddView(). Configuramos depois os parâmetros de layouts de tvTemperatura(temperaturaParams) e ivStatusClima (statusClimaParams), a seguir os adicionamos nonosso layout. Definimos agora a nossa classe ClimaAdapter (Listagem 10) que realizará, de fato, alistagem de objetos Climas. Se você observar, ela estende BaseAdapter, que é a classe basepara objetos que queiram servir como ponte entre os dados e a interface gráfica, que seráutilizada para visualizá-los de acordo com alguma fonte de dados (arrays, Cursors, etc).Ela é utilizada por AdapterViews, que são Views cujo seus filhos são determinados porum Adapter, como é o caso de ListView, que usa um ListAdaper. Resumindo: todo essemecanismo é o padrão MVC (Modelo-Visão-Controle) “por trás dos panos”, que foifortemente utilizado na plataforma Android para podermos realizar o binding de dados(modelo) com os Views (visão) utilizando Adapters (controle), diminuindo o grau deacoplamento entre ambos. Continuemos a análise de nosso Adapter. Declaramos dois objetos: um Contextrepresentando nossa ListActivity e um List (climas) que conterá objetos Climas que serãovisualizados na lista. Como BaseAdapter é abstrata, devemos implementar os métodosabstratos (na verdade, estes métodos pertencem à interface Adapter) que são: getCount(),utilizado para retornar o número de objetos dentro da lista, que será o tamanho de nossaList; getItem(), que retorna o item (Object) referente a uma posição na lista; getItemId()que retorna o id do item de acordo com uma posição na lista; e getView(), que recebe trêsparâmetros: a sua posição, um View e um ViewGroup, que será o layout ao qual esteobjeto pertence. Obtemos o objeto em determinada posição da lista chamandoclimas.get(position), que no nosso caso será um Clima. Depois, instanciamosClimaAdapterView que será a nossa extensão de LinearLayout. De uma maneira bemsimples: a nossa lista conterá elementos que serão objetos da classe ClimaAdapterView. Agora criaremos nossa Activity (ClimaAdapterActivity) responsável por visualizarnosso layout customizado. Observe que ela estende ListActivity pois nossa aplicaçãoutilizará uma lista. Sobrescrevemos onCreate() de ListActivity, que é o primeiro método aser chamado quando a Activity é criada. Depois, chamamos o método onCreate() da superclasse e carregamos o layout atualque será utilizado por meio do método setContentView(). Perceba em main.xml nodiretório res/layout/, (Listagem 12) que nosso layout será carregado utilizando um<LinearLayout>. Aninhado a este existe a tag <ListView> com o atributo android:id quepossui o valor “@+id/android:list”informando que a lista a ser carregada será uma pré-definida pela plataforma. A tag <TextView> representa um texto que mostrará umamensagem caso não exista nenhum elemento na lista. Essa mensagem é referenciada peloatributo android:text com o valor ”@string/sem_itens”, que está no arquivo strings.xml(Listagem 13). Agora instanciaremos um ArrayList que representará a fonte de dados que
  16. 16. 16passaremos para ClimaAdapter mais à frente. Agora, instanciamos e adicionamos na lista(climas) vários objetos Clima, passando no seu construtor o nome da cidade, a suatemperatura, e o status do clima, respectivamente. Aqui vem uma das partes mais interessantes: instanciamos o objeto ClimaAdapter epassamos em seu construtor a referência this, representando a ClimaAdapterActivity, e oArrayList de climas. Finalmente, chamamos o método setListAdaper() e passamos umClimaAdapter (climaAdapter) como parâmetro, responsável pelo binding com os dados eo elemento que representará a lista. Na Figura 19, podemos visualizar no emulador oestágio final de nosso novo layout em ação.ViewGroup DescriçãoGallery Exibe uma lista de imagens (com rolagem para a direita e esquerda).GridView Exibe uma grade com rolagem que possui linhas e colunas.ListView Exibe uma lista de Views (apenas uma coluna).ScrollView Uma coluna de elementos com rolagem na vertical.Spinner Exibe um único item por vez, de acordo com uma lista de dados, dentro de uma caixa de texto de uma única linha. Semelhante à uma listbox que pode realizar a rolagem horizontalmente ou verticalmente.SurfaceView Permite acesso direto a uma superfície de desenho, possibilitando que seus filhos sejam dispostos em cima esta superfície. Porém, este componente deve ser utilizado para aplicações que desejem desenhar pixels em vez de widgets.TabHost Componente que permite que várias abas sejam adicionadas, selecionadas e que possam reagir a eventos de cliques do mouse.ViewFlipper Uma lista que exibe um componente por vez, dentro de uma caixa de texto de uma única linha. Este componente pode ser configurado para trocar (exibir outro) componente de acordo com determinado intervalo, como se fosse um slideshow.ViewSwitcher O mesmo que ViewFlipper.Tabela 1. Outros Layouts disponíveis em Android.Listagem 7. StatusClima.javapackage android.clima.adapter;public enum StatusClima { DESCONHECIDO, ENSOLARADO, NUBLADO, CHUVOSO}Listagem 8. Clima.javapackage android.clima.adapter;public class Clima { public String cidade; private int temperatura; private StatusClima statusClima = StatusClima.DESCONHECIDO; /* construtor e gets/sets */ public int getStatusClimaResource() { switch (statusClima) { case ENSOLARADO: return R.drawable.ensolarado; case NUBLADO: return R.drawable.nublado; case CHUVOSO: return R.drawable.chuvoso; } return android.R.drawable.unknown_image; }}Listagem 9. ClimaAdapterView.java
  17. 17. 17package android.clima.adapter;/* imports */public class ClimaAdapterView extends LinearLayout { public ClimaAdapterView(Context context, Clima clima) { super(context); this.setOrientation(HORIZONTAL); LinearLayout.LayoutParams cidadeParams = new LinearLayout.LayoutParams(100, LayoutParams.WRAP_CONTENT); cidadeParams.setMargins(1, 1, 1, 1); TextView tvCidade = new TextView(context); tvCidade.setText(clima.getCidade()); tvCidade.setTextSize(14f); tvCidade.setTextColor(Color.WHITE); tvCidade.setTypeface(Typeface.DEFAULT_BOLD); addView(tvCidade, cidadeParams); LinearLayout.LayoutParams temperaturaParams = new LinearLayout.LayoutParams(40, LayoutParams.WRAP_CONTENT); temperaturaParams.setMargins(2, 2, 2, 2); TextView tvTemperatura = new TextView(context); tvTemperatura.setText(Integer.toString(clima.getTemperatura())+"ºC"); tvTemperatura.setTextSize(14f); tvTemperatura.setTypeface(Typeface.DEFAULT_BOLD); tvTemperatura.setTextColor(Color.WHITE); addView(tvTemperatura, temperaturaParams); LinearLayout.LayoutParams statusClimaParams = new LinearLayout.LayoutParams(25, LayoutParams.WRAP_CONTENT); ImageView ivStatusClima = new ImageView(context); ivStatusClima.setImageResource(clima.getStatusClimaResource()); addView(ivStatusClima, statusClimaParams); }}Listagem 10. ClimaAdapter.javapackage android.clima.adapter;/* imports */public class ClimaAdapter extends BaseAdapter { private Context context; private List<Clima> climas; /* constructor */ public int getCount() { return climas.size(); } public Object getItem(int position) { return climas.get(position); } public long getItemId(int position) { return position; } public View getView(int position, View convertView, ViewGroup parent) { Clima clima = climas.get(position); return new ClimaAdapterView(this.context, clima ); }}Listagem 11. ClimaAdapterActivity.javapackage android.clima.adapter;/* imports */public class ClimaAdapterActivity extends ListActivity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); setContentView(R.layout.main); ArrayList<Clima> climas = new ArrayList<Clima>(); Clima w = new Clima("Belém", 32, StatusClima.ENSOLARADO); climas.add(w); w = new Clima("São Paulo", 17, StatusClima.NUBLADO);
  18. 18. 18 climas.add(w); w = new Clima("Recife", 18, StatusClima.CHUVOSO); climas.add(w); w = new Clima("Rio de Janeiro", 22, StatusClima.ENSOLARADO); climas.add(w); ClimaAdapter climaAdapter = new ClimaAdapter(this,climas); setListAdapter(climaAdapter); }}Listagem 12. main.xml<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <ListView android:id="@+id/android:list" android:layout_width="fill_parent" android:layout_height="fill_parent"/> <TextView android:id="@+id/android:empty" android:layout_width="fill_parent" android:layout_height="fill_parent" android:text="@string/sem_itens"/></LinearLayout>Listagem 13. strings.xml<?xml version="1.0" encoding="utf-8"?><resources> <string name="app_name">ClimaAdapterView</string> <string name="sem_itens">Não há itens na lista</string></resources>Figura 19. A aplicação carregada utilizando a nossa extensão de LinearLayout.Conclusões Conseguimos perceber ao longo deste artigo como Android facilita odesenvolvimento de interface gráfica com usuário, permitindo que qualquer GUI sejadefinida em um ou mais arquivos XML, o que diminui o nível de acoplamento entre GUI eoutras partes do seu código (as suas regras de negócio, por exemplo). Contudo, como
  19. 19. 19vimos na seção anterior, a plataforma permite que componentes gráficos (Views eViewGroups) sejam criados via código, caso o programador assim desejar. Neste artigo, você aprendeu como se criar layouts complexos em Android, sendoexplicado como a plataforma implementa a hierarquia de componentes de tela e como oscomponentes respeitam os limites de seus pais. Além disso, você aprendeu como reunir oslayouts e aninhá-los, a fim de construir estruturas gráficas mais complexas. Finalmente, foidemonstrado como estender layouts para incrementar a parte de interface gráfica da suaaplicação, caso as fornecidas por Android não sejam suficientes. Em um próximo artigoiremos explorar os tipos de recursos (imagens, cores, animações, estilos, etc) disponíveisna plataforma para você utilizar em seus projetos Android. Até a próxima!Links Hierarquia de Componentes de Tela http://code.google.com/android/devel/ui/hierarchy.html Principais Componentes de Layouts http://code.google.com/android/devel/ui/layout.html Documentação de AdapterView http://code.google.com/android/reference/android/widget/AdapterView.html Documentação de Adapter http://code.google.com/android/reference/android/widget/Adapter.html DroidDraw http://droiddraw.org

×