68349774-Como-criar-interfaces-graficas-com-android.pdf

Embed Size (px)

Citation preview

  • Comeando a Criar Interfaces

    Grficas com Android

    Introduo

    O estudo para criar este artigo foi feito em vrias fontes, mas uma

    chamou a ateno por teu uma seqncia de exemplos muito bem

    explicados e de fcil entendimento. O texto se chama Understanding User Interface in Android.

    Neste artigo vamos aprender como criar interfaces grficas (UI) mais

    bsicas com Android, utilizando o Eclipse como IDE de desenvolvimento.

    Pretendo criar outros artigos falando sobre componentes mais complexos

    ou se aprofundando nos apresentados aqui.

    Para quem est chegando de mundos um pouco mais obscuros em

    relao UI, como o Java ME, a diferena gritante e impressiona. Com

    Android temos gerenciadores de layout sofisticados, componentes

    estilizados com efeitos atrativos graficamente, alm de uma facilidade no

    desenvolvimento.

    O Android oferece dois modos de criar interfaces grficas, uma

    definindo um arquivo XML que ser carregado no startup da aplicao e a

    renderizao da tela construda em tempo de execuo. O outro modo

    atravs da codificao pura. Na maioria dos casos o desenvolvedor usar as

    duas maneiras, porm, recomenda-se a preferncia pelo uso do XML.

    Como vimos nos outros publicados por mim no Java Mvel, um

    aplicativo Android ter uma Activity, que responsvel pela interface

    Obs: O Java ME ganhou muito poder UI quando ganhou o

    framework LWUIT, permitindo uso de componentes e gerenciadores de

    layouts. Mas quem programou com Java ME pr-LWUIT sabe das

    dificuldades de criar uma tela amigvel com Canvas. Existem algumas

    plataformas, como a da RIM (responsvel pelos aparelhos BlackBerry)

    que redefiniu o Java ME para suas necessidades. Nestes aparelhos,

    tambm possvel criar telas atraentes para o usurio.

  • grfico da aplicao. Na verdade, ela pode ser imaginada como uma tela do

    seu software.

    Como dissemos anteriormente, existem dois modos de criao de UI

    no Android, aqui vamos nos deter principalmente no XML. Ento, veja o

    exemplo abaixo:

    O XML acima representa a interface grfica, contendo um campo de

    texto em um layout linear, orientado verticalmente. A aplicao deve

    possuir no mnimo uma classe que herde de Activity e sobrecarregue o

    mtodo onCreate:

    @Override

    public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    setContentView(R.layout.main);

    }

    Perceba que definidos a interface atravs de um arquivo XML,

    usando o mtodo setContentView. O R representa a classe com as

    constantes que identificam os recursos da nossa aplicao.

    Obs: A Activity utiliza uma pilha, chamada de activity stack, o

    ndice que estiver no topo da pilha ser a tela exibida para o usurio da

    aplicao. Para quem programa para BlackBerry OS ver grandes

    similaridades com a pilha de Screens desta plataforma.

  • Ao longo deste artigo vamos ver em detalhes o pouco que fizemos

    at aqui, vamos a luta.

    View e ViewGroup

    Quando pensamos em interface grfica de um aplicativo Android

    devemos ter em mente oque significa View e ViewGroup. Ambos

    representam qualquer componente visual que voc visualizar na tela do

    aparelho.

    Como estas classes so de suma importncia para o entendimento do

    texto no geral, vou parafrasear o site oficial de desenvolvedores Android:

    A classe View representa o bloco de construo bsico para

    componentes de interface grfica. Uma View ocupa uma rea retangular na

    tela e responsvel por desenhar e controlar os eventos. View a classe

    bsica para widgets, que so usados para criar componenets de UI

    interativos (botes, caixas de texto, etc.). A subclasse ViewGroup a classe

    base para layouts, que so containers invisveis que contm Views (ou

    outros ViewGroups) e definem as propriedades desse layout. Veja a Figura

    1 para um melhor entendimento.

    Figura 1: Views e Views Group.

    Para fazer com que o leitor entenda definitivamente importncia

    dessas duas classes, veja a Figura 2:

    Na interface existe um vasto conjunto de widgets, desde botes at

    caixas de selees. Todos esses componentes esto dentro de um

    gerenciador de layout, mais precisamente em um LinearLayout.

  • Figura 2: Exemplo real de Views e Views Group.

    Gerenciadores de Layout

    Vamos comear a brincadeira com UI no Android com os

    gerenciadores de layout. Como o prprio nome indica, estas classes

    orientam o posicionamento dos widgets na tela. Dependendo do layout

    utilizado, at a altura e largura do componente alterada.

    Para quem trabalhou com o swing do Java lembra do BorderLayout,

    FlowLayout, dentre outros. At mesmo no Java ME possvel utilizar

    gerenciador parecidos com os mencionados anteriormente, atravs do

    LWUIT.

    Inicialmente vamos criar uma aplicao Android que alteraremos

    conforme o gerenciador de layout a ser estudado.

    o Criando o projeto

    Recapitulando dos nossos artigos anteriores. Siga o caminho file-

    >new->Android Project. Configure as seguintes opes e clique em Ok:

  • Project Name: LayoutsAndroid.

    Contents: Create new project in workspace.

    Target Name: Android 2.1.

    Application Name: Layouts Android

    Package Name: com.estudo.android.

    Create Activity: LayoutsAndroid

    Figura 3: Configuraes do projeto inicial.

  • O Eclipse j cria o projeto e toda a estrutura de pastas e cdigos

    necessria. Execute este projeto e ver o seguinte:

    Figura 3: Projeto inicial emulado.

    D uma olhada tambm no arquivo main.xml, que pode ser

    encontrado no caminho res->layout.

    Listagem 1:

    O nosso exemplo j usa um gerenciador de layout, o LinearLayout,

    que, por acaso, ser nosso primeiro objeto de estudo.

  • o LinearLayout

    Este gerenciador organiza seus componentes filhos em uma nica

    coluna ou nica linha, dependendo da orientao que o mesmo tiver.

    Para ficar mais claro, vamos editar o arquivo main.xml citado

    anteriormente:

    Listagem 2:

    Se executarmos a aplicao agora, veja como fica:

    Figura 4: Projeto alinhados verticalmente.

  • Vamos fazer algumas alteraes no XML para compreender oque ele

    faz. Na declarao do layout, que sempre deve ser o n raiz do documento,

    temos o LinearLayout. Definimos para este componente trs propriedades:

    android:orientation="vertical"

    android:layout_width="fill_parent"

    android:layout_height="fill_parent"

    A orientation defina se os componentes se desenrolaro no sentido

    horizontal ou vertical. Se a tela ter apenas uma linha ou uma coluna, como

    falado anteriormente. Mudemos essa propriedade para:

    android:orientation="horizontal"

    O resultado podemos ver abaixo:

    Tambm definimos as propriedades de largura (width) e altura

    (height). Ambos usam fill_parent, que diz o seguinte: use todo o espao

    disponvel na tela. Vamos mudar novamente o main.xml, mais

    especificamente as propriedades do LinearLayout.

  • android:layout_width="100px"

    android:layout_height="100px">

    O resultado :

    Perceba que o restante dos componentes foi cortado, por exceder os

    limites do seu container, o LinearLayout. Na prtica, porm, vai ser raro as

    vezes em que este gerenciador de layout no vai ocupar todo o espao

    disponvel na tela.

    Existem alguns atributos especficos para componentes que fazem

    todo sentido quando aplicados no LinearLayout. Vamos trabalhar com duas

    propriedades: android:layout_weight e android:layout_gravity.

    Reescreva o main.xml:

    LISTAGEM 3:

    Depois de executar veremos o seguinte:

  • Figura 7: Utilizando gravity e weight.

    A propriedade gravity funciona como uma funo de alinhamento

    em relao ao container, como usamos right no boto, veja que ele se

    encontra na extremidade direita da tela.

    O weight repassa para os componentes o espao no utilizado na tela.

    H, no se preocupem com os componentes, eles sero tratados daqui a

    pouco. Volte para a figura 4 e perceba que o espao vazio desapareceu, sendo atribudo para as duas caixas de textos que definiram a propriedade

    weight. Perceba tambm, que a segunda caixa de texto recebeu 70% do

    espao no utilizado, por isso ficou maior que a primeira caixa.

    Bem, encerramos por aqui a discusso sobre a LinearLayout. H, no

    se preocupe com os widgets (componentes). Logo veremos detalhadamente

    cada um.

    o AbsoluteLayout

    Este gerenciador define exatamente a posio (coordenada x/y) onde

    cada componente deve ficar. Este layout menos flexvel e tambm exige

    um maior trabalho para manuteno. Por exemplo, quando o aparelho

    muda a orientao, quem deve redefinir a posio dos componentes o

    programador, via cdigo.

    Mas chega de conversa, redefina o main.xml para isso:

  • LISTAGEM 4:

    Quando executamos a nossa aplicao fica com a seguinte cara:

    Figura 8: Utilizando AbsoluteLayout.

    Simples n? Mas como o leitor j deve ter percebido, na um

    gerenciador de layout muito aconselhado.

  • o TableLayout

    Este gerenciador pode ser o mais auto-descritivo de todos. Para

    surpresa geral, ele organiza seus componentes filhos em linhas e colunas.

    As linhas da tabela so representadas pela classe TableRow. As

    colunas so criadas conforme a insero de componentes em uma mesma

    linha. No permitido bordas em linhas, colunas e clulas.

    Reescreva o main.xml:

    LISTAGEM 5:

    Para gerar uma interface como a Figura 9:

    Figura 8: Utilizando TableLayout.

    Vrios pontos devem ser detalhados aqui. Primeiramente, veja que

    definimos a largura dos componentes somente para a primeira linha. Isso

  • porque a coluna define sua largura como igual a largura do maior

    componente horizontal. Assim, se redefinirmos a ltima caixa de texto e o

    boto para:

    O resultado da interface vai ser o mesmo. Tanto o campo de texto de

    endereo como o boto tem largura menor que a primeira caixa de texto.

    Na ltima linha colocamos um campo de texto vazio:

    Isso deve ser feito para que no ocorra o seguinte efeito:

    Figura 8: Utilizando TableLayout com espao a mais.

    o RelativeLayout

    O RelativeLayout trabalha da seguinte forma. Cada componente filho

    deve indicar sua posio em relao a outro componente.

    Vamos comear nossos estudos com este main.xml.

  • LISTAGEM 6:

    O primeiro componente, um texto esttico, est orientado em relao

    ao sei pai, ou seja, ao prprio layout. Ento, definimos que ele estar a

    esquerda e ao topo da tela.

    android:layout_alignParentTop="true"

    android:layout_alignParentLeft="true"

    Antes de prosseguir, veja como fica esta interface em trabalho.

  • Figura 9: Utilizando RelativeLayout.

    A caixa de texto tem sua localizao definida com:

    android:layout_alignLeft="@+id/lblComments"

    android:layout_below="@+id/lblComments"

    O layout_alignLeft diz que o componente estar alinhado a esquerda

    do componente com o id lblCmments, que neste caso, o texto esttico

    Idias. Tambm, usamos o layout_below para dizer que este componente estar logo abaixo do mesmo componente de texto lblComments.

    O boto de lixeira define sua localizao com;

    android:layout_below="@+id/txtComments"

    android:layout_alignLeft="@+id/txtComments"

    Exatamente da forma como definimos nossa caixa de texto, exceto

    pela mudana do componente referenciado. Agora indicamos o

    txtComments como ponto de referncia.

    Finalmente, temos o boto salvar:

    android:layout_below="@+id/txtComments"

    android:layout_alignRight="@+id/txtComments"

    A nica mudana de alignLeft para alignRight.

  • O desenvolver tem acesso as seguinte propriedades para definir o

    posicionamento dos componentes no RelativeLayout:

    * layout_above

    * layout_alignBaseline

    * layout_alignBottom

    * layout_alignLeft

    * layout_alignParentBottom

    * layout_alignParentLleft

    * layout_alignParentRight

    * layout_alignParentTop

    * layout_alignRight

    * layout_alignTop

    * layout_Below

    * layout_centerHorizontal

    * layout_centerInParent

    * layout_centerVertical

    * layout_leftOf

    * layout_rightOf

    * layout_true

    o FrameLayout

    O FrameLayout reserva um espao na tela que deve ser utilizado por

    uma View. Se mais de uma View for colocada nesta rea, haver

    sobreposio de componentes, com o ltimo que foi inserido aparecendo

    por primeiro.

    Vamos a codificao. Altere main.xml:

    LISTAGEM 7:

  • android:layout_height="wrap_content"

    android:layout_width="wrap_content"

    android:layout_y="104dip">

    Neste XML, apenas o TmePicker pode parecer estranho, mas ele

    somente um widget para escolher uma hora do dia. Veja visualmente como

    fica a execuo da aplicao com este XML:

    Figura 10: Utilizando FrameLayout.

    Estamos usando o FrameLayout dentro de um AbsoluteLayout, logo,

    devemos especificar sua posio em coordenadas x, y. O FrameLayout

    possui apenas uma widget, o TimePicker.

    At aqui parece que no veremos nada de diferente nesse layout. Mas

    vamos tentar adicionar mais um componente no XML:

  • android:layout_width="wrap_content"

    android:layout_y="104dip">

    Agora iniciamos a aplicao e veremos isto:

    Perceba que o boto sobreps o TimePicker. Isso acontece porque o

    FrameLayout mostra apenas uma View.

    o ScrollView

    Agora fiquei em dvida entre qual dos layout o mais auto-

    descritivo: TableLayout ou ScrollView. Este ltimo, mostra apenas uma

    ViewGroup que pode exceder os limites da tela fsica do aparelho.

    Geralmente o ViewGroup utilizado um LinearLayout.

  • Falta pouco, vamos editar pela ltima vez o main.xml neste tpico de

    layouts.

  • Este layout no tem mistrio, o leitor j deve at estar visualizando

    mentalmente como ficar a execuo do aplicao desta vez. Veja na

    Figura abaixo:

    Veja a barra no lado direito. Fcil esse scroll view hein.

  • Views

    Depois que aprendemos sobre os gerenciadores de layout,

    representados pelos ViewsGroups, est na hora de aprender sobre s os

    componentes, representados pelas classes que herdam de View.

    Para melhor compreenso, vamos dividir este tpico em cinco reas:

    Views bsicas: para criar componentes bsicos, como caixa de textos e botes;

    Pickers Views: componentes especiais que permitem o usurio selecionar de uma certa fonte;

    Views de listas: componentes que mostram uma lista de informaes;

    Views para imagens: componentes especializados para tratamento com imagens. Vocs iro se surpreender com estes componentes;

    Menus;

    Extras.

    Antes de iniciarmos este instigante tpico de estudo, vamos criar um

    novo projeto no Eclipse, chamado ViewsAndroid. Como o leitor j sabe os

    passos, s vou deixar a imagem com as configuraes:

  • Agora vamos partir para a ao.

    o BasicViews - Incio

    As views bsicas no precisam de muita explicao, o leitor j deve

    ter usado elas intensamente em qualquer software. E, se o leitor for

    programador, ento j deve ter criado milhares destes componentes:

  • TextView

    EditText

    Button

    ImageButton

    CheckBox

    ToggleButton

    RadioButton

    RadioGroup

    Vamos editar nosso main.xml do projeto recm criado. Reescreva-o

    com as seguintes informaes:

  • android:layout_width="fill_parent"

    android:layout_height="wrap_content"

    android:orientation="vertical"

    >

    Rode este projeto e vers o seguinte resultado:

    Figura 14: Exemplo de Views.

    O primeiro componente um TextView, dispensando maiores

    apresentaes. O segundo componente um Button, tambm muito auto-

  • explicativo. O terceiro componente um ImageButton, mesclando uma

    imagem ao boto tradicional. Aqui podemos perceber um ponto

    interessante na forma de programar do Android. Sempre devemos definir a

    fonte da imagem, no nosso exemplo utilizamos:

    android:src="@drawable/icon"

    O leito deve estar lembrado que na classe Activity usamos a seguinte

    linha de cdigo:

    setContentView(R.layout.main);

    Ou seja, ambos referem-se aos recursos localizados na pasta res. A

    diferena que no primeiro caso acessamos estes recursos atravs do

    XML, sendo assim devemos definir um @, a localizao do recurso (drawable, layout ou values) e o nome. No ltimo caso acessamos o

    recurso atravs do cdigo Java. Sendo assim, voc indica a classe R e, o

    caminho referente ao recurso desejado.

    Seguindo com o exemplo da Figura 14. O quarto componente um

    campo de texto, representado pela classe EditView. O quinto componente

    um simples CheckBox. O sexto componente tambm um CheckBox, mas

    com uma especificidade. Redefinimos seu estilo, veja:

    style="?android:attr/starStyle"

    O stimo e oitavo componente so instncias de RadioButton, dentro

    de um ButtonGroup. Finalmente, o ltimo componente um ToggleButton,

    um boto estilizado com dois estados: on e off.

    Tambm podemos mudar os textos do ToggleButton. Adicione mais

    duas propriedades ao ltimo componente citado:

    android:textOn="Sim"

    android:textOff="No"

    Agora o componente apresenta textos definidos pelo programador, e

    no aqueles padres, veja:

  • Outro componente que possui atributos importantes para serem

    citados aqui, o EditText. Em alguns casos, o programador adiciona um

    campo de texto onde o usurio informa sua senha, sendo assim, o texto

    deve ser substitudo por asteriscos. Para atingir este objetivo, existe uma

    propriedade que pode ser adicionada ao EditText:

    Veja oque acontece:

    o BasicViews Tratamento de Eventos

    At agora s mostramos alguns componente na tela, mas no

    inserimos nenhum tratamento de eventos. E como podemos fazer isso?

    No incio deste artigo falamos rapidamente que a interface grfica de

    um aplicativo pode ser construda de duas maneiras: diretamente com o

    XML ou codificando cada componente. Por exemplo, j usamos o

    TextView no XML, porm, existe uma classe TextView que pode ser

    instanciada e tratada diretamente via cdigo.

  • Mesmo quando optamos por criar a interface via XML, que mais

    indicada inclusive pelo site de desenvolvedores do Android, vamos usar a

    codificao pura em Java para tratar dos eventos.

    Vamos alterar a classe ViewsAndroid, localizada na pasta

    com.estudo.android, em src:

    Listagem 11:

    1: package com.estudo.android;

    2:

    3: import android.app.Activity;

    4: import android.os.Bundle;

    5: import android.view.View;

    6: import android.widget.CheckBox;

    7: import android.widget.Toast;

    8;

    9: public class ViewsAndroid extends Activity {

    10: /** Called when the activity is first created. */

    11: @Override

    12: public void onCreate(Bundle savedInstanceState) {

    13: super.onCreate(savedInstanceState);

    14: setContentView(R.layout.main);

    15:

    16: CheckBox checkBox=(CheckBox)

    findViewById(R.id.chkAutosave);

    17: checkBox.setOnClickListener(new View.OnClickListener()

    18: {

    19: public void onClick(View v) {

    20: Toast.makeText(getBaseContext(),

    "Salvar

    "+(((CheckBox)v).isChecked()?"Aut.":"Man."),

    Toast.LENGTH_SHORT).show();

    21: }

    22: });

    23:

    24: }

    25:}

    No sei se vocs perceberam que em todos widgets (componentes)

    criados at aqui, sempre definimos uma propriedade android:id. Essa

    identificao usada para recuperar este componente no cdigo Java

    atravs do mtodo findViewById(), linha 16 da listagem de cdigo 16 .

    Com posse da instncia de CheckBox podemos configurar um

    listener para o evento de clique, usando o mtodo setOnClickListener e

    passando por parmetro uma instncia de OnClickListener.

    Na Listagem de cdigo isso feito na linha 17. Perceba que

    instanciamos a classe passada para o mtodo da mesma linha. Quando

    definimos o mtodo OnClickLisener devemos redefinir o comportamento

    do mtodo onClick. Este, por sua vez, programa oque acontecer quando o

    comportamento receber o evento de clique.

  • Veja nas Figuras abaixo oque programos para o momento em que o

    boto for selecionado como checado e no-checado. Inicialmente o

    CheckBox est desativado, ento, quando ele for selecionado mostramos

    Salvar Aut., caso inverso mostramos Salvar Man..

    Figura 15: CheckBox ativado. Figura 16: CheckBox desativado.

    Esse texto que aparece na tela um Toast. Veja a linha de cdigo 20

    da Listagem 11. Usamos o mtodo esttico makeToast() que recebe os

    seguintes parmetros: um contexto, a mensagem e um inteiro que define a

    durao. No temo usamos a constante LENGHT_SHORT.

    Para os componentes Button e ToogleButton tambm podemos usar o

    OnClickListener. Para o RadioButton vamos utilizar o

    OnCheckedChangeListener.

    Vamos fazer algumas alteraes no exemplo anterior, assim, o

    ChangeLisener ser compreendida perfeitamente.

    A idia associar uma imagem com o campo de escolha do sexo.

    Sendo assim, a primeira mudana no main.xml, adicionando mais uma

    propriedade ao boto de escolha do sexo masculino.

    Com isso, a opo de Masculino vai vir marcada como padro.

    O primeiro passo criar um widget ImageView na nossa tela.

    Inicialmente ela mostrar uma imagem do sexo masculino:

  • Ao rodar este aplicativo veremos o seguinte:

    Figura 17: RadioButton masculino selecionado.

    As imagens que aparecero so da internet, voc por qualquer

    imagem na sua pasta res/drawable e chama-las de menino e menina.

    Se o usurio escolher Feminino ainda no acontece nada. Eu disse ainda, porque vamos mudar isso agora. Veja a Listagem de cdigo 12:

    Listagem 12:

    1:public void onCreate(Bundle savedInstanceState) {

    2: ...

    3: RadioGroup radioGroup = (RadioGroup) findViewById(R.id.rdbSexo);

    4: radioGroup.setOnCheckedChangeListener(new

    OnCheckedChangeListener()

    5: {

    6: public void onCheckedChanged(RadioGroup group, int

    checkedId) {

    7: RadioButton rdb = (RadioButton) findViewById(checkedId);

    8: ImageView img = (ImageView) findViewById(R.id.imgSexo);

    9: if (rdb.getText().equals("Feminino")){

    10: img.setImageResource(R.drawable.menina);

    11: } else {

    12: img.setImageResource(R.drawable.menino);

    13: }

    14: }

    15: });

    16:}

    Na linha 4 adicionamos o OnCheckedChangeListener ao

    componente RadioGroup. Assim, quando um dos RadioButtons for

    selecionado o mtodo onCheckedChanged(), na linha 6, ser notificado. Os

  • parmetros que este mtodo recebe so: o RadioGroup que recebeu a

    iterao e o identificador nico do RadioButton que foi marcado como

    checado.

    Na linha 7 recuperamos o objeto RadioButton atravs do id recebido

    como parmetro. Na linha 8 recuperamos o objeto ImageView da forma j

    conhecida, ou seja, referenciando o componente atravs das constantes da

    classe R.

    Na linha 9 testamos se o texto do RadioButton selecionado igual a

    Feminino. Caso afirmativo, devemos configurar a fonte do ImageView para a imagem da menininha. E isso que fizemos na linha 11. Caso o teste

    booleano resulte em false, a imagem mostrada deve ser do menino (como j

    foi mostrado na Figura 17).

    Agora podemos executar o aplicativo novamente e marcar a caixa de

    seleo Feminino. Veremos algo semelhante ao mostrado na Figura 18:

    Figura 18: RadioButton masculino selecionado.

    o BasicViews Barra de Progresso

    A barra de progresso um componente muito comum em qualquer

    interface de usurio. Seus exemplos de uso podem ser: acompanhar quantos

    bytes foram transmitidos quando envia seu relatrio para seu chefe,

    acompanhar um processamento um pouco mais pesado e no pensar que a

    aplicao deu erro e est travada, dentre outros.

    Vamos criar uma nova tela para vermos o comportamento desse

    widget. Crie um novo arquivo .xml em res/layout, chamado

    barradeprogresso.xml. Veja como na Figura 19:

  • Figura 19: Criando o barradeprogresso.xml.

    Edite o barradeprogresso.xml com o cdigo da Listagem 13:

    Listagem 13:

  • Mude tambm a classe ViewsAndroid (Listagem 14).

    Listagem 14:

    package com.estudo.android;

    import android.app.Activity;

    import android.os.Bundle;

    public class ViewsAndroid extends Activity {

    /** Called when the activity is first created. */

    @Override

    public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    setContentView(R.layout.barradeprogresso);

    }

    }

    Depois de executar o aplicativo temos:

    Essa a forma mais bsica da barra de progresso do Android, d uma

    olhada nas propriedades e ver que no acrescentamos nada de novo ao que

    j vnhamos utilizando. O modo que estamos usando este componente

    padrozinado, seu ciclo indeterminado. til para operaes que no temos

    idia de quando sero finalizadas.

    No cdigo acima a barra de progresso (que mais parece um crculo

    de progresso) vai ficar na tela infinitamente. Vamos adicionar o cdigo da

    Listagem 15 no onCreate:

    Listagem 15:

    1:progressBar = (ProgressBar) findViewById(R.id.progressbar);

    2:

    3:new Thread(new Runnable() {

    4: public void run() {

    5: while (progressStatus < 10) {

    6: progressStatus++;// = doSomeWork();

    7: try {

  • 9: Thread.sleep(500);

    10: } catch (InterruptedException e) {

    11: e.printStackTrace();

    12: }

    13: }

    14:

    15: progressBar.setVisibility(8);

    16: }

    17:}).start();

    A Listagem 15 recupera o objeto PorgressBar logo na primeira

    linha. Posteriormente, adicionamos uma rotina com cdigo Java puro, que

    apenas roda uma Thread enquanto a varivel progressStatus for menor que

    10. Depois disse ele muda a visibilidade do ProgressBar, para 8.

    Execute o aplicativo, espere alguns segundos e...

    Como assim? Que erro esse?

    Substitua a linha 15 pelo conjunto de linhas de cdigo abaixo:

    handler.post(new Runnable() {

    public void run() {

    progressBar.setVisibility(8);

    }

    });

  • O erro aconteceu porque dentro de uma Thread, no possvel lanar

    outra linha de execuo. O Handler permite que isso acontece trabalhando

    diretamente com o sistema operacional. Depois da correo voc pode

    reiniciar a aplicao e esperar alguns segundos que o ProgressBar

    desaparecer da tela.

    Mas ainda ficou uma questo em aberto. Reveja a linha de cdigo:

    progressBar.setVisibility(8);

    Afinal, oque significa o parmetro 8. O ProgressBar pode ter trs

    estados possvel, identificados por nmeros inteiros:

    0 visvel

    4 invisvel

    8 finalizado

    Por exemplo, se mudarmos a linha do setVisibly para:

    progressBar.setVisibility(4);

    Depois do mesmo intervalo de tempo veramos:

  • Mas ainda no acabamos a discusso sobre o ProgressBar. Outra

    propriedade interessante a possibilidade de mudar o estilo do widget. O

    primeiro passo redefinir o widget em nosso xml:

    Fizemos duas coisas. O atributo style define o estilo do componente.

    O android:max define o valor mximo da barra de progresso (que agora

    sim ter um formato de barra de progresso).

    Na classe ViewsAndroid redefina o bloco de cdigo dentro do while

    para:

    while (progressStatus < 50) {

    progressStatus++;

    handler.post(new Runnable() {

    public void run() {

    progressBar.setProgress(progressStatus);

    }

    });

    try {

    Thread.sleep(100);

    } catch (InterruptedException e) {

    e.printStackTrace();

    }

    }

    Perceba que implementamos o mtodo setProgress dentro do lao,

    ou seja, a cada iterao a barra de progresso aumenta sua rea completada.

    Depois chegar aos 50 (seu valor mximo) ela ainda dever sumir, portanto,

    o restando do cdigo permanece igual.

    Execute novamente o aplicativo e recebera:

  • o BasicViews AutoCompleteTextView

    O AutoCompleteTextView filho de TextView, sendo assim, ele traz

    um campo para insero de texto. Seu diferencial a possibilidade de

    definir um conjunto de Strings que funcionam como auto complemento do

    texto que est sendo digitado pelo usurio.

    Reescreva o barradeprogresso.xml com o cdigo da Listagem 16:

    Listagem 16:

    At este momento apenas criamos o campo de texto. Se olharmos o

    aplicativo nesse momento a interface conter apenas uma caixa de exto

    normal, sem complemento de cdigo nenhum.

    Agora vamos editar tambm o ViewsAndroid com o texto da

    Listagem 17:

    Listagem 17:

    package com.estudo.android;

    import android.app.Activity;

    import android.os.Bundle;

    import android.widget.ArrayAdapter;

    import android.widget.AutoCompleteTextView;

    public class ViewsAndroid extends Activity {

    1:

    2: String[] estadios = { "Soccer City", "Ellis Park",

    "Moses Mabhida", "Peter Mokaba", "Mbombela Stadium",

    "Loftus Versfeld", "Royal Bafokeng", "Free State",

    "Green Point", "Nelson Mandela Bay" };

    /** Called when the activity is first created. */

    @Override

    3: public void onCreate(Bundle savedInstanceState) {

    4: super.onCreate(savedInstanceState);

    5: setContentView(R.layout.barradeprogresso);

    6:

  • 7: ArrayAdapter adapter = new

    ArrayAdapter(this, android.R.layout.

    simple_dropdown_item_1line, estadios);

    8: AutoCompleteTextView textView = (AutoCompleteTextView)

    findViewById(R.id.txtEstadios);

    9: textView.setThreshold(3);

    10: textView.setAdapter(adapter);

    11: }

    12:}

    Vamos examinar o cdigo a partir da linha 8. Neste ponto criamos a

    instncia de AutoCompleteTextView. Na linha 9 usamos o mtodo

    setThreshold para definir que depois da terceira letra o complemento j

    pode trabalhar e, finalmente, na linha 10 adicionamos o ArrayAdapter ao

    componente, este, definir os textos que podem ser usados no

    complemento.

    O ArrayAdapter, por sua vez, criado na linha 7. O construtor usado

    recebe um contexto, que pode ser this. Recebe tambm um segundo

    parmetro inteiro, que define seu comportamento. O ltimo parmetro

    recebe um vetor de Objects com as Strings para complemento.

    Agora podemos executar a aplicao novamente.

    Perceba que depois que digito a terceira letra, o e,ele me traz as opes cadastradas no ArrayAdapter.

    o PickerViews

    Estetipo de widget permite que o usurio selecione uma data ou hora

    de um componente estilizado e atraente visualmente.

    Vamos criar uma nova interface que pede o nome do usurio, a data

    e hora do nascimento e calcula quantos dias faltam para tira a carteira de

  • habilitao, ou, quantos dias faltam para a aposentadoria (pensando em 65

    anos). Se o usurio tiver mais que 65 anos, mostramos quantas copas o

    usurio j assistiu.

    Crie um novo arquivo XML chamado datahora.xml:

    Listagem 18:

    No XML da Listagem 18 os nicos dois componentes que se

    destacam por serem novos so o DatePicker e o TimePicker. As

    propriedades de ambos j so bem conhecidas do leitor.

    Tambm altere a classe ViewsAndroid usando o cdigo da Listagem

    19:

    Listagem 19: package com.estudo.android;

    import java.util.Calendar;

    import java.util.Date;

    import android.app.Activity;

    import android.os.Bundle;

    import android.view.View;

    import android.widget.Button;

    import android.widget.DatePicker;

    import android.widget.EditText;

    import android.widget.TimePicker;

    import android.widget.Toast;

    public class ViewsAndroid extends Activity {

    private static final String CATEGORIA = "data e hora";

  • /** Called when the activity is first created. */

    @Override

    public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    setContentView(R.layout.datahora);

    }

    }

    Ao executarmos este aplicativo veremos:

    Figura 26: Aplicativo usando DatePicker e TimePicker.

    Nossa aplicao ainda no far nada se clicarmos no boto

    Calcular. Para conseguir isso vamos adicionar o trecho de cdigo da Listagem 20 depois da linha do setContentView no mtodo onCreate.

    1:Button botao = (Button) findViewById(R.id.btnCalcular);

    2;botao.setOnClickListener(new View.OnClickListener(){

    3: public void onClick(View v){

    4: TimePicker hora = (TimePicker) findViewById(R.id.pckHora);

    5: DatePicker data = (DatePicker) findViewById(R.id.pckData);

    6: EditText edtNome = (EditText) findViewById(R.id.txtNome);

    7;

    8: Calendar calNasc = Calendar.getInstance();

    9: calNasc.set(Calendar.YEAR, data.getYear());

    10: calNasc.set(Calendar.MONTH, data.getMonth());

    11: calNasc.set(Calendar.DAY_OF_MONTH, data.getDayOfMonth());

    12: calNasc.set(Calendar.HOUR_OF_DAY, hora.getCurrentHour());

    13: calNasc.set(Calendar.MINUTE, hora.getCurrentMinute());

    14:

    15: Calendar calHoje = Calendar.getInstance();

    16: calHoje.setTime(new Date());

  • 17:

    18: int tempo = calHoje.compareTo(calNasc);

    19:

    20: if (tempo > 0){

    21: calculaData(calNasc, calHoje,

    edtNome.getText().toString());

    22: }

    23: }

    24:});

    Nas duas primeiras linhas configuramos o listener para o

    componente Button. Na linha 3 criamos o mtodo que vai responder por

    todas iteraes.

    Nas linhas 4, 5 e 6 recuperamos os objetos para o TimePicker,

    DatePicker e EditText.

    Na linha 8 criamos a instncia de Calendar que armazena a data de

    nascimento do usurio. Na seqncia de linhas de 9 at 11, configuro os

    valores de ano, ms e data do calendrio, utilizando os mtodos da classe

    DatePicker para recuperar os valores configurados pelo usurio.

    As linhas 12 e 13 configuram a hora do dia e o minuto do nascimento

    do usurio, utilizando mtodos da classe TimePicker. Perceba que no

    tratamos o tempo, apenas inclumos estas linhas de cdigo como

    aprendizado, porm, pode ficar como um tema de casa para o leitor.

    Na linha 15 criamos uma nova instncia de Calendar. Na linha 16

    configuramos a data atual como valor para o objeto criado na linha anterior.

    Na linha 18 utilizamos o mtodo compareTo da classe Calendar para

    pegar um nmero inteiro com a diferena entre as duas datas comparadas.

    Se o valor for maior que zero (teste realizado na linha 20), significa que o

    usurio informou uma data do passado, caso contrrio, a lgica do

    programa no precisa ser concluda porque ningum nasce no futuro, ainda.

    O leitor deve ter percebido que paramos no mtodo calculaData,

    onde passamos trs parmetros: data de nascimento do usurio, data atual e

    nome do usurio.

    Veja na Listagem 21 o cdigo do mtodo calculaData:

    Listagem 21: public void calculaData(Calendar nascimento, Calendar agora, String

    nome){

    int ano = agora.get(Calendar.YEAR);

    int mes = agora.get(Calendar.MONTH);

    int dia = agora.get(Calendar.DAY_OF_MONTH);

    int anoNasc = nascimento.get(Calendar.YEAR);

    int mesNasc = nascimento.get(Calendar.MONTH);

    int diaNasc = nascimento.get(Calendar.DAY_OF_MONTH);

  • int idade = ano - anoNasc;

    if(mes < mesNasc) {

    idade--;

    } else if (mes == mesNasc) {

    if(dia < diaNasc) {

    idade--;

    }

    }

    String mensagem = "";

    if (idade < 18)

    mensagem = nome+ ", faltam "+(18 - idade)+" anos para tirar

    a carteira!";

    else if (idade >= 18 && idade < 65)

    mensagem = "Calma "+nome+", faltam "+(65 - idade)+" anos

    para voc se aposentar";

    else

    mensagem = nome+ ", o senhor j assistiu "+(idade/4)+"

    copas";

    Toast.makeText(getBaseContext(),

    mensagem, Toast.LENGTH_SHORT).show();

    }

    O cdigo da Listagem 21 no tem segredo, apenas cdigo Java.

    Primeiramente calculamos a idade, conforme esse resultado configuramos a

    mensagem do aviso. Finalmente, utilizamos o Toast (j discutido nesse

    texto), para apresentar a mensagem ao usurio.

    Veja o resultado de um dos casos:

    Figura 27: Caso de uso do aplicativo usando DatePicker e TimePicker.

  • No utilizamos muito o TimePicker, mas o aplicativo j mostrou uma

    idia do uso deste componente. Assim como os outros widgets do Android,

    este bem fcil de usa.

    O programador tambm pode usar os pickers um uma janela de

    dilogo. Vamos fazer algumas alteraes, primeiro, no datahora.xml:

    Realmente acho que no preciso explicar o XML. A nossa aplicao

    vai mostrar uma caixa de texto e um boto. O objetivo que ao interagir

    com o boto, o usurio receba uma caixa de dilogo com um seletor de

    hora para configurar seu despertador.

    Vamos alterar o contedo da classe ViewsAndroid. Veja a Listagem

    23:

    Listagem 23:

    1: private static final int TIME_DIALOG_ID = 0;

    2: private TextView lblAlarme;

    3:

    4: /** Called when the activity is first created. */

    5: @Override

    6: public void onCreate(Bundle savedInstanceState) {

    7: super.onCreate(savedInstanceState);

    8: setContentView(R.layout.datahora);

    9: lblAlarme = (TextView) findViewById(R.id.txtAlarme);

    10: Button btn = (Button) findViewById(R.id.btnConfigurar);

    11: btn.setOnClickListener(new View.OnClickListener(){

    12: public void onClick(View v){

    13: showDialog(TIME_DIALOG_ID);

    14: }

    15: });

  • 16:

    17: }

    18: @Override

    19: protected Dialog onCreateDialog(int id)

    20: {

    21: switch (id) {

    22: case TIME_DIALOG_ID:

    23: TimePickerDialog td = new TimePickerDialog(

    24: this, mTimeSetListener, 12, 00, false);

    25:

    26: return td;

    27: }

    28: return null;

    29: }

    30:

    31: private TimePickerDialog.OnTimeSetListener mTimeSetListener =

    32: new TimePickerDialog.OnTimeSetListener()

    33: {

    34: public void onTimeSet(TimePicker view, int hourOfDay, int

    minuteOfHour)

    35: {

    36: lblAlarme.setText("Alarme configurado para " + hourOfDay +

    ":" + minuteOfHour);

    37: }

    38: };

    Na linha 9 recuperamos o objeto TextView, porque vamos editar seu

    texto posteriormente. Na linha 10 recuperamos o objeto Button. Na linha 11

    adicionamos um OnClickListener para o boto recm criado. Quando o

    usurio clicar neste componente vamos abrir uma caixa de dilogo.

    Para que o dilogo mostrado no seja o padro do Android, devemos

    sobrescrever o mtodo onCreateDialog. Tambm por isso, passamos o

    TIME_DILAOG_ID como parmetro, para termos certeza de interceptar

    somente nosso dilogo. Com isso, mensagens vindas diretamente do

    Android continuaro a serem mostradas.

    Dentro do onCreatDialog verificamos se estamos recebendo a

    mensagem do nosso prprio cdigo. Caso afirmativo, instanciamos um

    novo objeto TimePickerDialog (linha 23). Seu construtor recebe um

    Context, um OnTimeSetListener, uma hora e um minuto inicial e, por fim,

    um valor booleano dentificando se o componente trabalhar com 24 horas

    ou, com horas AM e PM.

    Perceba que o OnTimeSetListener foi criado no mesmo cdigo, na

    linha 31, devemos obrigatoriamente implementar o mtodo onTimeSet

    (linha 34). Este ltimo mtodo chamado sempre que a hora configurada

    no TimePickerDialog. Quando isso acontecer apenas mudamos o texto do

    TextView.

    Veja em trs passos a aplicao em funcionamento:

  • Figura 28: Tela inicial da

    aplicao.

    Figura 29: Dilogo aberto aps

    clicar no boto.

    Figura 30: Depois de clicar em

    Set mudamos o texto do TetView.

    o ListViews

    O ListView um componente para mostrar uma grande lista de dados

    com scroll.

    Este componente no precisa de muita explicao, porm, tem

    algumas diferenas significativas com os exemplos que vimos at aqui.

    Para explorar ao mximo este widget vamos criar uma lista com todos os

    pases da copa do mundo de 2010. Ao clicarmos em um dos nomes

    mostramos a posio da seleo no ranking da FIFA.

    Primeiramente vamos criar um novo XML, listview.xml. Veja seu

    contedo na Listagem 24:

    Listagem 24:

  • Ainda no vimos nenhuma novidade, mas veja como ficar nossa

    classe ViewsAndroid na Listagem 25:

    Listagem 25:

    1:public class ViewsAndroid extends ListActivity {

    2:

    3: String[] paises = {

    4: "Africa do Sul",

    5: ...

    6: "Uruguai" };

    7:

    8: int posicoes[] = new int[]{

    9: 90, ..., 18 };

    10:

    11: public void onCreate(Bundle savedInstanceState)

    12: {

    13: super.onCreate(savedInstanceState);

    14: setContentView(R.layout.listview);

    15:

    16: setListAdapter(new ArrayAdapter(this,

    17: android.R.layout.simple_list_item_1, paises));

    18: }

    19:

    20: public void onListItemClick(ListView parent, View v,

    int position, long id) {

    21: Toast.makeText(this, paises[position]+" est na

    "+posicoes[position]+" posio", Toast.LENGTH_SHORT).show();

    22: }

    23:}

    A primeira grande diferena j encontramos na linha 1, perceba que

    no estendemos mais a classe de Activity, mas sim de ListActivity. O

    interessante deste componente, que ele j utiliza internamente uma

    ListView.

    Na linha 3 criamos um vetor de String com todos os nomes dos

    pases participantes da copa do mundo. Como no iramos colocar os 32

    pases a, usamos as reticncias. Na linha 8 a vez de criar o vetor de

    inteiros com as posies das selees no ranking da FIFA.

    O ListActivity precisa que a classe configure seu ListAdapter, que

    pode ser entendido como um adaptador que faz a ponte entre o vetor de

    itens com a lista propriamente dita. Na Listagem estamos fazendo isso na

    linha 16. Um de seus construtores (usados na nossa codificao) recebe um

    Context, um inteiro que define o layout da lista e um vetor com os itens da

    lista.

    Finalmente, implementamos o mtodo onListItemChecked para tratar

    das interaes do usurio com a lista. Com o parmetro position definimos

    o pas e sua colocao e apresentamos em um Toast.

    Veja na Figura abaixo o comportamento do aplicativo em execuo:

  • Figura 31: Lista de pases com interao no item Brasil.

    Nossa lista est configurado para escolha nica, padro do

    componente. Mas poderamos alterar isso, trabalhando com a sua

    propriedade android:choiceMode, que permite o uso de trs constantes:

    none, singleChoice e multipleChoice.

    o SpinnerViews

    Este componente tambm objetiva mostrar uma grande quantidade

    de dados em uma lista. Porm, ele mostra uma lista no estilo popup,

    lembrando o ChoiceGroup estilo POPUP NO Java ME.

    Vamos trabalhar no mesmo exemplo criado acima mas mudando o

    componente. Para comear, crie um arquivo chamado spinner.xml e edite-o

    conforme a Listagem 26:

    Listagem 26:

  • android:id="@+id/spinner1"

    android:layout_width="wrap_content"

    android:layout_height="wrap_content" />

    A classe ViewsAndroid tambm sofrer algumas mudanas. A

    primeira na declarao da classe, que fica assim:

    public class ViewsAndroid extends Activity {

    No onCreate tambm teremos alteraes. Veja a Listagem 27:

    Listagem 27: 1: super.onCreate(savedInstanceState);

    2: setContentView(R.layout.spinner);

    3:

    4: s1 = (Spinner) findViewById(R.id.spinner1);

    5: ArrayAdapter adapter = new ArrayAdapter(this,

    android.R.layout.simple_spinner_item, paises);

    6:

    7: s1.setAdapter(adapter);

    8: s1.setOnItemSelectedListener(new OnItemSelectedListener() {

    9: public void onItemSelected(AdapterView arg0,

    10: View arg1, int arg2, long arg3) {

    11: int index = s1.getSelectedItemPosition();

    12: Toast.makeText(getBaseContext(), paises[index]+" ocupa a

    "+posicoes[index]+" no ranking da FIFA", Toast.LENGTH_SHORT).show();

    13: }

    14:

    15: public void onNothingSelected(AdapterView arg0) {}

    16:});

    Na linha 4 recuperamos o objeto Spinner. Este componente tambm

    trabalha com um adaptador, criado na linha 5, e configurado para o Spinner

    na linha 7. Na linha 8 adicionamos o OnItemSelectedListener, e

    implementamos seus dois mtodos obrigatrios. No onItemSelected

    recuperamos a posio do item selecionado no Spinner (linha 11) e depois

    mostramos a mesma mensagem mostrada no exemplo anterior.

    Veja como ficou este aplicativo:

    Figura 32: Tela inicial do aplicativo com Spinner.

  • Figura 33: Spinner mostrando seus itens.

    Figura 34: Tela depois de selecionarmos a Argentina no Spinner.

    Tambm podemos mudar a forma como a lista mostrada ao

    usurio. Altere a linha 5 da lista 27 para:

  • ArrayAdapter adapter = new ArrayAdapter(this,

    android.R.layout.simple_spinner_dropdown_item, paises);

    Veja o resultado:

    Figura 35: Spinner com layout modificado.

    o Gallery e ImageView

    A partir desse momento vamos ver componente que nos ajudam a

    apresentar imagens ao usurio. Se o leitor deste texto estava comeando se

    apaixonar pelo Android, vai pedir a mo dele em casamento ao final deste

    tpico.

    Como este tpico difere dos demais, vamos criar um novo aplicativo,

    chamado ImagesInAndroid:

  • Figura 36: Criao do projeto ImagesInAndroid.

    Crie um arquivo XML chamado passo1.xml. Veja seu contedo na

    Listagem 28:

    Listagem 28:

  • Tambm precisamos alterar a classe ImagesInAndroid. Como as

    mudanas so vrias, vamos por partes.

    Primeiramente veja o bsico que j aprendemos sobre Android:

    package com.estudos.android;

    import

    public class ImagesInAndroid extends Activity

    {

    @Override

    public void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);

    setContentView(R.layout.passo1);

    }

    }

    Nenhuma novidade. O passo seguinte separar algumas imagens e

    joga-las dentro da patas res.drawable. Veja como fica a estrutura de

    diretrio na Figura 37:

    Figura 37: Arquitetura atualizada com as imagens.

    Feito isso, cria-se um varivel com um vetor de instncias de Integer.

    Veja abaixo como fica. Perceba que estamos referenciando a nossa classe

    de recursos, R.

  • Integer[] imageIDs = {

    R.drawable.pic1,

    R.drawable.pic2,

    R.drawable.pic3,

    R.drawable.pic4,

    R.drawable.pic5,

    R.drawable.pic6

    };

    Agora, vamos adicionar um evento de clique nas imagens do

    Gallery. O cdigo mostrado abaixo est dentro do mtodo onCreate:

    Gallery gallery = (Gallery) findViewById(R.id.gallery1);

    gallery.setOnItemClickListener(new OnItemClickListener() {

    public void onItemClick(AdapterView parent, View v, int

    position, long id) {

    Toast.makeText(getBaseContext(), "Selecionou" + (position +

    1), Toast.LENGTH_SHORT).show();

    }

    });

    Nesse cdigo tambm no encontramos nada de novo em relao ao

    que j vimos at aqui. Agora execute este arquivo e:

    Figura 38: Usando Gallery.

    Cad as imagens? As imagens no apareceram porque o Gallery

    tambm precisa de um adaptador, semelhante ao que ocorre com o

    ListView e o Spinner, vistos a pouco.

    Esse adaptador precisa ser criado, diferentemente do Spinner por

    exemplo, que j tem uma implementao da BaseAdapter para ela

    (SpinnerAdapter), ou do ListView, que possui o ListAdapter. Sendo assim,

    vamos criar uma classe interna chamada ImageAdapter, veja na Listagem

    32 seu cdigo:

    Listagem 33:

    1:public class ImagesInAndroid extends Activity

    2:{

    3:

  • 4:

    5: public class ImageAdapter extends BaseAdapter {

    6: private Context context;

    7: private int itemBackground;

    8:

    9: public ImageAdapter(Context c) {

    10: context = c;

    11: }

    12:

    13: public int getCount() {

    14: return imageIDs.length;

    15: }

    16:

    17: public Object getItem(int position) {

    18: return position;

    19: }

    20:

    21: public long getItemId(int position) {

    22: return position;

    23: }

    24:

    25: public View getView(int position, View convertView,

    ViewGroup parent) { }

    26: }

    27:}

    Veja que a classe ImageAdapter est dentro de ImagesInAndroid. Ela

    herda diretamente de BaseAdapter, e, como a linguagem Java ensina,

    existem alguns mtodos que devem ser implementados ao herdar esta

    classe, sendo eles:

    getCount (linha 13): retorna o nmero de componentes. No nosso caso retornamos o nmero de elementos no vetor imageIDs, que

    contm as imgens que sero mostradas no Gallery.

    getItem e getItemId (linhas 17 e 21 respectivamente): retornam o objeto e o identificador do elemento em uma determinada posio.

    getView (linha 25): retorna um objeto que herda de View que ser mostrado em uma determinada posio do Gallery.

    Vimos que o getView retorna o objeto que ser mostrado na galeria.

    Aqui estamos trabalhando com ImageView, mas importante sabe que o

    mtodo pode retornar qualquer classe que herda de View. Por exemplo,

    poderamos retornar instncias de TextView. Veja como ficaria o mtodo

    getView:

    public View getView(int position, View convertView, ViewGroup parent)

    {

    TextView tv = new TextView(context);

    tv.setWidth(100);

  • tv.setText("Teste");

    return tv;

    }

    E o resultado :

    Figura 39: Usando Gallery com TextView.

    Claro que este exemplo no tem nenhuma utilidade prtica, mas

    serve como prova de conceito.

    Voltando aquilo que realmente importa neste tpico, que Gallery

    com ImageView, devemos retornar uma instncia desta ltima classe no

    lugar do TextView no mtodo getView.

    Vamos editar novamente o mtodo:

    public View getView(int position, View convertView, ViewGroup parent)

    {

    ImageView imageView = new ImageView(context);

    imageView.setImageResource(imageIDs[position]);

    return imageView;

    }

    E o resultado:

    Figura 40: Usando Gallery com ImageView.

  • As imagens ainda esto com o seu tamanho natural, tambm

    possvel perceber que elas tem um sombreamento mais claro nas

    extremidades laterais, isso acontece porque o estilo padro do

    componente.

    Vamos configurar algumas propriedades do ImageView para

    melhorar o Gallery. Adicione mais estas duas linhas de cdigo no corpo do

    getView:

    imageView.setScaleType(ImageView.ScaleType.FIT_XY);

    imageView.setLayoutParams(new Gallery.LayoutParams(150, 120));

    Estamos definindo o tamanho do componente na segunda linha e, na

    primeira, configuramos o tipo de escala. Como resultado, a imagem vai

    ocupar toda a rea reservada pra ela (150 por 120 pixeis). Veja como fica

    na Figura 41:

    Figura 41: Usando Gallery com ImageView e parmetros de layout.

    Para finalizar com toque de ouro, vamos usar um estilo para

    melhorar a apresentao das fotos.

    public View getView(int position, View convertView, ViewGroup parent)

    {

    ...

    ...

    ...

    imageView.setBackgroundResource(

    android.R.drawable.alert_light_frame);

    return imageView;

    }

    E o resultado disso:

  • Figura 42: Usando Gallery com ImageView e estilo.

    Mas acho que nossa aplicao ainda no est legal, no momento

    quando clicamos em uma foto apenas mostramos na tela qual imagem foi

    clicada:

    Figura 43: Resultado inicial de interao com imagens.

    Mas acho que podemos fazer melhor que isso. Vamos mostrar a

    imagem selecionada na parte central da tela, em um componente

    ImageView. Para conseguir nosso objetivo edite o passo1.xml e adicione o

    seguinte trecho de cdigo logo depois do Gallery.

  • android:layout_width="320px"

    android:layout_height="250px" />

    Tambm altere o tratamento da interao do usurio com o Gallery,

    veja:

    gallery.setOnItemClickListener(new OnItemClickListener() {

    public void onItemClick(AdapterView parent,

    View v, int position, long id) {

    ImageView imageView = (ImageView) findViewById(R.id.image1);

    imageView.setImageResource(imageIDs[position]);

    }

    });

    O resultado est na Figura 44:

    Figura 44: Interao com imagens configurando imagens no centro.

    Lembram-se que antes usamos o tipo de escala para definir o

    comportamento da galeria de imagens na parte superior da tela, tambm

    podemos usar agora na visualizao da imagem. Adicione o seguinte

    atributo ao ImageView no passo1.xml:

    android:scaleType="fitXY" />

  • Agora a imagem vai preencher toda a regio reservada ao

    ImageView. Veja na Figura 45:

    Figura 45: ImageView escalado para preencher regio central da tela.

    o ImageSwitcher

    A troca de imagens que implementamos no exemplo anterior com

    ImageView e Gallery tambm pode ser conseguida com este componente ,

    e com uma vantagem, o ImageSwitcher permite configurar alguns efeitos

    3D na troca das imagens.

    Este exemplo ser construdo encima do anterior. Sendo assim, edite

    o arquivo passo1.xml conforme a Listagem 39:

    Listagem 39:

  • android:layout_alignParentRight="true"

    android:layout_alignParentBottom="true" />

    Tambm preciso alterar a classe ImagesInAndroid. Siga a Listagem

    40:

    Listagem 40:

    1:public class ImagesInAndroid extends Activity implements

    ViewFactory {

    2: private ImageSwitcher imageSwitcher;

    3:

    4: Integer[] imageIDs = {};

    5:

    6: @Override

    7; public void onCreate(Bundle savedInstanceState)

    8: {

    9: super.onCreate(savedInstanceState);

    10: setContentView(R.layout.passo1);

    11:

    12: imageSwitcher = (ImageSwitcher) findViewById(R.id.switcher1);

    13: imageSwitcher.setFactory(this);

    14:

    15: imageSwitcher.setInAnimation( AnimationUtils.loadAnimation(

    this, android.R.anim.fade_in));

    16: imageSwitcher.setOutAnimation( AnimationUtils.loadAnimation(

    this, android.R.anim.fade_out));

    27:

    18: Gallery gallery = (Gallery) findViewById(R.id.gallery1);

    19: ...

    20: gallery.setOnItemClickListener(new OnItemClickListener() {

    21: public void onItemClick(AdapterView parent,

    22: View v, int position, long id) {

    23: imageSwitcher.setImageResource(imageIDs[position]);

    24: }

    25: });

    26: }

    27:

    28: public class ImageAdapter extends BaseAdapter

    29: {}

    30:

    31: @Override

    32: public View makeView() {

    33: ImageView imageView = new ImageView(this);

    34: imageView.setBackgroundColor(0xFF000000);

    35: imageView.setScaleType(ImageView.ScaleType.FIT_XY);

    36: imageView.setLayoutParams(new

    37: ImageSwitcher.LayoutParams(

    LayoutParams.FILL_PARENT,

    LayoutParams.FILL_PARENT));

    38: return imageView;

    39: }

    40:}

  • Vamos falar somente das alteraes feitas na classe anterior. Perceba

    que na linha 12 recuperamos o componente ImageSwitcher. Na linha 13

    usamos o mtodo setFactory para definir a fbrica usada para criar as duas

    imagens que sero usadas para o componente fazer o flip.

    Este mtodo recebe como parmetro uma classe que implemente a

    interface ViewFactory, implementada na mesma classe ImagesInAndroid,

    veja a linha 1.

    Nas linhas 15 e3 16 configuramos os eventos que a imagem ter no

    momento de entrada e de sada da tela do usurio.

    Tambm mudamos a tarefa a realizar quando o usurio clicar em

    uma das imagens do Gallery. Neste momento indicamos ao ImageSwitcher

    qual imagem ele deve apresentar na tela, ele prprio trata da renderizao

    dos efeitos configurados anteriormente.

    Por fim, v at a linha 32 e veja que implementamos o mtodo

    makeView, obrigatrio quando implementamos a ViewFactory. Estemtodo

    criar a nova View que ser adicionada no switcher. Aqui tambm

    poderamos passar qualquer componente que herde de View, como fizemos

    com o TextView no exemplo do tpico anterior (Gallery e ImageView).

    Ao executar a aplicamos veremos:

    Figura 46: Uso do ImageSwitcher.

  • Aparentemente no percebemos nenhuma diferena, a no ser pelo

    fato da imagem ocupar a tela inteira. Porm, interaja com o Gallery para

    ver os efeitos do ImageSwitcher.

    o GridView

    Para finalizar este artigo/tutorial/ vos mostrar o GridView, que,

    como o prprio nome indica permite que mostramos imagens em uma

    grade de fotos.

    O passo1.xml fica da seguinte maneira:

    No prprio XML configuramos algumas propriedades que so

    prprias de qualquer grade, no s Android, como por exemplo:

    android:layout_width, android:layout_height, android:numColumns,

    android:verticalSpacing, android:horizontalSpacing,

    android:columnWidth.

    O ImagesInAndroid sofre mudanas, mas o leitor ir tirar de letra

    este cdigo a esta altura do campeonato. Veja a Listagem de cdigo 42:

    Listagem 42: public class ImagesInAndroid extends Activity {

    //---the images to display---

    Integer[] imageIDs = {

    R.drawable.pic1,

    R.drawable.pic2,

    R.drawable.pic3,

    R.drawable.pic4,

    R.drawable.pic5,

    R.drawable.pic6

    };

  • @Override

    public void onCreate(Bundle savedInstanceState)

    {

    super.onCreate(savedInstanceState);

    setContentView(R.layout.passo1);

    GridView gridView = (GridView) findViewById(R.id.gridview);

    gridView.setAdapter(new ImageAdapter(this));

    gridView.setOnItemClickListener(new OnItemClickListener()

    {

    public void onItemClick(AdapterView parent,

    View v, int position, long id)

    {

    Toast.makeText(getBaseContext(),

    "pic" + (position + 1) + " selected",

    Toast.LENGTH_SHORT).show();

    }

    });

    }

    public class ImageAdapter extends BaseAdapter

    {

    private Context context;

    private int itemBackground;

    public ImageAdapter(Context c)

    {

    context = c;

    }

    public int getCount() {

    return imageIDs.length;

    }

    public Object getItem(int position) {

    return position;

    }

    public long getItemId(int position) {

    return position;

    }

    public View getView(int position, View convertView, ViewGroup

    parent) {

    ImageView imageView;

    if (convertView == null) {

    imageView = new ImageView(context);

    imageView.setLayoutParams(new

    GridView.LayoutParams(85, 85));

    imageView.setScaleType(

    ImageView.ScaleType.CENTER_CROP);

    } else {

    imageView = (ImageView) convertView;

    }

    imageView.setImageResource(imageIDs[position]);

    return imageView;

    }

    }

    }

  • Execute a aplicao:

    o CONCLUSO

    Primeiramente gostaria de agradecer mais uma vez ao autor do texto

    Understanding User Interface in Android, que foi de onde parti meu estudo em interfaces de usurio com Android. Alm de outras fontes que

    pesquisei.

    No texto foi possvel perceber claramente a facilidade que existe na

    criao das UIs de nossos aplicativos com a mistura entre XML e

    codificao Java. Os componentes do Android so fceis de usar e muito

    bonitos, deixando um programador Java ME como eu de queixo cado,

    principalmente nas View que tratam de imagens.

    Se o tempo permitir pretendo continuar com a srie de artigos aqui

    no Java Mvel, comentrios e sugestes so sempre bem vindos.

    Obs: as fotos so uma homenagem a uma pessoa mais que

    especial na minha vida, minha noiva e futura esposa. Sheila, te amo. Ah,

    ela liberou o direito de imagem, est tudo certo.

  • o SOBRE MIM

    Meu nome Ricardo da Silva Ogliari, sou graduado em Cincia da

    Computao pela Universidade de Passo Fundo. Atualmente tambm estou

    cursando uma ps-graduao em web, estratgias de inovao e tecnologia,

    no Senac SP. Trabalho com mobile a 6 anos, escrevo artigos para algumas

    revistas nacionais especializadas. Sou criador e mantenedor do

    http://www.mobilidadetudo.com e sou um dos membros do

    www.javamovel.com. Palestrei em eventos nacionais e internacionais,

    como o FISL e o JustJava, alm de ter dezenas de artigos meus espalhados

    pelo mundo da internet.