167
Desenvolvendo Aplicações com Java para Android 1 ATENÇÃO: ESTÁ EM DESENVOLVIMENTO, TEM MUITOS ERROS Qualquer coisa manda e-mail para: [email protected] Sobre os Autores Wellington Pinto de Oliveira é formado em Ciência da Computação e entusiasta plataforma móvel desde 2001. Possui experiência com várias ferramentas, como Sattelite Forms, AppForge, CodeWarrior, NS Basic e HB++, Windows Mobile com Visual Studio. Mestre em Ensino de Ciências atua na área educacional, mesclando tecnologia e ensino. Atualmente atua como Analista na Venki Tecnologia em Software LTDA e como professor na Faculdade de Tecnologia de São Paulo (FATEC) na qual ministra disciplinas como: Sistemas Operacionais I e II, Redes de Computadores e Teleprocessamento, Interface Humano-Computador, Gerenciamento de Projetos, etc.. Possui muita experiência com aplicações móveis pois já atuou em dezenas de projetos relacionados, publicou dezenas de artigos, lançou duas apostilas (Windows Mobile e Palm OS com HB++) e um livro sobre desenvolvimento de aplicações com NS Basic par Palm OS. E-mail para contato: [email protected] Wanderson Pinto de Oliveira .... TODO ..... Wallace Pinto de Oliveira ... TODO ... E-mail para contato: Marcas Registradas Várias Marcas Registradas aparecem no decorrer desta obra. Mais do que simplesmente listar estes nomes informar que possui seus direitos de exploração, ou ainda imprimir os logotipos das mesmas, os autores declaram estar utilizando tais nomes apenas para fins editoriais, em benefício exclusivo do dono da Marca Registrada, sem intenção de infringir as regras de sua utilização.

Apostila Android Gratuita

Embed Size (px)

DESCRIPTION

Contém erros de Português, mais a teria está OK.

Citation preview

Page 1: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 1

ATENÇÃO: ESTÁ EM DESENVOLVIMENTO, TEM MUITOS ERROS

Qualquer coisa manda e-mail para: [email protected]

Sobre os Autores

Wellington Pinto de Oliveira é formado em Ciência da Computação e entusiasta plataforma móvel desde 2001. Possui experiência com várias ferramentas, como Sattelite Forms, AppForge, CodeWarrior, NS Basic e HB++, Windows Mobile com Visual Studio.

Mestre em Ensino de Ciências atua na área educacional, mesclando tecnologia e ensino. Atualmente atua como Analista na Venki Tecnologia em Software LTDA e como professor na Faculdade de Tecnologia de São Paulo (FATEC) na qual ministra disciplinas como: Sistemas Operacionais I e II, Redes de Computadores e Teleprocessamento, Interface Humano-Computador, Gerenciamento de Projetos, etc..

Possui muita experiência com aplicações móveis pois já atuou em dezenas de projetos relacionados, publicou dezenas de artigos, lançou duas apostilas (Windows Mobile e Palm OS com HB++) e um livro sobre desenvolvimento de aplicações com NS Basic par Palm OS.

E-mail para contato: [email protected] Wanderson Pinto de Oliveira .... TODO ..... Wallace Pinto de Oliveira ... TODO ... E-mail para contato:

Marcas Registradas

Várias Marcas Registradas aparecem no decorrer desta obra. Mais do que simplesmente listar estes nomes informar que possui seus direitos de exploração, ou ainda imprimir os logotipos das mesmas, os autores declaram estar utilizando tais nomes apenas para fins editoriais, em benefício exclusivo do dono da Marca Registrada, sem intenção de infringir as regras de sua utilização.

Page 2: Apostila Android Gratuita

2 Desenvolvendo Aplicações Móveis com SuperWaba

Dizeres Legais

Todos os direitos reservados a Wellington Pinto de Oliveira, Wanderson Pinto de Oliveira e Wallace Pinto de Oliveira. Nenhuma parte desta obra poderá ser reproduzida, transmitida e gravada, por qualquer meio eletrônico, mecânico, por fotocópia e outros, sem a prévia autorização, por escrito, dos autores.

Page 3: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 3

Indice

SOBRE OS AUTORES ................................................................................................................................... 1  

MARCAS REGISTRADAS .............................................................................................................................. 1  

DIZERES LEGAIS ........................................................................................................................................... 2  

1 INTRODUÇÃO ............................................................................................................................................. 7  

Objetivos Deste Capítulo ................................................................................................................................. 7  

Definindo a Plataforma ................................................................................................................................... 7  

Plataforma Móvel ............................................................................................................................................. 8  

Plataforma Android ......................................................................................................................................... 9  

Requerimentos ................................................................................................................................................ 10  

Como está Estruturado o Livro .................................................................................................................... 10  

Convenções ..................................................................................................................................................... 10  

O Código do Livro .......................................................................................................................................... 11  

Download ........................................................................................................................................................ 11  JDK J2SE 6.0 ................................................................................................................................................................ 11  Eclipse 3.6.2 .................................................................................................................................................................. 11  Android SDK ................................................................................................................................................................ 11  

2 INSTALANDO E CONFIGURANDO O AMBIENTE .................................................................................. 12  

Objetivos Deste Capítulo ............................................................................................................................... 12  

Introdução ....................................................................................................................................................... 12  

Instalando a JDK ........................................................................................................................................... 12  

Instalando o Eclipse ....................................................................................................................................... 15  

Instalando a SDK do Android ....................................................................................................................... 16  

Configurando o Eclipse ................................................................................................................................. 20  

3 HELLO WORLD ......................................................................................................................................... 25  

Objetivos Deste Capítulo ............................................................................................................................... 25  

Introdução ....................................................................................................................................................... 25  

Estrutura do Projeto ...................................................................................................................................... 27  

Configurando o Emulador ............................................................................................................................ 30  

Executando a Aplicação ................................................................................................................................. 32  

Page 4: Apostila Android Gratuita

4 Desenvolvendo Aplicações com Java para Android

4 DEPURANDO E DISTRIBUINDO A APLICAÇÃO .................................................................................... 35  

Objetivos Deste Capítulo ............................................................................................................................... 35  

Introdução ...................................................................................................................................................... 35  

Atualizando o Sistema ................................................................................................................................... 35  

Depurando uma Aplicação pelo Device ....................................................................................................... 36  

Deploy ............................................................................................................................................................. 41  

5 A LINGUAGEM .......................................................................................................................................... 44  

Objetivos Deste Capítulo ............................................................................................................................... 44  

Introdução ...................................................................................................................................................... 44  

Algoritmos ...................................................................................................................................................... 44  

Variáveis, Operadores e Estruturas de Controle ........................................................................................ 45  Variáveis ........................................................................................................................................................................ 45  Tipos de Dados Primitivos ............................................................................................................................................ 45  Declaração de variáveis ................................................................................................................................................. 47  Comentários ................................................................................................................................................................... 48  Operadores ..................................................................................................................................................................... 49  Estruturas de Controle ................................................................................................................................................... 53  Estruturas de controle de erros ...................................................................................................................................... 60  Gerando suas Próprias Exceções ................................................................................................................................... 63  

5 PROGRAMAÇÃO ORIENTADA A OBJETOS .......................................................................................... 66  

Objetivo Deste Apêndice ............................................................................................................................... 66  

Introdução ...................................................................................................................................................... 66  

Especificando uma Classe ............................................................................................................................. 67  

Objetos ............................................................................................................................................................ 68  

Atributos ......................................................................................................................................................... 68  Coleta automática de lixo .............................................................................................................................................. 69  Acesso aos atributos e métodos e alterações dos atributos ............................................................................................ 70  

Métodos ........................................................................................................................................................... 70  Sintaxe de declaração de métodos ................................................................................................................................. 70  this ................................................................................................................................................................................. 72  Sintaxe de chamada ou acesso a métodos ..................................................................................................................... 72  Nova versão do programa Circulo ................................................................................................................................. 72  

Construtores ................................................................................................................................................... 74  

Destrutores Ou “finalizers” .......................................................................................................................... 76  

Ponteiros, Referências e Objetos .................................................................................................................. 77  Passagem por Referência ............................................................................................................................................... 77  Vetores e Matrizes ......................................................................................................................................................... 77  

Encapsulamento ............................................................................................................................................. 78  Encapsulando Métodos e Atributos ............................................................................................................................... 78  

Page 5: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 5

Quando Utilizar Encapsulamento? ........................................................................................................................... 79  

Herança ........................................................................................................................................................... 79  Hierarquia de Tipos ...................................................................................................................................................... 80  Uma Hierarquia Simples ............................................................................................................................................... 80  Construtores e herança .................................................................................................................................................. 81  Protected ....................................................................................................................................................................... 83  

Interfaces ......................................................................................................................................................... 83  

Polimorfismo e Classes Abstratas ................................................................................................................. 85  

Redefinição de Métodos para uma Classe Herdeira ................................................................................... 85  

7 INTERFACE COM O USUÁRIO ................................................................................................................ 86  

Objetivo Deste Apêndice ............................................................................................................................... 86  

Introdução ....................................................................................................................................................... 86  

View ................................................................................................................................................................. 86  

Activity ............................................................................................................................................................ 86  Ciclo de vida de uma Activity ...................................................................................................................................... 87  

Editor de Layout ............................................................................................................................................ 90  

android.widget ................................................................................................................................................ 98  TextView ...................................................................................................................................................................... 98  EditText ........................................................................................................................................................................ 98  Button ............................................................................................................................................................................ 99  ToggleButton .............................................................................................................................................................. 101  RadioButton e RadioGroup ........................................................................................................................................ 103  CheckBox .................................................................................................................................................................... 105  AutoCompleteTextView ............................................................................................................................................. 107  MultiAutoCompleteTextView .................................................................................................................................... 108  Spinner ........................................................................................................................................................................ 113  Data e Hora ................................................................................................................................................................. 116  

DatePicker .............................................................................................................................................................. 116  TimePicker ............................................................................................................................................................. 116  CalendarView ......................................................................................................................................................... 119  Chronometer ........................................................................................................................................................... 119  

Imagens e Mídia .......................................................................................................................................................... 122  ImageView ............................................................................................................................................................. 122  ImageButton ........................................................................................................................................................... 128  Gallery .................................................................................................................................................................... 130  

Listas e Tabelas ........................................................................................................................................................... 134  ListView ................................................................................................................................................................. 134  ExpandableListView .............................................................................................................................................. 139  

APÊNDICE 1 HABILITANDO DEPURAÇÃO ............................................................................................. 161  

Objetivo Deste Apêndice ............................................................................................................................. 161  

Introdução ..................................................................................................................................................... 161  

APÊNDICE 2 PERSPECTIVA NO ECLIPSE .............................................................................................. 163  

Objetivo Deste Apêndice ............................................................................................................................. 163  

Page 6: Apostila Android Gratuita

6 Desenvolvendo Aplicações com Java para Android

Introdução .................................................................................................................................................... 163  

APÊNDICE 3 SHOW VIEW IN PERSPECTIVE .......................................................................................... 164  

Objetivo Deste Apêndice ............................................................................................................................. 164  

Introdução .................................................................................................................................................... 164  

Page 7: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 7

11 1 Introdução

Objetivos Deste Capítulo • Conhecer um pouco mais sobre a plataforma Android;

• Conhecer os requerimentos mínimos para se utilizar o Eclipse e Android;

• Realizar o download dos arquivos necessários;

• Instalar e configurar o ambiente.

Definindo a Plataforma Este livro está destinado a pessoas que atuam ou pretendem atuar no desenvolvimento de

aplicações móveis para o mercado coorporativo, definimos como tema a plataforma Android por vários motivos, para entender vamos fazer um retrocesso no tempo e acompanhar os eventos dos últimos 18 anos do contexto mobilidade.

Antes de 1995 a mobilidade era resumida a agendas eletrônicas com programas fixo no hardware, porem em 1995-1996 uma divisão da U.S. Robotics retira do papel o primeiro modelo Personal Digital Assistaints também conhecido como PDA. Porem esta empresa passou por problemas judiciais relacionados a patentes entre 1998-2000. Tais problemas internos fez com que a empresa fosse dividia, vendida e unida várias vezes durante os anos de 2000-2006, estas mudanças constantes fez com que seu hardware evoluísse pouco se comparado com o concorrente Windows Mobile.

Talvez porque antes de ser lançado ninguém acreditava que seria um produto tão bem aceito pela complexidade do ambiente para o público da época acostumado com as agendas. Só que as empresas viram neste hardware uma opção para levar sua automação para além da fronteira dos escritórios e parques dotados de computadores, ou seja, este equipamento poderia ir para campo atuar de forma independente e trazer dados para ser computados em computadores de maior porte, as agendas não permitiam isso pois o processo de desenvolvimento e até a capacidade de introduzir novos softwares era muito limitado.

Se beneficiando destes problemas internos da Palm a outra fabricante de Sistemas Operacionais chamada Microsoft começa a deslanchar suas vendas do Windows CE, isso porque apoiado em um processador mais forte e desenvolvido por várias empresas de Hardware (o Sistema Operacional é Microsoft e o hardware é de terceiros) e mais recursos. Neste período pode então criar uma divisão no perfil do usuário, que é o público coorporativo e o público voltado ao entretenimento.

Mercado Coorporativo e Automação Industrial que busca equipamentos com menos distrações a seus funcionários, que o Sistema Operacional seja estável e leve, e ainda que o hardware seja barato. Por causa deste público que a Palm OS sobrevive entre os anos de 2000-2010 afinal o hardware e Sistema Operacional era ideal para estes fins. O autor deste livro já viu por exemplo um cliente comprar 500 PDAs da marca Palm Z22 com 500 modens Pegasus III em uma única compra, este kit custou algo em torno de 520,00 Reais (na época). Se a mesma compra fosse feita da marca concorrente sairia no mínimo por 1300,00 Reais o Kit. Este mercado força a estabilidade do Hardware e do Sistema Operacional a manter pouca evolução para manter preços.

Page 8: Apostila Android Gratuita

8 Desenvolvendo Aplicações com Java para Android

Já o outro público, que busca entretenimento força o mercado a subir em qualidade o que eleva os preços, a Microsoft lançou inúmeras versões de seu Sistema Operacional e por não haver um foco as empresas que desenvolvem hardware para este OS mudaram constantemente de modelos, recursos, muitas apareceram com bons equipamentos e em poucos anos somem. O mercado ficou volátil e recentemente podemos ver que "a própria cobra mordeu seu rabo" pois a Microsoft está perdendo vendas devido a essa volatilidade do mercado que ela ajudou a criar.

Quando decidi escrever um novo material para equipamentos móveis fiquei em dúvida entre Android e IOS da Apple, alguns fatores me fizeram decidir em adotar a plataforma Android, vamos então descrever tais fatores:

- Meu público é coorporativo, digo público não só do livro em questão mas também clientes que desenvolvo aplicações móveis, nunca nenhum usuário que busca entretenimento me contratou para desenvolver um novo player de música para seu uso próprio.

- Meu cliente requer equipamentos baratos, hoje temos dezenas de empresas trabalhando com hardwares equipados com o sistema operacional Android, isso abaixa os preços dos equipamentos o que é bom, porem surge a dificuldade de escolher bons fornecedores, mas nada que a Internet não me ajude a decidir.

- Sistema Operacional consolidado, com representantes fortes.

- Um ambiente de programação gratuito, não preciso trocar o Sistema Operacional da minha máquina Host para ter que programar, ao contrário da IOS que o leitor precisaria de ter um Mac OS no Host. Isso mostra que é uma plataforma fechada e não aberta como o Android. Se for para apostar no futuro aposto na plataforma aberta.

Plataforma Móvel

É natural que um grande grupo de leitores deste livro já desenvolveram aplicações para Desktop e Web porem tiveram pouco contato com a plataforma móvel. Um desenvolvedor de aplicações móveis deve ter em mente que sua aplicação não pode ser complexa, um estudo realizado pela Pam Inc (PALM INC. 2002) revela que em 80% do tempo os usuários de aplicações Desktop utilizam 20% dos recursos de um aplicativo complexo.

On a desktop system, users use 20% of an application’s features 80% of the time. Your application should provide only that top 20% of features (Palm Inc., 2002).

A recomendação desta empresa é que as aplicações móveis não precisam atingir a totalidade da abstração de aplicações Desktop nos equipamentos móveis, mas sim as principais ações que o usuário realmente requer.

Minha experiência no assunto diz que mesmo se uma aplicação deva atingir a totalidade de ações de uma aplicação que esteja sendo portada da plataforma Deskotp para a Mobile então eu delimito as principais ações e desenvolvo interfaces e lógicas que priorizem estas ações mais importantes, as demais devemos abstrair em menus (que estão geralmente ocultos) ou fora do foco principal das interfaces.

No mesmo documento gerado pela Palm Inc. (Palm Inc., 2002) aborda que a usabilidade de aplicações móveis é diferente na questão do tempo de acesso e na regularidade do acesso. Geralmente uma aplicação móvel é acessada várias vezes ao dia porem o acesso tende a ter um período menor se comparado com a plataforma Desktop. No capítulo dedicado a Interface com o usuário vou dedicar alguns tópicos para abordar as teorias de Interface Humano-Computador (IHC) para plataforma Mobile.

Page 9: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 9

Figura 1 - Acesso dos usuários (Palm Inc., 2002)

Outra questão importante que o leitor deve levar em consideração é a conectividade, dispositivos móveis estão voltados a conectividade, isso porque seus recursos são limitados e seu objetivo não é substituir a plataforma Dekstop, mas sim estar no local certo no momento certo ou seja, no momento da necessidade do usuário. Logo a ideia não é armazenar a informação, mas sim ter acesso a esta informação que está no servidor, seja de arquivos ou de banco de dados. Tais questões de conectividade serão abordadas com ênfase no capítulo apropriado.

Plataforma Android Android é um Sistema Operacional que utiliza em seu núcleo a versão 2.6 do kernel do Linux. É um

sistema leve porem poderoso, por estar apoiado na versão 2.6 do kernel do Linux é considerado estável e está preparado para atender as necessidades modernas.

Figura 2 - Interface do Android

Atualmente o Android equipa Celulares, Tablets PC, SmartPhones, etc. de grandes e pequenas empresas. A portabilidade de nossas aplicações está centrada na portabilidade do Java. Na Figura 2 temos a interface de um equipamento (celular) emulado, já na Figura 3 temos a execução do Android em um Notebook. A aplicação desenvolvida deverá ser executada sem problemas (geralmente de interface) em ambos os equipamentos, sem a necessidade de reprogramação.

Figura 3 - Android em um Notebook

Page 10: Apostila Android Gratuita

10 Desenvolvendo Aplicações com Java para Android

Neste livro vamos desenvolver aplicações em Java, a portabilidade do Java para a plataforma é de 100%, no próximo capítulo vamos instalar e configurar o Java. Se você não conhece nada da linguagem Java não se preocupe, temos dois capítulos no livro que abordarão dês do básico da linguagem até noções avançadas de Programação Orientada a Objetos.

Requerimentos

Antes de instalar a ferramenta devemos conhecer os requisitos mínimos para se executar o Eclipse e o Android:

• Microsoft Windows® XP ou superior;

• Pentium 4;

• 1 GB de RAM;

• 10 GB de HardDisk.

Como está Estruturado o Livro Após decidir qual tecnologia baseado na vivencia que o autor teve chegou a hora de decidir qual o

foco do livro, bom foi fácil, busco instruir profissionais que atuam na área de desenvolvimento de aplicações que conheça no mínimo algoritmos e tenha uma visão lógica. Para isso então decidi estruturar o livro para uma pessoa leiga em Java, no início do livro vamos ver que temos muitas figuras, passo-a-passo processos de instalação e configuração, parece até que vamos ter umas 2000 páginas de tanta figura, mas aprendi atuando na área educacional que o começo da exploração de um novo conhecimento deve ser gratificante e de muito sucesso para elevar a autoestima do aprendiz.

Nada é mais difícil (é uma crítica mesmo) no ambiente Java do que configurar o próprio ambiente, e ainda somando a complexidade de comunicação com outro Sistema Operacional (o Android emulado), por isso detalhei muito a instalação e configuração com imagens.

Após detalhar a instalação e a configuração decidi montar um capítulo clássico Hello World, este capítulo em todos os livros servem para elevar a autoestima e garantir que o ambiente foi bem configurado. Nada de programação, criar um projeto e executar, simples para ter sucesso.

Acredito que por ser barato, o leitor tenha um hardware equipado com Android, então após o Hello World adicionei um capítulo importante, sobre como realizar a depuração do código, a gerar um arquivo de instalação para o Android físico (não emulado) e como instalar no Android o seu programa. Acredito que você queira sair mostrando "Eu consegui,,, Eu consegui" para mão, pai, filho, funcionário, esposa, cachorro (eu adoro animais, realmente faço isso), gato, para as galinhas (animais), etc.. Seja feliz que isso motiva a aprender mais e ainda a vizinhança vai achar que você é doido e não vai bater na porta para pedir açúcar emprestado, como se pudesse devolver algo que se come (na verdade pode mais fica difícil separar o resultado final).

Como eu disse, este livro NÃO É DEDICADO SOMENTE APROGRAMADORES JAVA, então montei dois capítulos que abordam a linguagem do básico até as teorias de Programação Orientada a Objetos, se você é programador VB.NET, Basic (os autores deste livro já programaram em mais de 10 linguagens), Delphi, Clipper, C, C++, C#, Python/IronPython etc.. não precisa se preocupe, apenas dê muita atenção a estes dois capítulos.

A partir dai começo a aprofundar na teoria de Android, com interfaces gráficas, conexão com SQLite, comunicação com servidores Sockets, etc..

Convenções

Utilizamos uma série de estilos de texto e layout no livro para auxiliar a distinguir os diferentes tipos de informações. A seguir estão exemplos dos estilos mais utilizados e uma explicação do que significam:

Os marcadores aparecem recuados, a seguinte maneira:

• Uma pequena esfera é utilizada para marcar um item;

Page 11: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 11

Todos os caminhos e atalhos estão em negrito, exemplo:

Iniciar | Programas | Assessórios | Bloco de Notas O caminho acima é um exemplo de atalho para o Bloco de Notas.

O código fonte está limitado entre duas linhas horizontais e com as linhas numeradas.

0 1 //criando uma variável 2 String minha_variavel = “”; 3 //atribuindo dados a uma variável 4 minha_variavel = “Wellington Pinto de Oliveira”; 5

O comentário será feito no código utilizando a nomenclatura Java // ou /* */.

Quando for necessário exibir uma sintaxe de algum método ou rotina estarei adicionando um fundo cinza, conforme o exemplo abaixo:

alguma Sintaxe

O Código do Livro O código do livro está disponível para download na página

http://ww.grupoandroid.com.br/LivroAndroid.aspx digite o código AndroidSoftpalm para efetuar o download.

Nesta página também é possível encontrar todos os programas e aplicativos utilizados ao longo do livro.

Download Todos os arquivos necessários serão adquiridos na Internet, será necessário realizar o download de

três arquivos básicos, são eles:

JDK J2SE 6.0 O primeiro passo para que você comece a desenvolver programas em Java, consiste em obter o Kit

de Desenvolvimento Java, que já está na versão 1.6, atualmente conhecido com J2SE 6.0. Para conseguir o J2SE 6.0 JDK você deve acessar o endereço: http://www.grupoandroid.com.br/LivroAndroid.aspx (conforme tópico “O Código do Livro”).

Eclipse 3.6.2 No momento da edição deste livro, a versão disponível é a 3.6.2, mas como se trata de um

desenvolvimento open source, essas versões são rapidamente alteradas. Você pode baixar o IDE do Eclipse no endereço http://www.grupoandroid.com.br/LivroAndroid.aspx (conforme tópico “O Código do Livro”).

Android SDK O donwload do Android SDK não é diferente, acesse a URL

http://www.grupoandroid.com.br/LivroAndroid.aspx (conforme tópico “O Código do Livro”) e faça o download do arquivo installer_r11-windows.exe.

Page 12: Apostila Android Gratuita

12 Desenvolvendo Aplicações com Java para Android

22 2 Instalando e Configurando o Ambiente

Objetivos Deste Capítulo • Instalar os SDKs Java e Android;

• Instalar o Eclipse e configurar;

• Configurar o Emulador.

Introdução O Android não possui um IDE próprio, ele utiliza o Eclipse para manipulação de código fonte e

emulação. O Eclipse é uma IDE de desenvolvimento de programação, inicialmente desenvolvida pela IBM, que, segundo notícias, gastou mais de 40 Milhões de dólares no seu desenvolvimento antes de se transformar essa ferramenta Open Source para um consórcio, chamado Eclipse.org, que inicialmente incluiu a Borland, IBM, QNX Software Systems, Rational Software, Red Hat, SuSE, TogetherSoft e Webgain.

Instalando a JDK A primeira instalação deve ser o Java JDK, encontre o arquivo obtido no download e execute o

arquivo, abaixo temos uma sequência de telas obtidas durante o processo de instalação.

Figura 4 - Instalando o JDK jdk-6u-windows-j586-p.exe

Leia os termos de licença exibidos pela ferramenta, afinal não se deve aceitar nada sem ler nos dias de hoje.

Page 13: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 13

Figura 5 - Termos de licença.

Caso esteja de acordo pressione Accept e avance no processo de instalação.

Figura 6 - Opções de instalação de arquivos

Faça uma analise e instale o que realmente achar importante, caso queira manter a mesma instalação do autor prossiga sem alteração pressionando Next.

Figura 7 - Processo de instalação de arquivos.

Aguarde o termino do processo de instalação, isso pode demorar alguns minutos. Após a instalação devemos verificar se a variável de ambiente foi criada corretamente, para isso acesso o Painel de Controle do Windows em Iniciar | Painel de Controle, no painel procure pelo ícone Sistema.

Variáveis de ambiente são sequência de caracteres que contêm uma informação importante para o sistema ou para um software, controlando o comportamento dos programas. Como exemplos de variáveis de ambiente temos: PATH, CLASSPATH, USER, TEMP, JAVA_HOME, etc.

Page 14: Apostila Android Gratuita

14 Desenvolvendo Aplicações com Java para Android

Figura 8 - TabPanel Sistema

Pressione o botão Variáveis de ambiente conforme imagem acima.

Figura 9 - Variáveis de ambiente

Na figura acima temos as variáveis de ambiente do meu sistema operacional, veja que não existe JAVA_HOME, para criar pressiono o botão Nova. Se já tiver ignora este passo.

Page 15: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 15

Figura 10 - Basta informar o nome e o caminho

Para criar a variável JAVA_HOME atribua este nome a variável e adicione o caminho no valor da variável, lembre-se que este valor muda de instalação para instalação.

Figura 11 - Variáveis de ambiente

Veja na figura acima que agora temos a variável JAVA_HOME cadastrada.

Instalando o Eclipse Para manter um padrão de URL crie um novo diretório na pasta Program Files chamado eclipse,

conforme figura abaixo.

Atenção: Se estiver no Windows 7 ou Windows Vista você terá dificuldades de permissão de acesso a esta pasta.

Figura 12 - Criando a pasta eclipse

O Eclipse não possui um instalador, basta descompactar o arquivo obtido no download e já podemos executar o programa, logo descompacte o eclipse dentro da pasta criada.

Page 16: Apostila Android Gratuita

16 Desenvolvendo Aplicações com Java para Android

Figura 13 - Arquivos descompactados na pasta eclipse

Na figura acima podemos ver os arquivos descompactados na pasta eclipse, agora só precisamos criar um ícone na área de trabalho para agilizar o dia a dia do programador (Ver figura abaixo).

Figura 14 - Criando um ícone na área de trabalho

Altere o nome do ícone na área de trabalho para ter uma interface mais agradável.

Figura 15 - Ícone na área de trabalho

Instalando a SDK do Android O próximo passo é instalar o SDK do Android, efetue um duplo clique no arquivo installer_r11-

windows.exe, com isso a instalação será iniciada.

Page 17: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 17

Figura 16 - Inicio da Instalação

O processo de instalação é simples, porem vamos detalhar alguns pontos.

Figura 17 - Abertura do instalador

Esse é um ponto estranho, repare que ele está pedindo para instalar a SDK Java, mas ela já foi instalada. Macete é voltar em Back e avançar, ai ele detecta J.

Figura 18 - Java SE Development Kit não detectado

Page 18: Apostila Android Gratuita

18 Desenvolvendo Aplicações com Java para Android

Figura 19 - Java SE Development Kit detectado

Depois deste inconveniente, só temos que prestar atenção no diretório de instalação, esse diretório será útil para configurar o Eclipse.

Figura 20 - Diretório de instalação do Android

Agora é Next, Next até Finish como toda instalação Windows.

Figura 21 - Fimal da Instalação da SDK

Após a instalação do SDK o Android automaticamente chama a interface de atualização da API e ferramentas, conforme podemos ver na figura abaixo.

Page 19: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 19

Figura 22 - Atualizando lista para download

Será exibida uma lista de ferramentas e APIs que deverão ser baixadas, para isso aceite e inicie a instalação destes artefatos.

Figura 23 - Lista de Artefatos

Bom, isso pode demorar pois não depende só da sua conexão com a Internet, reparei em 5 instalações que o limitador está do outro lado. Então se não conhece muito bem Java você já pode ir lendo sobre a linguagem neste próprio texto (no capítulo dedicado a Linguagem Java).

Figura 24 - Processo de Download

Após realizar o download automaticamente e configurar os pacotes ele deverá exibir a mensagem abaixo informando que os pacotes foram atualizados. Diga Yes.

Page 20: Apostila Android Gratuita

20 Desenvolvendo Aplicações com Java para Android

Figura 25 - Atualizando os pacotes

Deverá demonstrar os arquivos atualizados, conforme figura abaixo, clique em Close.

Figura 26 - Lista de arquivos Atualizados

Próximo passo é configurar o Eclipse.

Configurando o Eclipse

Com o Eclipse instalado na maquina execute o arquivo .exe através do atalho criado.

Figura 27 - Abertura do Eclipse

Quando o Eclipse é executado ele solicita ao desenvolvedor que informe o Workspace, neste Workspace serão armazenados todos os projetos de forma organizada, vamos manter essa ideia para poder facilitar durante processo de suporte. Outro ponto interessante é que mantemos estes projetos em servidor SVN de acordo com o desenvolvimento é possível recuperar o projeto no ponto correto do livro.

Figura 28 - Informando o local do Workspace

Ao iniciar o Eclipse pela primeira vez o desenvolvedor tem que atualizar seus componentes, no nosso caso vamos apenas importar os componentes do Android, é simples basta acessar Help | Install New Software....

Page 21: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 21

Figura 29 - Atualizando componentes

Nosso objetivo é adicionar a SDK do Android no Eclipse para que possa ajudar no desenvolvimento, nesta SDK temos um conjunto de ferramentas que serão fundamentais para o progresso de nosso estudo.

Figura 30 - Adicionando o respositório de plugin

Ao clicar em Add... uma pequena janela deve ser aberta, informe o nome do Plugin e seu URL, então vamos utilizar:

Propriedade Valor

Name Android

URL https://dl-ssl.google.com/android/eclipse/

Conforme figura abaixo.

Figura 31 - Dados da nova fonte

Clique em OK para finalizar. Repare que na tela anterior aparece o Developer Tools, isso é bom. Mantenha ele selecionado e clique em Next.

Page 22: Apostila Android Gratuita

22 Desenvolvendo Aplicações com Java para Android

Figura 32 - Sites cadastrados no Eclipse

Neste momento o eclipse deve validar os sites selecionados, conforme figura abaixo e exibir uma lista de itens que podem ser instalados.

Figura 33 - Sites ativos

Deixe a opção marcada, vamos atualizar todos os objetos do Android, clique em Next e avance.

Page 23: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 23

Figura 34 - Termos de licença dos componentes

Leia os termos com atenção, se aceitar marque a opção “I accept the terms in the license agreement” e clique em Finish.

Figura 35 - O eclipse se conecta no site automaticamente para fazer o download

Atenção, se a imagem abaixo aparecer, clique em OK e continue.

Figura 36 - Informação de Segurança

Ao finalizar o download o próprio Eclipse solicitará ser reiniciado, pressione Restart Now.

Figura 37 - Mensagem de alerta

Após o Eclipse ser reiniciado ele deverá apresentar as alterações de interface, tais alterações estão relacionadas a execução correta do plugin que acabamos de adicionar.

Page 24: Apostila Android Gratuita

24 Desenvolvendo Aplicações com Java para Android

Figura 38 - Android SDK and AVD Manager

Para finalizar a configuração temos que informar ao Eclipse (plugin) qual o local a SDK Android foi instalada, para isso em Window | Preferences conforme figura abaixo.

Figura 39 - Efeito da instalação do Plugin

No item Android (ver figura abaixo) informe o caminho de instalação do SDK Android (ver Figura 20) e clique no botão Apply. Após clicar neste botão o Eclipse deverá exibir uma lista de plataformas conforme a figura abaixo.

Figura 40 - Plataformas Android instaladas

Pronto, clique em OK e seu Eclipse já se encontra configurado.

Page 25: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 25

33 3 Hello World

Objetivos Deste Capítulo Criar um projeto no Eclipse para Android;

Configurar o Emulador;

Testar o ambiente.

Introdução O Hello World tem como objetivo demonstrar ao estudante como criar um projeto muito simples e

depois como o executar, também será utilizado para validar a configuração do ambiente. Se esta etapa for concluída com sucesso deve gerar no aluno uma satisfação que eleva a moral, isso faz com que o aprendizado seja mais fácil, pois um aluno motivado é mais atento, por este motivo acredito que o Hello World é o capítulo mais importante, ele não pode ser deixado de lado pelos iniciantes.

Neste capítulo ainda vamos ter muitas imagens, como se fosse um grande tutorial, isso deve acabar nos próximos capítulos que serão mais teóricos.

Para iniciar um projeto no Eclipse é muito simples, pressione File | New | Other conforme imagem abaixo.

Figura 41 - Iniciando um Projeto

É fácil localizar o projeto Android, quando o Eclipse se conectou ao site dos desenvolvedores do Android ele automaticamente importou e instalou os plugins que facilitam o trabalho do programador. Na imagem abaixo demonstro como criar um novo projeto.

Page 26: Apostila Android Gratuita

26 Desenvolvendo Aplicações com Java para Android

Figura 42 - Criando um novo projeto

Clique em Next para avançar, na próxima tela defina o nome do projeto, neste caso vamos chamar de Hello World.

Figura 43 - Definindo o nome do projeto

Utilize o nome HelloWorld, mantenha a configuração padrão (tela acima), já nas demais opções vamos detalhar (tela inferior).

Page 27: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 27

Figura 44 - Configuração do Projeto

Application Name será o nome utilizado pela aplicação no device e o Package Name será o nome utilizado para empacotar as classes.

Um Activity é um componente do aplicativo que fornece uma tela no qual o usuário podem interagir, a fim de realizar alguma tarefa como discar o telefone, tomar um foto, envie um e-mail, ou ver um mapa. Cada Activity é controla uma janela na qual pode-se desenhar sua interface com o usuário. A janela normalmente preenche a tela, mas pode ser menor do que a tela e flutuar em cima de outras janelas, vamos nos aprofundar neste assunto no capítulo apropriado.

Um aplicativo normalmente consiste de múltiplas Activities que são fracamente ligadas umas as outras. Normalmente, uma Activity em um aplicativo é especificada como a "Activity Main", que é apresentada ao usuário ao iniciar o aplicativo pela primeira vez, no exemplo acima essa Activity Main será chamada de Gerenciador. Cada Activity pode começar outra Activity, a fim de executar várias ações diferentes. Cada vez que uma começa a Activity anterior é interrompida, mas o sistema preserva a Activity em uma pilha ("pilha de retorno").

A opção Min SDK Version informa a versão mínima do SDK que será utilizada para depuração e execução. Clique em Finsh para cliar o projeto.

Estrutura do Projeto Agora vamos entender a estrutura do projeto, afinal o plugin instalado gera a partir de nossa

configuração inúmeros arquivos. Na figura abaixo encontramos a estrutura criada no nosso projeto HelloWorld.

Page 28: Apostila Android Gratuita

28 Desenvolvendo Aplicações com Java para Android

Figura 45 - Estrutura do projeto HelloWorld

Todo o código Java que vamos desenvolver será adicionado a pasta src, nesta pasta encontramos os pacotes organizados. Gerenciador.java é a classe responsável pela nossa entrada na aplicação, sua configuração é feita no arquivo AndroidManifest.xml conforme figuras abaixo.

Figura 46 - Configuração do Pacote Principal

Nesta configuração encontramos o pacote principal, a configuração da Activity inicial é demonstrado na figura abaixo.

Page 29: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 29

Figura 47 - Configuração da Activity Gerenciador.java

Na pasta res (ver Figura 45) encontramos os Resources da aplicação, são arquivos que associados aos códigos (da pasta srv) formam a aplicação. Vamos ao exemplo de nossa interface inicial, abaixo temos o código do arquivo Gerenciador.java.

1 package br.com.softpalm.hello; 2 3 import android.app.Activity; 4 import android.os.Bundle; 5 6 public class Gerenciador extends Activity { 7 /** Called when the activity is first created. */ 8 @Override 9 public void onCreate(Bundle savedInstanceState) { 10 super.onCreate(savedInstanceState); 11 setContentView(R.layout.main); 12 } 13 }

Na linha 11 temos o comando setContentView() que adiciona um resource ao ContentView e exibe na tela do device, ele recebe como parâmetro um número inteiro que é utilizado para carregamento do Resource apropriado, neste caso R.layout.main. Vamos voltar a Figura 45 e localizar a classe R.java.

1 /* AUTO-GENERATED FILE. DO NOT MODIFY. 2 * 3 * This class was automatically generated by the 4 * aapt tool from the resource data it found. It 5 * should not be modified by hand. 6 */ 7 8 package br.com.softpalm.hello; 9 10 public final class R { 11 public static final class attr { 12 } 13 public static final class drawable { 14 public static final int icon=0x7f020000; 15 } 16 public static final class layout {

Page 30: Apostila Android Gratuita

30 Desenvolvendo Aplicações com Java para Android

17 public static final int main=0x7f030000; 18 } 19 public static final class string { 20 public static final int app_name=0x7f040001; 21 public static final int hello=0x7f040000; 22 } 23 }

O aviso é claro, não modifique pois isso é gerado automaticamente. Trouxe o aprendiz até este código para ver que o número que identifica o recurso main está na linha 17. Essa declaração é gerada automaticamente, você não precisa alterar. Resta agora achar esse tal de main. Voltando a Figura 45 encontramos em res\layout\ o artefato main.xml.

Ao efetuar um duplo clique neste arquivo ele deverá abrir um editor, conforme figura abaixo.

Figura 48 - Editor de Layout

No editor as abas 1 e 2 são responsáveis pelo layout exibido no editor, 1 apresenta um layout em que o programador arras objetos e configura, já na opção 2 o programador encontra um editor de XML, ambas as visualizações possuem a mesma função.

Em 3 temos a ToolBox, na qual encontramos os objetos de interface que usamos para montar o layout.

Em 4 encontramos uma barra de visualização, na qual podemos ver a interface em diferentes resoluções, temas, etc..

Em 5 podemos ver nossa interface.

Configurando o Emulador Antes de finalizar este capítulo vamos abordar a emulação, más antes de executar nossa aplicação

precisamos fazer algumas configurações básicas. Inicie clicando em Window | Android SDK and AVD Manager conforme figura abaixo.

Page 31: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 31

Figura 49 - Acessando o AVD Manager

Será exibida uma lista sem nenhum emulador configurado, bom então pressione New... para adicionar um emulador.

Figura 50 - Lista de Emuladores (nenhum configurado)

Para criar um emulador basta atribuir um nome, no meu caso vou chamar de Device_2_2 porque vou emular a versão 2.2 do Android. Selecionei a Target 2.2 para emular a versão 2.2 do Android.

Informe uma memória, vou usar 512MB para ter certeza que não vai ter problemas de memória, e WQVGA400 para ter uma tela pequena.

Figura 51 - Configuração do Emulador Device_2_2

Clique em Create AVD.

Page 32: Apostila Android Gratuita

32 Desenvolvendo Aplicações com Java para Android

Figura 52 - Lista de Emuladores

Pronto, emulador criado.

Executando a Aplicação Para executar nossa aplicação precisamos relacionar o nosso projeto HelloWorld com o

Device_2_2. Para isso clique em Run Configurations... conforme figura abaixo.

Figura 53 - Criando uma Configuração

Clique com o botão direito do mouse sobre Android Application conforme figura abaixo e selecione New.

Figura 54 - New Android Application

Na aba Android (ver figura abaixo) selecione usando o botão Browser... a aplicação HelloWorld.

Figura 55 – Selecionando o Projeto

Agora na aba Target selecione o Device_2_2 conforme figura abaixo.

Page 33: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 33

Figura 56 - Selecionando o Emulador

Clique em Run. A aplicação deverá chamar o emulador, que deve demorar um pouco para carregar (calma, hora de tomar um café). A demora está relacionada com o carregamento do Sistema Operacional dentro do emulador, logo abrimos uma única vez e mantemos o emulador aberto sempre.

Figura 57 - Emulador Android 2.2

Com o emulador carregado (ver figura acima) destrave arrastando o cadeado até o ponto verde. Pronto sua aplicação deverá ser carregada.

Page 34: Apostila Android Gratuita

34 Desenvolvendo Aplicações com Java para Android

Figura 58 - Aplicação HelloWorld executando

Page 35: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 35

44 4 Depurando e Distribuindo a Aplicação

Objetivos Deste Capítulo • Depurar a aplicação no Device;

• Criar uma distribuição do aplicativo.

Introdução Em muitos textos o processo de montagem de uma distribuição é abordado ao término de capítulos

mais avançados, neste texto pretendo abordar não só a depuração no device mas também esse processo visando a motivação do aprendiz. A motivação é a chave da aprendizagem, o capítulo de Hello World e este capítulo devem ser capazes de suprir as dúvidas básicas de como funciona uma aplicação e como elas se comporta no device.

Atualizando o Sistema Antes de tentar se conectar pela USB precisamos baixar alguns drivers e componentes através de

atualizações do Eclipse, no futuro vamos utilizar os componentes para navegar na estrutura do device.

No Eclipse acesse Window | Android SDK and AVD Manager conforme figura abaixo.

Figura 59 - Acessando a janela de atualização

O nosso objetivo principal é atualizar as APIs para USB, veja na figura abaixo que todas as opções foram marcadas.

Page 36: Apostila Android Gratuita

36 Desenvolvendo Aplicações com Java para Android

Figura 60 - Atualizando as APIs

Clique em Install Selected, e aguarde.

Depurando uma Aplicação pelo Device Durante o desenvolvimento a depuração do código é uma tarefa inevitável, isso porque a

complexidade computacional é grande. Com o ambiente Eclipse configurado essa tarefa é fácil, realizar a depuração do código exige pouco esforço. Vou alterar o código da classe Gerenciador.java do projeto HelloWorld para poder depurar. Segue abaixo o código alterado.

1 package br.com.softpalm.hello; 2 3 import android.app.Activity; 4 import android.os.Bundle; 5 6 public class Gerenciador extends Activity { 7 /** Called when the activity is first created. */ 8 @Override 9 public void onCreate(Bundle savedInstanceState) { 10 super.onCreate(savedInstanceState); 11 setContentView(R.layout.main); 12 13 String s = System.getProperty("java.io.tmpdir"); 14 } 15 }

Apenas adicionei uma linha (linha 13) para ter algo para verificar, vamos ver em tempo de execução o valor atribuído a s.

Para isso vamos ter que criar um ponto de parada, clique com o botão direito do mouse na barra lateral esquerda do código conforme figura abaixo.

Page 37: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 37

Figura 61 - Linha que será adicionada o BreakPoint

Repare que estou posicionando o mouse exatamente na linha anterior a atribuição, poderia ser justamente na linha porem o símbolo de Warning está atrapalhando a visibilidade do ponto que quero demonstrar.

Clicando com o botão direito do mouse deverá aparecer um menu suspenso conforme figura abaixo.

Figura 62 - Adicionando o BreakPoint

Selecione Toggle Breakpoint. Repare que agora aparece um bolinha azul na linha que pretendemos parar.

Figura 63 - Linha com BreakPoint

Agora vamos configurar nosso emulador/device para depuração, para isso clique em Debug Configurations... conforme figura abaixo.

Page 38: Apostila Android Gratuita

38 Desenvolvendo Aplicações com Java para Android

Figura 64 - Acessando Debug Configurations...

Nos já temos a configuração feita no capítulo anterior, então vamos só alterar. Para isso clique em Terget.

Figura 65 - Configuração já existente

Nosso objetivo é marcar como Manual e procurar em uma lista de devices ou emuladores a opção que queremos usar como teste.

Figura 66 - Alterando a Target

A figura acima é a configuração como está (baseado no capítulo anterior) já a tela abaixo temos a opção Manual marcado.

Figura 67 - Configuração Manual

Agora vamos iniciar o processo de depuração, clique em Run. Será exibida uma lista conforme a imagem abaixo.

Page 39: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 39

Figura 68 - Lista de Devices/Emuladores

No meu caso não tenho nenhum device conectado no momento, somente o emulador. Se você tiver um device com Android 2.2 conectado então ele deverá aparecer na lista. Muito simples, escolha a opção e clica em OK.

Atenção: Se você tem um equipamento conectado e ele não aparece na lista então veja o Apêndice 1 Habilitando Depuração.

Figura 69 - Eclipse iniciando a depuração

Repare que o Eclipse deve mudar a sua perspectiva.

Figura 70 - Perspectiva

Atenção: Se não abrir a perspectiva Debug conforme figura acima recorra ao Apêndice 2 Perspectiva no Eclipse.

Ao abrir o Eclipse ele vai estar em modo Debug (figura acima) e com a linha que possui o Breakpoint selecionada e com um cursor também em azul (setinha em cima da bolinha conforme imagem abaixo).

Page 40: Apostila Android Gratuita

40 Desenvolvendo Aplicações com Java para Android

Figura 71 - Código em modo debug

Agora vamos pressionar duas vezes (devagar) a tecla F6 para o cursor andar duas linhas, conforme figura abaixo (repare que o cursor azul está na chave).

Figura 72 - Depuração após 2xF6

Agora passe o cursor sobre a variável s, veja que deve abrir uma caixa com o valor contido em s.

Figura 73 – Valores da variável

Os valores das variáveis também podem ser vistos na aba Variables conforme figura abaixo.

Page 41: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 41

Figura 74 - Aba variables

Desta forma você pode testar linha a linha sua aplicação antes de construir a versão release (versão final).

Deploy Ao chegar neste tópico o aprendiz ao menos já possui em suas mãos o projeto HelloWorld

compilando, ótimo pois precisamos somente deste até o momento.

Nosso objetivo é a montagem do arquivo .apk, este arquivo é um Instalador que vamos distribuir, o usuário final pode através de um cartão de memória executar este arquivo diretamente no device.

Antes de partir para a construção do arquivo .apk temos que abordar um assunto sobre certificações digitais, o sistema android exige que todas as aplicações instaladas tenham certificados digitais assinados com uma chave privada, este certificado é utilizado não para controlar se uma aplicação pode ou não ser instalada, mas sim para identificar o autor da aplicação e manter uma certa relação de confiança.

Os pontos importantes para a compreensão sobre assinaturas digitais para Android são:

1 - Todas as aplicações devem ser assinadas. O sistema não irá instalar uma aplicação que não está assinada;

2 - Nenhuma autoridade controla os certificados, você pode gerar tais certificados a partir da sua máquina. No nosso caso vamos configurar o Eclipse para tal tarefa;

3 - Quando você estiver pronto para liberar o seu aplicativo para usuários finais, você deverá assiná-lo com uma chave apropriada privada. Você não pode publicar um aplicativo que está assinado com a chave de depuração gerado pelas ferramentas do SDK.

O sistema Android não irá instalar ou executar um aplicativo que não está assinado apropriadamente. Isto se aplica sempre que o sistema é executado no Android, mesmo em um emulador. Por esta razão, você deve configurar a assinatura para a sua aplicação antes de você ser capaz de executar ou depurar-lo em um emulador ou dispositivo.

As ferramentas do Android SDK ajudará você a assinar seus aplicativos durante a depuração. Tanto o Plugin ADT para o Eclipse e o Ant oferecer ferramenta de dois modos de assinatura - debug mode e release mode.

Durante o desenvolvimento e teste, você pode compilar em modo de depuração "debug mode". Em modo de depuração, a ferramenta build usa o utilitário keytool (incluído no JDK), para criar e armazenar as chaves.

Quando seu aplicativo está pronto para lançamento (release), você deve compilar no modo de liberação (release mode), em seguida assinar o APK com sua chave privada. Há duas maneiras de fazer isso:

• Usando Keytool e jarsigner por linha de comando no prompt;

• Usando o Assistente de Exportação no Eclipse (que faz tudo).

Atenção: Não precisa ter medo desta complexidade, no Eclipse isso é mais fácil que tirar bala de criança.

Conhecendo um pouco a idéia então vamos construir nosso instalador. Selecione o projeto com botão direito do mouse Android Tools | Export Signed Application Package... conforme figura abaixo.

Page 42: Apostila Android Gratuita

42 Desenvolvendo Aplicações com Java para Android

Figura 75 - Export Signed Application Package

Selecione o projeto, que no nosso caso é o HelloWorld, conforme figura abaixo.

Figura 76 - Selecionando o Projeto

Agora temos que selecionar uma chave existente ou criar uma, como é nossa primeira exportação vamos criar uma nova chave. Preencha o formulário conforme figura abaixo.

Atenção: Para todos os campos senhas vou usar: android

Figura 77 - Gerando uma Chave

Agora vamos preencher os demais dados da nossa chave, conforme figura abaixo.

Page 43: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 43

Figura 78 - Dados de uma chave

Agora falta pouco, temos que apontar para um diretório e dar nome ao nosso instalador, conforme feito na figura abaixo.

Figura 79 - Diretório de exportação

Pronto, feito J. No Eclipse tudo é mais fácil. Veja no Windows Explorer (figura abaixo) que o arquivo foi gerado.

Figura 80 - Arquivo .apk gerado com sucesso

Agora você deve pegar este arquivo .apk e adicionar a um Cartão, introduza o cartão no equipamento e através do navegador do seu equipamento encontre o arquivo, ao efetuar um clique sobre ele automaticamente será instalado.

Page 44: Apostila Android Gratuita

44 Desenvolvendo Aplicações com Java para Android

55 5 A Linguagem

Objetivos Deste Capítulo • Especificação da linguagem;

• Declaração de variáveis;

• Como utilizar instruções de seleção if e if...else para escolher entre ações alternativas;

• Utilizando o switch para determinar um bloco de ações específicas;

• Como utilizar instruções de repetição, tais como while, for, do...while;

• Noção de fluxogramas.

Introdução Antes de escrever um programa capaz de resolver um problema, é essencial ter entendimento

completo do problema e planejar uma abordagem simples mais eficiente que resolva tal problema. Ao escrever um programa, também é essencial entender os tipos de blocos de construção que estão disponíveis e empregar técnicas comprovadas de construção de programa. Os conceitos apresentados aqui são importantes para o programador Android, principalmente se este programador for iniciante no mundo orientado a objetos ou Java.

Neste capítulo vamos introduzir a teoria Java pois é a base para o desenvolvimento, tais como as instruções if, if...else, switch, while, for e do...while, etc..

Algoritmos Qualquer problema de computação pode ser resolvido executando-se uma série de ordem

específica. O exemplo a seguir demonstra que é importante especificar corretamente a ordem em que as ações executam.

Algoritmo: Algoritmo para treino da Escola Ájax de Futebol.

Descrição: Aos sábados, o autor deste livro realiza um trabalho social que visa tirar crianças carentes da rua, ministrando treinamento físico em uma escolinha de futebol infantil. Os trabalhos seguem o seguinte algoritmo:

Inicia-se os trabalhos verificando as qualidades das chuteiras e material de trabalho;

Se existe algo com problema anote;

Realizar chamada;

Se criança ausente, procure saber o motivo com os colegas;

Conversar com algumas crianças para saber como foi a semana, na escola entre outras coisas, no máximo 10 minutos (repetição indefinida);

Inicia-se um alongamento;

Inicia-se uma corrida moderada no campo, enquanto não for 10 voltas não parar (repetição de 0 até

Page 45: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 45

10);

60 minutos de coletivo (repetição de 0 até 60);

Uma pequena parada para conversar com as crianças, sobre assuntos que as motivam.

Repare que o algoritmo teoricamente pode ser qualquer texto que exprima ações e seqüência em que ocorrem as ações, imagine que se o contador na ação 5 não fosse incrementado, estaríamos dando voltas no campo até hoje, tudo tem que funcionar de forma seqüencial e correta. Se as ações 3 e 7 não fossem executadas não seria um serviço social que visa formar um ser social, estaria apenas fazendo um jogador. Se a ação 1 não ocorrer, um belo dia não vamos ter bolas ou chuteiras para as crianças.

Sempre use algoritmos de alto nível para entender melhor o problema, muitas vezes a solução é tão simples que se torna imperceptível durante a edição do código fonte.

Variáveis, Operadores e Estruturas de Controle Apresentaremos agora uma pequena discussão sobre a sintaxe da linguagem Java, abordando os

tipos de dados existentes, as regras para declaração de variáveis, as recomendações gerais para nomenclatura, os operadores, sua precedência e as estruturas de controle disponíveis. Como será notado, a sintaxe da linguagem Java é muito semelhante àquela usada pela linguagem C/C++.

Variáveis Na matemática de segundo grau lidamos com variáveis a todo momento, variável é um símbolo que

armazena um valor não fixo, ou seja, o programador não pode prever os valores possíveis. Na matemática pouco importa se o número que será atribuído é 6 ou 2,4, ambos poderiam se atribuídos em uma variável X. Veja que não é preciso informar o tipo de variável, porque a matemática é uma linguagem fracamente tipada. Já a linguagem Java é fortemente tipada, temos que definir os tipos de objetos durante a sua criação.

Tipos de Dados Primitivos A linguagem Java possui oito tipos básicos de dados, denominados tipos primitivos, que podem

agrupados em quatro categorias:

Categoria Tipo Primitivo

Tipo Inteiro Byte; Inteiro Curto; Inteiro; Inteiro Longo

Tipo Ponto Flutuante Ponto Flutuante Simples; Ponto Flutuante Duplo

Tipo Lógico Boleano

Tipo Caracter Caractere

Tipos de dados primitivos

Como pode ser facilmente observado, os tipos primitivos do Java são os mesmos encontrados na maioria das linguagens de programação e permitem a representação adequada de valores numéricos. A representação de outros tipos de dados utiliza objetos específicos assim como existem classes denominadas wrappers que encapsulam os tipos primitivos como objetos da linguagem.

Tipos de Dados Inteiros

Existem quatro diferentes tipos de dados inteiros byte (8 bits), short (inteiro curto - 16 bits), int (inteiro - 32 bits) e long (inteiro longo - 64 bits) cuja representação interna é feita através de complemento de 2 e que podem armazenar valores dentro dos seguintes intervalos numéricos:

Tipo Valor Mínimo Valor Máximo

byte -128 +127

short -32.768 + 32.767

int -2.147.483.648 +2.147.483.647

Page 46: Apostila Android Gratuita

46 Desenvolvendo Aplicações com Java para Android

long 9.223.372.036.854.775.808

+9.223.372.036.854.775.807

Tipos de Dados Inteiros

Por padrão os valores literais são tratados como inteiros simples (int) ou seja valores de 32 bits. Não existe em Java o modificador unsigned disponível em outras linguagens assim os tipos inteiros são sempre capazes de representar tanto valores positivos como negativos.

Tipo de Dados em Ponto Flutuante

No Java existem duas representações para números em ponto flutuante que se diferenciam pela precisão oferecida: o tipo float permite representar valores reais com precisão simples (representação interna de 32 bits) enquanto o tipo double oferece dupla precisão (representação interna de 64 bits). Os valores m ponto flutuante do Java estão em conformidade com o padrão IEEE 754:

Tipo Valor Mínimo Valor Máximo

float

double

Tipos de Dados em Ponto Flutuante

Deve ser utilizado o ponto como separador de casas decimais. Quando necessário, expoentes podem ser escritos usando o caractere 'e' ou 'E', como nos seguintes valores:

1.44E6 (= 1.44 x 106 = 1,440,000) ou 3.4254e-2 (= 3.4254 x 10-2 = 0.034254).

Tipo de Dados Caractere O tipo char permite a representação de caracteres individuais. Como o Java utiliza uma

representação interna no padrão UNICODE, cada caractere ocupa 16 bits (2 bytes) sem sinal, o que permite representar até 32.768 caracteres diferentes, teoricamente facilitando o trabalho de internacionalização de aplicações Java. Na prática o suporte oferecido ao UNICODE ainda é bastante limitado embora permita a internacionalização do código Java.

Alguns caracteres são considerados especiais pois não possuem uma representação visual, sendo a maioria caracteres de controle e outros caracteres cujo uso é reservado pela linguagem. Tais caracteres podem ser especificados dentro dos programas como indicado na tabela abaixo, ou seja, precedidos por uma barra invertida ('\'):

Representação Significado

\n Pula linha (newline ou linefeed)

\r Retorno de carro (carriage return)

\b Retrocesso (backspace)

\t Tabulação (horizontal tabulation)

\f Nova página (formfeed)

\’ Apóstrofe

\” Aspas

\\ Barra Invertida

\u223d Caractere UNICODE 233d

\g37 Octal

\fca Hexadecimal

Representação de Caracteres Especiais

O valor literal de caracteres deve estar delimitado por aspas simples (' ').

Page 47: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 47

Tipo de Dados Lógico Em Java dispõe-se do tipo lógico boolean capaz de assumir os valores false (falso) ou true

(verdadeiro) que equivalem aos estados off (desligado) e on (ligado) ou no (não) e yes (sim).

Deve ser destacado que não existem equivalência entre os valores do tipo lógico e valores inteiros tal como usualmente definido na linguagem C/C++.

Declaração de variáveis Uma variável é um símbolo definido pelo programador ao qual pode ser associado um valor

pertencente a um certo tipo de dados (que já estudamos). Em outras palavras, uma variável é como uma memória, capaz de armazenar um valor de um certo tipo, para a qual se dá um nome que usualmente descreve seu significado ou propósito e que usamos como referência natural (linguagem natural do ser humano). Desta forma toda variável possui um nome, um tipo e um conteúdo.

Figura 81 - Variável com Nome, tipo e conteúdo (Barbosa, 2010).

O nome de uma variável em Java pode ser uma seqüência de um ou mais caracteres alfabéticos e numéricos, iniciados por uma letra ou ainda pelos caracteres '_' (underscore) ou '$' (cifrão). Os nomes não podem conter outros símbolos gráficos, operadores ou espaços em branco, podendo ser arbitrariamente longos embora apenas os primeiros 32 caracteres serão utilizados para distinguir nomes de diferentes variáveis.

É importante ressaltar que as letras minúsculas são consideradas diferentes das letras maiúsculas, ou seja, a linguagem Java é sensível ao caixa empregado, assim temos como exemplos válidos: a, total, x2, $mine, _especial, TOT, Maximo e ExpData.

Segundo as mesmas regras temos abaixo exemplos inválidos de nomes de variáveis: 1x, Total geral, numero-minimo e void.

A razão destes nomes serem inválidos é simples: o primeiro começa com um algarismo numérico, o segundo possui um espaço em branco, o terceiro contêm o operador menos mas por que o quarto nome é inválido?

Porque além das regras de formação do nome em si, uma variável não pode utilizar como nome uma palavra reservada da linguagem. As palavras reservadas são os comandos, nomes dos tipos primitivos, especificadores e modificadores pertencentes a sintaxe de uma linguagem.

As palavras reservadas da linguagem Java que, portanto não podem ser utilizadas como nome de variáveis ou outros elementos, são:

abstract continue finally interface public Throw

boolean default float long return Throws

break do for native short Transient

byte else implements null super Try

case else implements null super Try

catch extends import package switch Void

char false instanceof private synchronized While

Page 48: Apostila Android Gratuita

48 Desenvolvendo Aplicações com Java para Android

class final int protected this

Palavras reservadas da linguagem Java

Além destas existem outras que embora reservadas não são utilizadas pela linguagem: const, future, generic, goto, inner, operator, outer, rest, var, volatile, etc..

Algumas destas, tal como o goto, faziam parte da especificação preliminar do Oak, antes de sua formalização como Java. Recomenda-se não utilizá-las qualquer que seja o propósito.

Também devemos seguir uma ordem, por exemplo, não podemos dizer “prato o de me”, temos que dizer “me de o prato”, logo para que o compilador entenda temos que dizer:

int meusimbolo;

Chamamos isso de sintaxe, desta forma para declararmos uma variável devemos seguir a seguinte sintaxe:

Tipo nome1 [, nome2 [, nome3 [..., nomeN]]];

Ou seja, primeiro indicamos um tipo, depois declaramos uma lista contendo um ou mais nomes de variáveis desejadas deste tipo, onde nesta lista os nomes são separados por vírgulas e a declaração terminada por ';' (ponto e vírgula). Exemplos:

1 // Uma única variável 2 int i; 3 // Declaração com muitas variáveis 4 float total, preco; 5 // Declarando e já adicionando um valor 6 int mascara = 5;

Código 1 - Código de Exemplo

A declaração anterior (Linha 4) equivale as duas declarações abaixo:

1 float total; 2 float preco;

Código 2 - Código de Exemplo

Também é possível definirmos uma valor inicial para uma variável diretamente em sua declaração como indicado a seguir:

Variáveis podem ser declaradas em qualquer ponto de um programa Java, sendo válidas em todo o escopo onde foram declaradas (a partir da linha em que foi criada) e nos escopos internos à estes. Por escopo entende-se como bloco (conjunto de comandos da linguagem) onde ocorreu a declaração da variável.

Dica para Denominação de Variáveis

Em Java recomenda-se que a declaração de variáveis utilize nomes iniciados com letras minúsculas. Caso o nome seja composto de mais de uma palavras, as demais deveriam ser iniciadas com letras maiúsculas tal como nos exemplos: contador, total, sinal, posicaoAbsoluta, valorMinimoDesejado, mediaGrupo e Tarefa2.

A utilização de caracteres numéricos no nome é livre enquanto o uso do traço de sublinhar (underscore '_') não é recomendado.

Comentários Comentários são trechos de texto, usualmente explicativos, inseridos dentro do programa de forma

que não sejam considerados como parte do código, ou seja, são informações deixadas juntamente com o código para informação de quem programa.

O Java aceita três tipos de comentários: de uma linha, de múltiplas linhas e de documentação. O primeiro de uma linha utiliza duas barras (//) para marcar seu início:

Page 49: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 49

1 // comentário de uma linha 2 // tudo após as duas barras é considerado comentário

Código 3 - Código de Exemplo

O segundo usa a combinação /* e */ para delimitar uma ou mais linhas de comentários:

1 /* comentário 2 de múltiplas linhas */

Código 4 - Código de Exemplo

O último tipo é semelhante ao comentário de múltiplas linhas mas tem o propósito de documentar o programa:

1 /** comentário de documentação que também 2 * podem ter múltiplas linhas 3 */

Código 5 - Código de Exemplo

Geralmente o comentário de documentação é posicionado imediatamente antes do elemento a ser documentado e tem seu conteúdo extraído automaticamente pelo utilitário javadoc fornecido juntamente com o JDK. Esta ferramenta gera páginas em formato html contendo os comentário organizados da mesma forma que a documentação fornecida juntamente com o JDK.

Aproveitando tal característica do javadoc, usualmente se adicionam tags html aos comentários de documentação para melhorar a forma final da documentação produzida com a inclusão de imagens, tabelas, textos explicativos, links e outros recursos. Além das tags html vários tipos de informação administradas pelo javadoc podem ser adicionadas a estes comentários especiais através de marcadores pré-definidos iniciados com "@" que permitem a criação automática de ligações hipertexto entre a documentação e a formatação padronizada de outros elementos, tais como nome do autor, parâmetros, tipo de retorno, etc. conforme Código 6.

1 package br.com.softpalm; 2 3 import java.io.*; 4 /** 5 * Classe destinada ao armazenamento de dados relacionados a arquivos ou 6 * diretórios. 7 * <p> 8 * Pode ser usada para armazenar árvores de diretórios. 9 * 10 * @author Wellington Pinto de Oliveira 11 * @see java.io.File 12 */ 13 public class FileData extends File { 14 15 /** 16 * Construtor 17 * 18 * @param filename 19 * nome do arquivo 20 */ 21 public FileData(String filename) { 22 super(filename); 23 } 24 }

Código 6 - Código da classe FileData v.: 1.0

Operadores A linguagem Java oferece um conjunto bastante amplo de operadores destinados a realização de

Page 50: Apostila Android Gratuita

50 Desenvolvendo Aplicações com Java para Android

operações aritméticas, lógicas, relacionais e de atribuição.

Operadores Aritméticos

Como na maioria das linguagens de programação, o Java possui vários operadores aritméticos, conforme descritos na Tabela 1 - Operadores.

Operador Significado Exemplo

+ Adição a + b

- Subtração a – b

* Multiplicação a * b

/ Divisão a / b

% Resto da Divisão Inteira a % b

- Sinal negativo (- unário) -a

+ Sinal Positivo (+ unário) +a

++ Incremento unitário ++a ou a++

-- Decremento unitário --a ou a--

Tabela 1 - Operadores

Estes operadores aritméticos podem ser combinados para formar expressões onde deve ser observada a precedência (ordem convencional) de avaliação dos operadores.

Parêntesis podem ser utilizados para determinar uma forma específica de avaliação de uma expressão. A seguir um exemplo de aplicação que declara algumas variáveis, atribui valores iniciais e efetua algumas operações imprimindo os resultados obtidos.

1 package br.com.softpalm; 2 3 public class Operadores { 4 5 /** 6 * @param args 7 */ 8 public static void main(String[] args) { 9 int a = 5; 10 int b = 2; 11 12 // Varios exemplos de operacoes sobre variaveis 13 System.out.println("a = " + a); 14 System.out.println("b = " + b); 15 System.out.println("-b = " + (-b)); 16 System.out.println("a + b = " + (a + b)); 17 System.out.println("a - b = " + (a - b)); 18 System.out.println("a * b = " + (a * b)); 19 System.out.println("a / b = " + (a / b)); 20 System.out.println("(float) a / b = " + ((float) a / b)); 21 System.out.println("a % b = " + (a % b)); 22 System.out.println("a++ = " + (a++)); 23 System.out.println("--b = " + (--b)); 24 System.out.println("a = " + a); 25 System.out.println("b = " + b); 26 } 27 }

Código 7 - Código da classe Operadores (Revisão svn 1)

Page 51: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 51

Compilando e executando o código fornecido teríamos o resultado ilustrado a seguir:

Figura 82 Resultado da Aplicação Aritmética

Embora o exemplo só tenha utilizado variáveis e valores inteiros, o mesmo pode ser realizado com variáveis do tipo ponto flutuante (float ou double).

Operadores Relacionais

Além dos operadores aritméticos o Java possui operadores relacionais, isto é, operadores que permitem comparar valores literais, variáveis ou o resultado de expressões retornando um resultado do tipo lógico, isto é, um resultado falso ou verdadeiro. Os operadores relacionais disponíveis são:

Operador Significado Exemplo

== Igual a == b

!= Diferente a != b

> Maior que a > b

< Menor que a < b

>= Maior ou igual a a >= b

<= Menor ou igual a a <=b

Tabela 2 - Tabela de Operadores

A seguir um outro exemplo simples de aplicação envolvendo os operadores relacionais. Como para os exemplos anteriores, sugere-se que esta aplicação seja testada como forma de se observar seu comportamento e os resultados obtidos.

1 package br.com.softpalm; 2 3 public class Relacionais { 4 5 /** 6 * @param args 7 */ 8 public static void main(String[] args) { 9 int a = 15; 10 int b = 12; 11 System.out.println("a = " + a); 12 System.out.println("b = " + b); 13 System.out.println("a == b -> " + (a == b)); 14 System.out.println("a != b -> " + (a != b)); 15 System.out.println("a < b -> " + (a < b));

Page 52: Apostila Android Gratuita

52 Desenvolvendo Aplicações com Java para Android

16 System.out.println("a > b -> " + (a > b)); 17 System.out.println("a <= b -> " + (a <= b)); 18 System.out.println("a >= b -> " + (a >= b)); 19 } 20 }

Código 8 - Código da clase Relacionais (Revisão svn 2)

Operadores Lógicos Como seria esperado o Java também possui operadores lógicos, isto é, operadores que permitem

conectar logicamente o resultado de diferentes expressões aritméticas ou relacionais construindo assim uma expressão resultante composta de várias partes e portanto mais complexa.

Operador Significado Exemplo

&& E lógico a && b

|| Ou lógico a || b

! Negação !a

Tabela 3 - Operadores Lógicos

Os operadores lógicos duplos, isto é, definidos por dois caracteres, também não podem conter espaços em branco.

Operador de Atribuição

Atribuição é a operação que permite definir o valor de uma variável através de uma constante ou através do resultado de uma expressão envolvendo operações diversas.

1 boolean result = false; 2 i = 0; 3 y = a*x + b;

Código 9 - Exemplo de Código

Em Java é válido o encadeamento de atribuições, tal como abaixo, onde todas as variáveis são inicializadas com o mesmo valor:

1 byte m, n, p, q; 2 M 3 m = n = p = q = 0; // equivale a m = (n = (p = (q = 0)));

Código 10 - Exemplo de Código

Precedência de Avaliação de Operadores

Numa expressão onde existam diversos operadores é necessário um critério para determinar-se qual destes operadores será primeiramente processado, tal como ocorre em expressões matemáticas comuns. A precedência é este critério que especifica a ordem de avaliação dos operadores de um expressão qualquer. Na Tabela 4 temos relacionados os níveis de precedência organizados do maior (Nível 1) para o menor (Nível 15). Alguns dos operadores colocados na tabela não estão descritos neste texto.

Nível Operadores

1 . (Seletor) [] ()

2 ++ -- ~ instanceof new clone – (unário)

3 * / %

4 + -

Page 53: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 53

5 << >> >>>>

6 < > <= >=

7 == !=

8 &

9 ^

10 |

11 &&

12 ||

13 ?

14 = op=

15 ,

Tabela 4 - Precedência dos Operadores em Java

Note que algumas palavras reservadas (instanceof, new e clone) se comportam como operadores. Operadores de um mesmo nível de precedência são avaliados conforme a ordem em que são encontrados, usualmente da esquerda para direita. Para modificarmos a ordem natural de avaliação dos operadores é necessário utilizarmos os parêntesis, cujo nível de avaliação é o mais alto, para especificar-se a ordem de avaliação desejada.

Estruturas de Controle Um programa de computador é uma seqüência de instruções organizadas de forma tal a produzir a

solução de um determinado problema. Naturalmente tais instruções são executadas em seqüência, o que se denomina fluxo seqüencial de execução. Em inúmeras circunstâncias é necessário executar as instruções de um programa em uma ordem diferente da estritamente seqüencial. Tais situações são caracterizadas pela necessidade da repetição de instruções individuais ou de grupos de instruções e também pelo desvio do fluxo de execução.

As linguagens de programação tipicamente possuem diversas estruturas de programação destinadas ao controle do fluxo de execução, isto é, estruturas que permitem a repetição e o desvio do fluxo de execução. Geralmente as estruturas de controle de execução são divididas em:

• Estruturas de repetição simples

Destinadas a repetição de um ou mais comandos, criando o que se denomina laços. Geralmente o número de repetições é pré-definido ou pode ser determinado pelo programa durante a execução. No Java dispõe-se da diretiva for.

• Estruturas de desvio de fluxo

Destinadas a desviar a execução do programa para uma outra parte, quebrando o fluxo seqüencial de execução. O desvio do fluxo pode ocorrer condicionalmente, quando associado a avaliação de uma expressão, ou incondicionalmente. No Java dispõe-se das diretivas if, if...else e switch.

• Estruturas de repetição condicionais

Semelhantes as estruturas de repetição simples mas cuja repetição está associada a avaliação de uma condição sendo geralmente utilizadas quando não se conhece de antemão o número necessário de repetições. No Java dispõe-se das diretivas while e do...while.

Além destas estruturas existem ainda:

• Mecanismos de modularizaço

• Estruturas de controle de erros

Page 54: Apostila Android Gratuita

54 Desenvolvendo Aplicações com Java para Android

Figura 83 - Variações do Fluxo de execução de um Programa

Os mecanismos de modularizaço são aqueles que nos permitem a construção de funções e procedimentos (dentro do paradigma procedural) ou métodos (dentro da paradigma da orientação à objetos) e serão discutidos na próxima seção. Já as estruturas de controle de erros constituem uma importante contribuição a programação pois simplifica bastante a inclusão e construção de rotinas de tratamento de erros dentro do código.

Antes de tratarmos especificamente das estruturas de controle da linguagem é necessário colocarmos algumas definições. Formalmente as instruções de um programa são chamadas diretivas (statements). Tradicionalmente as diretivas são escritas uma após o outra num programa e são separadas de alguma forma, por exemplo com uma quebra de linha ou um caractere de pontuação.

Em Java, tal como na linguagem C/C++, as diretivas são separadas uma das outras através do símbolo de pontuação ';' (ponto e vírgula), sendo possível existir várias diretivas numa mesma linha desde que separadas por um ponto e vírgula. Abaixo temos um exemplo hipotético de várias diretivas colocadas seqüencialmente:

diretiva1;

diretiva2;

diretiva3;

...

diretivaN;

Como nas outras linguagens de programação, as estruturas de controle podem operar sobre diretivas isoladas (individuais) ou sobre várias diretivas tratadas como um conjunto que é denominado bloco. Um bloco em Java é um grupo de diretivas delimitadas por chaves ({K}). Por sua vez um bloco de diretivas recebe um tratamento equivalente ao de uma única diretiva individual.

{

diretiva1;

diretiva2;

diretiva3;

...

diretivaN;

}

diretivaUnica;

Estruturas de repetição simples

Como repetição simples consideramos um trecho de código, isto é, um conjunto de diretivas que

Page 55: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 55

deve ser repetido um número conhecido e fixo de vezes. A repetição é uma das tarefas mais comuns da programação utilizada para efetuarmos contagens, para obtenção de dados, para impressão etc. Em Java dispomos da diretiva for cuja sintaxe é dada a seguir:

for (inicialização; condição de execução; incremento/decremento)

diretiva;

O for possui três campos ou seções, todas opcionais, delimitados por um par de parêntesis que efetuam o controle de repetição de uma diretiva individual ou de um bloco de diretivas. Cada campo é separado do outro por um ponto e vírgula. O primeiro campo é usado para dar valor inicial a uma variável de controle (um contador). O segundo campo é uma expressão lógica que determina a execução da diretiva associada ao for, geralmente utilizando a variável de controle e outros valores.

Figura 84- Comportamento da Diretiva for

Após a execução da seção de inicialização ocorre a avaliação da expressão lógica. Se a expressão é avaliada como verdadeira, a diretiva associada é executada, caso contrário o comando for é encerrado e a execução do programa prossegue com o próximo comando após o for. O terceiro campo determina como a variável de controle será modificada a cada iteração do for. Considera-se como iteração a execução completa da diretiva associada, fazendo que ocorra o incremento ou decremento da variável de controle. A seguir um exemplo de utilização da diretiva for:

1 package livro.linguagem.estControle; 2 import waba.sys.*; 3 /** 4 * Classe que demonstra o uso do FOR 5 * @author Wellington 6 * @version 1.0 7 */ 8 9 public class ExemploFor extends waba.ui.MainWindow { 10 1 public ExemploFor() 2 { 3 for(int j = 0; j < 10; j++) 4 { 5 System.out.println("Volta: " + j); 6 } 7 } 8 }

Código 11 – Código da ExemploFor

Se executado, o exemplo acima deverá exibir uma contagem de 0 até 9 onde cada valor é exibido

Page 56: Apostila Android Gratuita

56 Desenvolvendo Aplicações com Java para Android

numa linha do console.

Estruturas de desvio de fluxo

Existem várias estruturas de desvio de fluxo que podem provocar a modificação da maneira com que as diretivas de um programa são executadas conforme a avaliação de uma condição. O Java dispõe de duas destas estruturas: if e switch.

O if é uma estrutura simples de desvio de fluxo de execução, isto é, é uma diretiva que permite a seleção entre dois caminhos distintos para execução dependendo do resultado falso ou verdadeiro resultante de uma expressão lógica.

if (expressão_lógica)

diretiva1;

else

diretiva2;

A diretiva if permite duas construções possíveis: a primeira, utilizando a parte obrigatória, condiciona a execução da diretiva1 a um resultado verdadeiro oriundo da avaliação da expressão lógica associada; a segunda, usando opcionalmente o else, permite que seja executada a diretiva1 caso o resultado da expressão seja verdadeiro ou que seja executada a diretiva2 caso tal resultado seja falso. Isto caracteriza o comportamento ilustrado pela Figura 7.

A seguir um exemplo de uso da diretiva if.

1 package br.com.softpalm; 2 3 public class ExemploIf { 4 5 /** 6 * @param args 7 */ 8 public static void main(String[] args) { 9 int x = 0; 10 int y = 10; 11 12 if (x == y) { 13 System.out.println("x é igual a y"); 14 } else { 15 System.out.println("x não é igual a y"); 16 } 17 } 18 }

Código 12 – Código da classe ExemploIf (Revisão svn 3)

Ao executar-se ente programa podem ocorrer duas situações distintas como resultado: ou x é igual a y ou é diferente.

Page 57: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 57

Figura 85 - Uso do if

Já o switch é uma diretiva de desvio múltiplo de fluxo, isto é, baseado na avaliação de uma expressão ordinal é escolhido um caminho de execução dentre vários possíveis. Um resultado ordinal é aquele pertencente a um conjunto onde se conhecem precisamente o elemento anterior e o posterior, por exemplo o conjunto dos números inteiros ou dos caracteres, ou seja, um valor dentro de um conjunto cujos valores podem ser claramente ordenados (0, 1, 2 .... no caso dos inteiros e 'A', 'B', 'C'... no caso dos caracteres).

O switch equivale logicamente a um conjunto de diretivas if encadeadas, embora seja usualmente mais eficiente durante a execução. Na Figura 86 temos ilustrado o comportamento da diretiva switch.

A sintaxe desta diretiva é a seguinte:

switch (expressão_ordinal) {

case ordinal1: diretiva3;

break;

case ordinal2: diretiva2;

break;

default: diretiva_default;

}

A expressão utilizada pelo switch deve necessariamente retornar um resultado ordinal. Conforme o resultado é selecionado um dos casos indicados pela construção case ordinal. As diretivas encontradas a partir do caso escolhido são executadas até o final da diretiva switch ou até uma diretiva break que encerra o switch. Se o valor resultante não possuir um caso específico são executadas as diretivas default colocadas, opcionalmente, ao final da diretiva switch.

Figura 86 - Comportamento da Diretiva switch

Note que o ponto de início de execução é um caso (case) cujo valor ordinal é aquele resultante da

Page 58: Apostila Android Gratuita

58 Desenvolvendo Aplicações com Java para Android

expressão avaliada. Após iniciada a execução do conjunto de diretivas identificadas por um certo caso, tais ações só são interrompidas com a execução de uma diretiva break ou com o final da diretiva switch.

A seguir temos uma aplicação simples que exemplifica a utilização das diretivas

1 package br.com.softpalm; 2 3 public class ExemploSW { 4 5 /** 6 * @param args 7 */ 8 public static void main(String[] args) { 9 int numero = 2; 10 switch (numero) { 11 case 1: 12 System.out.println("Um"); 13 break; 14 case 2: 15 System.out.println("Dois"); 16 break; 17 case 3: 18 System.out.println("Três"); 19 break; 20 case 4: 21 System.out.println("Quatro"); 22 break; 23 case 5: 24 System.out.println("Cinco"); 25 break; 26 default: 27 System.out.println("Maior que cinco"); 28 } 29 } 30 }

Código 13 – Código da ExemploSW (Revisão svn 4)

Como a variável número possui o valor 2 é natural que ele deva escrever “Dois” na saída.

Estruturas de repetição condicionais As estruturas de repetição condicionais são estruturas de repetição cujo controle de execução é

feito pela avaliação de expressões condicionais. Estas estruturas são adequadas para permitir a execução repetida de um conjunto de diretivas por um número indeterminado de vezes, isto é, um número que não é conhecido durante a fase de programação mas que pode ser determinado durante a execução do programa tal como um valor a ser fornecido pelo usuário, obtido de um arquivo ou ainda de cálculos realizados com dados alimentados pelo usuário ou lido de arquivos. Existem duas estruturas de repetição condicionais: while e do while. O while é o que chamamos de laço condicional, isto é, um conjunto de instruções que é repetido enquanto o resultado de uma expressão lógica (uma condição) é avaliado como verdadeiro. Abaixo segue a sintaxe desta diretiva enquanto seu o comportamento é ilustrado a seguir.

1 while (expressão_lógica) 2 diretiva;

Código 14 - Exemplo de Sintaxe

Note que a diretiva while avalia o resultado da expressão antes de executar a diretiva associada, assim é possível que diretiva nunca seja executada caso a condição seja inicialmente falsa. Um problema típico relacionado a avaliação da condição da diretiva while é o seguinte: se a condição

Page 59: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 59

nunca se tornar falsa o laço será repetido indefinidamente.

Figura 87 - Comportamento da Diretiva while

O do while também é um laço condicional, isto é, tal como o while é um conjunto de instruções repetido enquanto o resultado da condição é avaliada como verdadeira mas, diferentemente do while, a diretiva associada é executada antes da avaliação da expressão lógica e assim temos que esta diretiva é executada pelo menos uma vez.

Seguem a sintaxe da diretiva do while e uma ilustração do seu comportamento.

do

diretiva

while (expressão_lógica);

Figura 88 - Comportamento da Diretiva do while

A seguir temos exemplos da aplicação destas duas diretivas de repetição.

1 package br.com.softpalm; 2 3 public class ExemploWhile { 4

Page 60: Apostila Android Gratuita

60 Desenvolvendo Aplicações com Java para Android

5 /** 6 * @param args 7 */ 8 public static void main(String[] args) { 9 int i = 0; 10 11 while (i < 100) { 12 System.out.println("Volta: " + i); 13 i++; 14 } 15 } 16 }

Código 15 – Código da classe ExemploWhile (Revisão SVN 6)

O exemplo acima ilustra o uso da diretiva while tal como um laço de repetição simples equivalente a uma diretiva for como abaixo:

1 for (int i =0; i < 100); i++) { 2 System.out.println("Volta: " + i); 3 }

Código 16 - Exemplo de Código

A seguir um exemplo da diretiva do...while.

1 //Veja no início do livro como obter os fontes 2 package br.com.softpalm; 3 /** 4 * Classe que demonstra o uso do FOR 5 * @author Wellington 6 * @version 1.0 7 */ 8 9 public class ExemploDoWhile { 10 11 public static void main(String[] args) 12 { 13 int i = 0; 14 15 do 16 { 17 System.out.println("Volta: " + i); 18 i++; 19 }while(i < 100); 20 21 } 22 }

Código 17 – Código ExemploDoWhile

Estruturas de controle de erros O Java oferece duas importantes estruturas para o controle de erros muito semelhantes as

estruturas existentes na linguagem C++: try catch e try finally. Ambas tem o propósito de evitar que o programador tenha que realizar testes de verificação e avaliação antes da realização de certas operações, desviando automaticamente o fluxo de execução para rotinas de tratamento de erro. Através destas diretivas, delimita-se um trecho de código que será monitorado automaticamente pelo sistema. A ocorrência de erros no Java é sinalizada através de exceções, isto é, objetos especiais que carregam informação sobre o tipo de erro detectado. Existem várias classes de exceção adequadas para o tratamento do problemas mais comuns em Java, usualmente inclusas nos respectivos pacotes. exceções especiais podem ser criadas em adição às existentes ampliando as possibilidades de

Page 61: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 61

tratamento de erro. Com o try catch a ocorrência de erros de um ou mais tipos dentro do trecho de código delimitado desvia a execução automaticamente para uma rotina designada para o tratamento específico deste erro.

A sintaxe do try catch é a seguinte:

try {

diretiva_normal;

} catch (exception1) {

diretiva_de_tratamento_de erro1;

} catch (exception2) {

diretiva_de_tratamento_de erro2;

}

O código a seguir possui uma ação muito perigosa, trabalhar com conexão a fonte de dados, diretórios, arquivos, dispositivos E/S são todas ações complicadas e com grande chance de exceptions.

1 try 2 { 3 File f = new File("/sdcard/GrupoAndroid/"); 4 f.mkdir(); 5 } 6 catch(Exception ex) 7 { 8 System.out.println(ex.getMessage()); 9 }

No código acima se ocorrer erro na ação mkdir() então a aplicação deve desviar a execução para o catch mais apropriado (no exemplo só temos 1) e executar o código de tratamento de erro, neste caso apenas estamos printando na saída o ocorrido.

Com o try finally temos um comportamento bastante diferente: uma rotina de finalização é sempre executada, isto é, o trecho particular de código contido na cláusula finally é sempre executado ocorrendo ou não erros dentro do trecho delimitado pela cláusula try.

A sintaxe do try finally é colocada a seguir:

try {

diretiva_normal;

} finally {

diretiva_de_tratamento_de erro;

}

Isto é particularmente interessante quando certos recursos do sistema ou estruturas de dados devem ser liberadas, independentemente de sua utilização.

1 //Veja no inicio do livro como obter os fontes 2 package livro.linguagem.erros; 3 4 //No pacote waba.io existe uma classe chamada Catalog 5 import waba.io.*; 6 7 /** 8 * Classe que demonstra um erro grave, pois o catalog deve ser fechado 9 */ 10 public class ExemploBerro extends waba.ui.MainWindow { 11 12 public ExemploBerro() {

Page 62: Apostila Android Gratuita

62 Desenvolvendo Aplicações com Java para Android

13 14 Catalog catalog = new Catalog("softpalm.com.br.ExemploBerro", 15 Catalog.CREATE_EMPTY); 16 //Se ocorrer erro dentro deste if o catalog não é fechado

corretamente 17 if (catalog.isOpen()) { 18 byte[] b = new byte[2]; 19 catalog.addRecord(2); 20 catalog.writeBytes(b, 0, b.length); 21 } 22 catalog.close(); 23 24 } 25 26 public void onStart() { 27 28 } 29 }

Código 18- Código da classe ExemploBerro

Na classe exposta na listagem acima (ver Código 18) estamos criando um objeto do tipo Catalog na linha 14. Se tudo estiver correto ele deve abrir o objeto e utilizar o método addRecord() conforme podemos ver na linha 19. Se algum erro ocorrer na linha 19 o objeto catalog não será fechado na linha 22.

1 //Veja no inicio do livro como obter os fontes 2 package livro.linguagem.erros; 3 4 //No pacote waba.io existe uma classe chamada Catalog 5 import waba.io.*; 6 7 /** 8 * Classe que demonstra o uso do finally para executar alguma ação 9 */ 10 public class ExemploBcorrecao extends waba.ui.MainWindow { 11 12 13 public ExemploBcorrecao() 14 { 15 16 try //Try 1 17 { 18 Catalog catalog = new

Catalog("softpalm.com.br.ExemploBerro",Catalog.CREATE_EMPTY); 19 try //Try 2 20 { 21 if(catalog.isOpen()) 22 { 23 byte[] b = new byte[2]; 24 catalog.addRecord(2); 25 catalog.writeBytes(b, 0, b.length); 26 } 27 } 28 catch(Exception ex) //Catch do Try 2 29 { 30 waba.sys.Vm.debug("Se ocorreu erro aqui,

devemos fechar o catalog pois ele se encontra aberto."); 31 } 32 finally // Finally do Try 2

Page 63: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 63

33 { 34 catalog.close(); 35 } 36 } 37 catch(Exception ex) //Catch do Try 1 38 { 39 waba.sys.Vm.debug("O catalog não foi aberto, então ele

não deve ser fechado."); 40 } 41 42 43 } 44 45 public void onStart() 46 { 47 48 } 49 }

Código 19 - Código da classe ExemploBcorreto

No código da classe ExemploBcorreto utilizamos uma seqüência de try...catch, em destaque o try..catch..finally, repare que se ocorrer erros entre a linha 21 e 26 o catalog tem total garantia que será fechado, pois quer ocorra erros ou não o bloco finally sempre será executado para o Try 2 (linhas 19 à 27). Utilizamos dois pois pode haver outro erro, o erro na linha 18 quando o catalog é criado, neste caso o catalog não precisa ser fechado pois nem foi aberto, se isso ocorrer será disparado o catch da linha 37.

Gerando suas Próprias Exceções O exemplo a seguir ensina como trabalhar com throw, a palavra chave usada para levantar

exceções. Este exemplo se baseia na classe ExemploAerro conforme descrito no Error! Reference source not found.. Nossa exceção será gerada quando nas operações de frações ocorrer uma divisão por zero.

Em Java, exceções são instâncias de classes que pertencem a hierarquia que é iniciada, encabeçada, pela classe Throwable. Neste exemplo construiremos nossa exceção herdando de Exception que por sua vez herda de Throwable.

1 //Veja no inicio do livro como obter os fontes 2 package livro.linguagem.erros; 3 4 /** 5 * Implementação de uma classe específica para 6 * manipular informaçõe de exception, poderiamos 7 * gravar no arquivo de Log este erro 8 * @author Wellington 9 * @version 1.0 10 */ 11 public class ExceptionDvZero extends Exception { 12 13 /** Mensagem de erro */ 14 private String mensagem = ""; 15 16 public ExceptionDvZero(String mensagem) 17 { 18 this.mensagem = mensagem; 19 }

Page 64: Apostila Android Gratuita

64 Desenvolvendo Aplicações com Java para Android

20 21 /** 22 * Encapsulamento da variável mensagem, neste caso 23 * esta variável é somente leitura 24 */ 25 public String getMessage() 26 { 27 return this.mensagem; 28 } 29 }

Código 20 – Classe ExceptionDvZero

Crie uma nova classe e escreva o seguinte código:

1 //Veja no inicio do livro como obter os fontes 2 package livro.linguagem.erros; 3 4 /** 5 * Classe que demonstra o uso de Throws para tratar exceções 6 * @author Wellington 7 * @version 1.0 8 */ 9 public class ExemploAcorrecao2 extends waba.ui.MainWindow { 10 11 public ExemploAcorrecao2() 12 { 13 int x = 0; 14 int y = 10; 15 16 try 17 { 18 int valor = dividir(x,y); 19 waba.sys.Vm.debug("Valor: " + valor); 20 } 21 catch(Exception ex) 22 { 23 waba.sys.Vm.debug("Erro: " + ex.getMessage()); 24 } 25 } 26 27 /** 28 * Método que recebe dois inteiros, se o divisor vor = a zero 29 * ele libera uma exceção e não executa a divisão 30 * @param x Divisor 31 * @param y Dividendo 32 * @return Se não ocorrer erro um número inteiro resultada o da divisão 33 * @throws ExceptionDvZero Erro se divisor é = a zero 34 */ 35 public int dividir(int x, int y) throws ExceptionDvZero 36 { 37 if(x == 0) 38 { 39 throw new ExceptionDvZero("A variável X não pode conter

um valor 0"); 40 } 41 return y/x; 42 }

Page 65: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 65

43 44 }

Código 21 – Código da classe ExemploAcorrecao2

Outro fato importante é que um bloco catch também pode gerar exceções, assim se você pegou uma exceção e resolveu que não consegue tratá-la você pode fazer um throw dela mesma ou mudar a classe da exceção e continuar propagando (throw de outra exceção), ou fazer o que você pode para reparar o erro e jogar uma exceção para que o que você fez seja completado por outros métodos. Lembre-se que se você pegou uma exceção, ela para de propagar.

Figura 89 - Execução da classe ExemploAcorrecao2

Page 66: Apostila Android Gratuita

66 Desenvolvendo Aplicações com Java para Android

66 5 Programação Orientada a Objetos

Objetivo Deste Apêndice • Endender os princípios da Programação Orientada a Objetos;

• Conhecer as estruturas Java.

Introdução Sabemos que na programação temos variáveis, até o momento estudamos as primitivas porem já

servem de base para nosso estudo de Programação Orientada a Objetos (POO).

Quando criamos uma variável primitiva, tal como o int estamos reservando na memória um determinado espaço, a quantidade de bits e como estes bits são iniciados por padrão estão definidos no tipo da variável, que neste caso é inteiro.

Digamos que eu queira construir o meu tipo, e ainda queira que este tipo seja composto por outros tipos. E se esse meu tipo além das propriedades (valores que podem ser armazenados) eu queira definir comportamentos. Em POO eu posso construir os meus tipos de acordo com minhas necessidades e a partir destes tipos criar objetos complexos (contraste com variáveis primitivas).

Preciso então criar antes de tudo um molde, este molde é a especificação para os objetos, algo mais ou menos como no tipo int no qual contém o molde para as variáveis declaradas como inteiros.

Esse molde será chamado de classe. Como uma classe pode ser composta de outros tipos internos vamos dizer que estes tipos são os “atributos” da classe e se pode ter comportamento podemos dizer que temos “métodos”.

Atenção: Repare que comportamento é ação, logo possui bloco de código. Em muitas linguagens estes métodos são chamados de funções.

Exemplo:

Um programa que utiliza uma interface controladora de um motor elétrico provavelmente definiria a classe motor. Os atributos desta classe seriam: temperatura, velocidade, tensão aplicada. Estes provavelmente seriam representados na classe por tipos como int ou float. Os métodos desta classe seriam funções para alterar a velocidade, ler a temperatura, etc.

Exemplo:

Um programa editor de textos definiria a classe parágrafo que teria como um de seus atributos uma String ou um vetor de Strings, e como métodos, funções que operam sobre estas strings (corretor ortográfico, formatador de texto). Quando um novo parágrafo é digitado no texto, o editor cria a partir da classe Paragrafo.java um objeto contendo as informações particulares do novo texto. Isto se

Page 67: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 67

chama instanciação ou criação do objeto.

Especificando uma Classe Suponha um programa que controla um motor elétrico através de uma saída serial. A velocidade do

motor é proporcional a tensão aplicada e esta proporcional aos bits que vão para saída serial e passam por um conversor digital analógico.

Vamos abstrair todos estes detalhes por enquanto e modelar somente a interface do motor como uma classe, a pergunta é que métodos e que atributos deve ter nossa classe, que argumentos e valores de retorno devem ter os métodos?

Representação da velocidade

A velocidade do motor será representada por um atributo inteiro (int). Usaremos a faixa de bits que precisarmos, caso o valor de bits necessário não possa ser fornecido pelo tipo, usaremos então o tipo long, isto depende do conversor digital analógico utilizado.

Representação da saída serial

O motor precisa conhecer a sua saída serial, a sua ligação com o “motor do mundo real”. Suponha uma representação em hexadecimal do atributo endereço de porta serial, um possível nome para o atributo: enderecomotor. Não se preocupe em saber como usar a representação hexadecimal.

Alteração do valor da velocidade

Internamente o usuário da classe motor pode desejar alterar a velocidade, cria-se então o método: public void altera_velocidade(int novav);. O código anterior corresponde ao cabeçalho do método ele é definido junto com a classe motor, associado a ela. O valor de retorno da função que “implementa” o método é void, poderia ser criado um valor de retorno (boolean) que indicasse se o valor de velocidade era permitido e foi alterado ou não era permitido e, portanto não foi alterado.

O ato de invocar um método também é chamado de “mensagem”, então quando passamos uma mensagem para o objeto que está executando este método estamos invocando sua funcionalidade através do método.

Não faz sentido usar ou chamar este método separado de uma variável do tipo motor, mas então porque na lista de argumentos da função não se encontra um motor? Este pensamento reflete a maneira de associar dados e código (funções) das linguagens procedurais.

Em linguagens orientadas a objetos o código e os dados são ligados de forma diferente, a própria declaração de um tipo definido pelo usuário já engloba as declarações das funções inerentes a este tipo.

Note que não fornecemos o código do método neste pondo de nosso estudo, isto não é importante por hora, a preocupação é com a interface definida pela classe: seus cabeçalhos de métodos e atributos. Apenas pense que sua interface deve ser flexível de modo a não apresentar entraves para a criação do código que seria feita numa outra etapa. Nesta etapa teríamos que imaginar que o valor numérico da velocidade deve ir para o conversor aonde irá se transformar numa diferença de potencial a ser aplicada nos terminais do motor, etc.

Figura 90 - Classe representada na UML

Implementando código descrito na listagem abaixo (ver Código 22 - Código da Classe Motor v.: 1.0).

1 package br.com.softpalm.poo; 2

Page 68: Apostila Android Gratuita

68 Desenvolvendo Aplicações com Java para Android

3 // A linha abaixo representa a declaração de uma classe 4 public class Motor { 5 6 // Duas variáveis primitivas são criadas dentro da nossa classe 7 // repare que a classe se torna um tipo composto de outros tipos 8 // chamamos estas variáveis de atributos da classe 9 public int velocidade; 10 public int endereco; 11 12 // A estrutura abaixo é um método ou seja, uma funcionalidade 13 repare que o método acessa o atributo velocidade usando o operador 14 this, não precisa se preocupar com este operador que será estudado 15 public void altera_velocidade(int novav) 16 { 17 this.velocidade = novav; 18 } 19 20 // Fechar a classe 21 }

Código 22 - Código da Classe Motor v.: 1.0

Objetos

Objetos são instâncias de uma classe. Quando um objeto é criado ele precisa ser inicializado, ou seja, para uma única classe de nome Motor podemos ter vários objetos durante a execução de um programa.

1 // Exemplo de dois objetos (m1 e m2) sendo instanciados a partir da nossa

2 classe Motor 3 Motor m1 = new Motor(); 4 Motor m2 = new Motor();

Código 23 - Exemplo de objetos

Objetos podem conter objetos, ou seja, os atributos de um objeto podem ser objetos, da mesma classe ou não. Objetos podem ser passados pela rede, armazenados em meio físico. Objetos possuem um estado e um comportamento. Métodos podem receber objetos como argumentos, podem declarar objetos como variáveis locais, podem chamar outros métodos. Você pode chamar um método (mandar uma mensagem) para objetos em outras máquinas através de sua rede.

Um objeto pode ser visto como um RECORD, só que com uma tabela de funções que podem ser chamadas para ele. Na verdade esta definição não é muito teórica, mas é um bom começo para os programadores que estão acostumados com linguagens procedurais. Na verdade podemos fazer com objetos muito mais do que fazemos com records e procedimentos em Pascal.

Atributos A classe círculo é especificada em um arquivo separado do arquivo da classe que contém o método

onStart().

É importante entender este exemplo, quando você estudar interfaces gráficas, poderá usar a classe círculo pré-definida na linguagem para desenhar círculos que se movem na tela. Embora não tenhamos explicado com detalhes os tipos básicos da linguagem, usaremos neste exemplo o tipo float (real), e nas explicações o tipo String e o tipo int (inteiro). No final deste tópico forneceremos uma explicação detalhada sobre tipos.

1 package br.com.softpalm.geometria; 2 3 /**

Page 69: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 69

4 * Classe que descreve uma circunferência 5 * @author Wellington 6 * @version 1.0 7 */ 8 public class Circulo { 9 10 // Atributo RAIO da circunferência 11 public float raio; 12 // Coordenada do ponto central da circunferência 13 public float x; 14 public float y; 15 16 }

Código 24 - Código da classe Circulo

Agora vamos utilizar a classe Circulo para gerar objetos.

1 package br.com.softpalm.geometria; 2 3 /** 4 * Classe que utiliza a classe Circulo 5 * @author Wellington 6 * @version 1.0 7 */ 8 public class UsaCirculo { 9 public static void main(String[] args) { 10 11 Circulo umcirc; // declaracao de uma variavel circulo no metodo

main. 12 umcirc = new Circulo(); // alocacao dessa variavel 13 System.out.println("(" + umcirc.x + "," + umcirc.y + "," +

umcirc.raio 14 + ")"); 15 umcirc.x = umcirc.x + 17; 16 System.out.println("(" + umcirc.x + "," + umcirc.y + "," +

umcirc.raio 17 + ")"); 18 19 } 20 21 }

Código 25 – Código da classe livro.poo.geometria.UsaCirculo

Então usamos o perador new para criar as instancias dos objetos, não adianta apenas delcarar conforme foi feito na linha 11, temos que instanciar também (ver linha 12).

Depois do objeto instanciado podemos utilizar os atributos.

Coleta automática de lixo A limpeza do objeto é feita pela linguagem Java e chamamos de “automatic garbage collection”,

você não precisa se preocupar com ela. Após a execução do método main, a memória do objeto umcirc já pode ser liberada, o que normalmente não ocorre de imediato, pois o ambiente da linguagem executa um “tread” em baixa prioridade que libera de tempos em tempos os espaços inutilizados de memória, tirando proveito, por exemplo, de eventuais pausas de iteração do usuário com o programa. Por executar em um “tread” entenda paralelamente ou quase paralelamente, voltaremos a este tópico mais adiante.

Page 70: Apostila Android Gratuita

70 Desenvolvendo Aplicações com Java para Android

Acesso aos atributos e métodos e alterações dos atributos O acesso aos atributos da variável (objeto) umcirc deve ser feito usando o nome do objeto e o nome

do atributo deste, separados por um ponto: umcirc.raio = 10.0; . Note que raio sozinho não faz sentido no programa, precisa-se especificar de que objeto se deseja alterar ou obter o raio.

A sintaxe de chamadas de métodos é semelhante à sintaxe descrita acima usada para atributos, só que ao invés de nome do atributo temos o nome do método seguido dos parênteses que podem conter zero ou mais argumentos. Volte ao primeiro programa (HelloWorld) e verifique a declaração do método onCreate().

Métodos Os métodos determinam o comportamento dos objetos de uma classe. Quando um método é

invocado, se diz que o objeto está recebendo uma mensagem (para executar uma ação). Programas complexos formam conjuntos de objetos que trocam mensagens entre si gerenciando inclusive os recursos do sistema.

Sintaxe de declaração de métodos A sintaxe simplificada para a declaração de métodos de uma classe é:

especificador_de_acesso tipo_de_retorno nome_do_metodo ( lista_de_argumentos )

{

/*codigo */

}

O programa a seguir exemplifica chamadas de métodos, para tal define um objeto que serve como contador, a implementação representa a contagem no atributo num que é um número inteiro. Os métodos são simples:

+ incrementa(): Incrementa a variável interna em + uma unidade;

+ decrementa(): Decrementa a variável interna em – uma unidade;

+ getNum(): Retorna o valor da variável interna, esta variável segue os conceitos de encapsulamento;

+ Contador(): Construtor da classe.

1 //Veja no inicio do livro como obter os fontes 2 package br.com.softpalm.poo; 3 4 /** 5 * Classe que implementa mecanismos de um contador 6 * @author Wellington 7 * @version 1.0 8 */ 9 public class Contador { 10 11 /** Atributo que armazena o valor do contador */ 12 private int num = 0; 13 14 /** 15 * Método que incrementa o atributo em +1 16 */ 17 public void incrementa() 18 { 19 num++; 20 } 21 /**

Page 71: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 71

22 * Método que decrementa um atributo em -1 23 */ 24 public void decrementa() 25 { 26 num--; 27 } 28 29 /** 30 * Método que prove o encapsulamento da variável num, afinal 31 * esta variável não pode ser alterada por outro objeto. 32 * @return Valor do contador 33 */ 34 public int getNum() 35 { 36 return this.num; 37 } 38 }

Código 26 – Código da classe Contador

Esta classe foi construída somente para armazenar valores de contadores, este valor é armazenado em uma variável interna que não pode ser alterada diretamente pela classe que utiliza um objeto de sua instancia.

Abaixo desenvolvemos uma classe que utiliza os serviços disponibilizados pela classe Contador.

1 //Veja no inicio do livro como obter os fontes 2 package br.com.softpalm.poo; 3 4 /** 5 * Classe que demonstra o uso da classe Contador 6 * @author Wellington 7 * @version 1.0 8 */ 9 public class UsaContador { 10 11 Public static void main(String[] args) 12 { 13 Contador cont = new Contador(); 14 15 //Contador com valor padrão 16 System.out.println ("Antes de incrementar: " + cont.getNum()); 17 18 //Incrementando 19 cont.incrementa(); 20 21 //Contador incrementado 22 System.out.println ("Depois de incrementar: " + cont.getNum()); 23 } 24 25 }

Código 27 – Código da classe UsaContador

Quando a classe acima é executada, inicia-se criando um objeto a partir da classe Contador(). Na linha 16 estamos imprimindo na tela o valor inicial do objeto. Na linha 19 estamos incrementando este valor para imprimir novamente na linha 22. Na figura abaixo temos um Print-Screen que demonstra a execução desta classe.

Page 72: Apostila Android Gratuita

72 Desenvolvendo Aplicações com Java para Android

Figura 91 - Executando o Código 27

this O operador this é uma palavra chave usada em um método como referência para atributos e

métodos do próprio objeto corrente, ela tem o significado de: “o método/atributo que estou chamando está no escopo de eu mesmo”.

Suponha uma classe (ver Figura 92) que possui a seguinte declaração de atributo: private String nome = “”, esta variável é publica somente dentro da classe, logo pode ser acessada normalmente. Agora deve-se escrever um método que tem a finalidade de prover a alteração desta variável pelo meio externo, isso é feito na linha 6, repare que na linha 6 declaramos uma nova variável com o mesmo nome da variável declarada na linha 4. Porem na linha 8 estamos dizendo que a variável marcada pelo this refere-se a variável criada na linha 4 e a variável (linha 8) sem o this refere-se a variável criada na linha 6.

A variável criada na linha 4 dizemos que tem o escopo da classe, pois pode ser visualizada em toda a classe, já a variável criada na linha 6 possui apenas o escopo do método em que é criada.

Figura 92 - Uma classe qualquer

Atenção: É uma boa prática o uso do this, mesmo que a ocorrência do nome da varável que está usando somente aparece no escopo da classe.

Sintaxe de chamada ou acesso a métodos A sintaxe de chamada ou acesso à métodos é semelhante a sintaxe de acesso aos atributos, com

exceção dos parênteses que contém a lista de argumentos da função que implementa o método, mesmo que a lista seja vazia eles devem estar presentes: umcontador.incrementa();. Primeiro insere-se o nome do objeto e depois a chamada da função, estes são separados por um ponto. Cuidado para não esquecer os parênteses em programas futuros, este é um erro bastante comum.

Nova versão do programa Circulo Agora reapresentaremos o programa Circulo baseado no exemplo 0, porém um pouco mais

complicado: Método move O método move altera as coordenadas do objeto. O objeto tem suas coordenadas x e y somadas

com os argumentos dessa função. Note que este método representa uma maneira mais segura, clara, elegante de alterar as coordenadas do objeto do que acessá-las diretamente da seguinte forma: ac.x+=dx;. ac.y+=dy;. Lembre-se que ac.x+=dx é uma abreviação para ac.x=ac.x+dx;.

Método mostra

Page 73: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 73

O método mostra imprime na tela, de forma compacta, os atributos do objeto.

1 //Veja no inicio do livro como obter os fontes 2 package br.com.softpalm.geometria; 3 4 /** 5 * Classe que descreve uma circunferência 6 * 7 * @author Wellington 8 * @version 2.0 9 */ 10 public class CirculoV2 { 11 /** atributo raio do circulo */ 12 public float raio; 13 /** Posição X, coordenada cartesiana */ 14 public float x; 15 /** Posição Y, coordenada cartesiana */ 16 public float y; 17 18 /** 19 * Movimenta um circulo 20 * @param dx incremento na posição X 21 * @param dy incremento na posição Y 22 */ 23 public void move(float dx, float dy) 24 { 25 this.x += dx; 26 y += dy; 27 } 28 29 /** 30 * Imprime as informações do objeto 31 */ 32 public void mostra() 33 { 34 System.out.println ("(" + x + "," + y + "," + raio + ")"); 35 } 36 37 }

Código 28 - Código da classe CirculoV2

A classe abaixo foi construída somente para manipular objetos criados a partir da classe CirculoV2.

1 //Veja no inicio do livro como obter os fontes 2 package br.com.softpalm.geometria; 3 4 /** 5 * Classe que utiliza a classe CirculoV2 6 * 7 * @author Wellington 8 * @version 2.0 9 */ 10 public class UsaCirculoV2 { 11 public static void main(String[] args) { 12 CirculoV2 umcirc; 13 // declaracao de atributo circulo 14 umcirc = new CirculoV2(); 15 umcirc.x = 0;

Page 74: Apostila Android Gratuita

74 Desenvolvendo Aplicações com Java para Android

16 umcirc.y = 0; 17 umcirc.raio = 12; 18 umcirc.mostra(); 19 umcirc.move(10, 10); 20 umcirc.mostra(); 21 umcirc.x = 100; 22 umcirc.mostra(); 23 24 } 25 26 }

Código 29 - Código da nova versão do UsaCirculo

A execução do código acima pode ser visto na figura abaixo.

Figura 93 - Execução da classe UsaCirculoV2

Construtores Construtores são métodos especiais chamados pelo sistema no momento da criação de um objeto.

Eles não possuem valor de retorno, porque você não pode chamar um construtor para um objeto, você só usa o construtor no momento da inicialização do objeto. Construtores representam uma oportunidade de inicializar seus dados de forma organizada, imagine se você esquece de inicializar corretamente ou o faz duas vezes, etc.

Um construtor tem sempre o mesmo nome da classe a qual pertence. Para a classe String, pré-definida na linguagem o construtor tem a forma String(“Constante do tipo String”); com o argumento entre aspas que é especificado pelo programador. Ele seria chamado automaticamente no momento da criação, declaração de uma String, sem necessidade de uso do nome do construtor como método, apenas dos argumentos:

1 String str; 2 str = new String("softpalm.com.br"); //Construtor String(String texto) 3 System.out.println(str.length());

Nos exemplos anteriores também usávamos construtores no momento de inicializar nossos objetos, só que eles não possuíam argumentos, por isso estavam implícitos.

Existem variações sobre o tema que veremos mais tarde: sobrecarga de construtor, “copy constructor”, construtor de corpo vazio. O exemplo a seguir é simples, semelhante aos anteriores, preste atenção no método com o mesmo nome que a classe, este é o construtor:

1 //Veja no inicio do livro como obter os fontes 2 package br.com.softpalm.geometria; 3 4 /** 5 * Classe Ponto 6 * @author Wellington 7 * @version 1.0

Page 75: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 75

8 */ 9 public class Ponto { 10 /** Variáveis que armazenam a posição no plano */ 11 private float x, y; 12 13 /** 14 * Construtor da classe 15 * @param x Novo valor para X 16 * @param y Novo valor para Y 17 */ 18 public Ponto(float x, float y) 19 { 20 this.x = x; 21 this.y = y; 22 } 23 24 /** 25 * Movimenta um ponto no plano 26 * @param dx Incremento X 27 * @param dy Incremento Y 28 */ 29 public void move(float dx, float dy) { 30 this.x += dx; 31 this.y += dy; 32 } 33 34 /** 35 * Escreve os valores X e Y 36 */ 37 public void mostra() { 38 System.out.println("(" + this.x + "," + this.y + ")"); 39 } 40 41 }

Código 30 - Código da classe Ponto

Agora vamos desenvolver a classe que utiliza o Ponto, crie uma nova classe chamada UsaPonto e escreva o seguinte código:

1 //Veja no inicio do livro como obter os fontes 2 package br.com.softpalm.geometria; 3 4 /** 5 * Classe que demonstra o uso do Ponto 6 * @author Wellington 7 * @version 1.0 8 */ 9 public class UsaPonto { 10 11 public UsaPonto() { 12 Ponto ap; 13 ap = new Ponto((float) 0.0, (float) 0.0); 14 ap.mostra(); 15 ap.move(1, 1); 16 ap.mostra(); 17 18 } 19 public static void main(String[] args) 20 {

Page 76: Apostila Android Gratuita

76 Desenvolvendo Aplicações com Java para Android

21 UsaPonto usar = new UsaPonto(); 22 } 23 }

Código 31 - Código da classe UsaPonto

Quando esta classe é executada, o construtor é automaticamente invocado (dentro do código main). Neste construtor temos um objeto chamado ap, este objeto recebe em seu construtor dois valores que serão armazenados, em seguida podemos utilizar este objeto para exibir valores ou até alterar estes valores. Veja na figura abaixo o resultado da execução da classe.

Figura 94 - Resultado da execução da classe UsaSPonto

Destrutores Ou “finalizers” A presença de coleta automática de lixo torna o conceito de destrutores um pouco diferente de seus

equivalentes em outras linguagens orientadas a objetos. Em Java destrutores são métodos chamados pelo sistema quando a memória de um objeto está para ser liberada pelo coletor automático de lixo (não quando está para ser coletada).

A sintaxe dos destrutores é a seguinte:

protected void finalize() {

//codigo para arrumar a casa, antes que o objeto seja apagado

}

Note que o que caracteriza o construtor é ter o mesmo nome da classe, já o destrutor é caracterizado por possuir o nome finalize. Você pode chamar o destrutor, mas isso não implica que o objeto será deletado. Ao contrário dos construtores, os destrutores não tem argumentos, mas possuem valor de retorno que é igual a void.

Os destrutores são muito úteis para “limpar a casa” quando um objeto deixa de ser usado. Um exemplo bastante comum do uso de destrutores é o de um objeto que lida com arquivos que devem ser fechados quando o objeto for destruído (ver Código 19). Existem outros casos onde um objeto deve comunicar aos outros objetos que será inutilizado, destruído, ou seja: sairá do programa conforme figura abaixo.

Figura 95 - Exemplo de processamento com finalizador

Em Java, que possui coleta automática de lixo, um objeto passa a não existir mais no programa quando nenhuma variável faz referência a ele. Nesse ponto, ele é armazenado no coletor automático de lixo, onde receberá o tratamento adequado. Um nó de uma lista ligada pode ser apagado simplesmente fazendo o nó anterior apontar para o posterior a ele. Os programadores não acostumados com esse conceito precisam ouvir a seguinte frase: “Você não é obrigado a liberar explicitamente a memória de um objeto como é feito em C++ e outras linguagens”.

Se estivéssemos, por exemplo, em C++ que não possui coleta automática de lixo, o destrutor seria chamado sempre que a memória de um objeto fosse desalojada, o que é feito pelo programador através de uma chamada a delete nomedoobjeto(); .

Em Java a liberação de memória que é feita pelo coletor automático de lixo que é executado de

Page 77: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 77

modo assíncrono com o restante do programa, ou seja, você não pode contar com o fato de que o destrutor será chamado imediatamente após o momento em que seu objeto sai de escopo, a não ser que o programa seja executado com o modo assíncrono do coletor automático de lixo desligado (java -noasyncgc NomePrograma).

Ponteiros, Referências e Objetos Alguém pode ter achado estranho que não foram discutidos ponteiros em Java, ocorre que eles não

existem nessa linguagem. Existem estudos que afirmam que erros com ponteiros são um dos principais geradores de “bugs” em programas, além disso com todos os recursos que temos não precisaremos deles.

Os programadores acostumados ao uso de ponteiros (e aos erros decorrentes desse uso) acharão natural e segura a transição para Java onde passarão a usar principalmente vetores e classes. A estruturação de seu código deverá agora ser feita em um modelo que se baseia no uso de objetos (vetores e Strings também são objetos). Objetos superam a representatividade obtida com records, funções isoladas e ponteiros.

De certo modo você estará usando referências, mas de forma implícita. Por exemplo: objetos são alocados dinamicamente com new, eles são referências ou ponteiros para posições na memória, mas a linguagem mascara este fato por razões de segurança. Como objetos são ponteiros (só que transparentes para você), nos depararemos com o problema de reference aliasing quando discutirmos cópia de objetos com outros objetos como atributos.

Passagem por Referência Linguagens como Pascal ou C criam meios de passar parâmetros por valor ou por referência. Como

Java não possui ponteiros, a passagem por referência deve ser feita através de objetos. Se o parâmetro já é um objeto, então a passagem dele é obrigatoriamente por referência.

No caso de tipos simples, podemos passá-los dentro de vetores que são objetos, ou então criar classes para embalar, empacotar estes tipos. Dada a necessidade destas classes, elas já foram definidas na linguagem. São classes definidas para conter cada tipo básicos e permitir certas conversões entre eles, falaremos destas classes conforme necessitarmos de seu uso. As vezes estas classes são chamadas de “wrappers”.

Vetores e Matrizes Vetores são objetos, eles possuem papel importante no estilo de programação desta linguagem que

exclui ponteiros. Por serem objetos, vetores são obrigatoriamente alocados de maneira dinâmica. O exemplo a seguir aloca um vetor de inteiros com três posições, seguindo uma sintaxe semelhante a de alocação de objetos:

1 //Veja no inicio do livro como obter os fontes 2 package br.com.softpalm.vetores; 3 4 /** 5 * Classe que demonstra o uso simples de um vetor 6 * 7 * @author Wellington 8 * @version 1.0 9 */ 10 public class SimplesVetor{ 11 12 public static void main(String[] args) { 13 int vetor[] = new int[5]; 14 vetor[0] = 0; 15 vetor[1] = 10; 16 vetor[2] = 20; 17 vetor[3] = 90; 18 vetor[4] = 100; 19

Page 78: Apostila Android Gratuita

78 Desenvolvendo Aplicações com Java para Android

20 for(int i = 0; i < vetor.length; i++) 21 { 22 System.out.println("I: " + i + " Valor: " + vetor[i] ); 23 } 24 } 25 26 }

Código 32 - Código da classe SimplesVetor

No código acima, estamos criando na linha 13 um simples vetor de 5 posições, na linha 14 inserimos o valor zero na primeira posição do vetor. Em Java vetor inicia-se na posição 0.

Na linha 20 estamos realizando um laço for para imprimir os valores armazenados no vetor. Abaixo temo uma imagem que ilustra esta ação.

Figura 96 - Execução da classe SimplesVetor

Encapsulamento Encapsulamento, “data hiding” é um conceito importante em orientação a objetos. Neste tópico

vamos falar das maneiras de restringir o acesso as declarações de uma classe e a própria classe, isto é feito através do uso das palavras reservadas conhecidas como modificador de acesso (public, private e protected) que são qualificadores (ver Figura 92).

Alguém pode estar se perguntando o porquê de se restringir o acesso a certas partes de uma classe. A idéia é simples, devemos fornecer ao usuário, cliente de uma classe, o necessário e somente o necessário para que ele tire proveito da funcionalidade desta classe. Os detalhes devem ser omitidos, somente a lista de operações a qual uma classe deve atender fica visível.

Os benefícios são muitos: clareza do código, minimização de erros, facilidade de extensão. Talvez a facilidade de modificação seja o mais importante dos benefícios. Como a classe é conhecida pela sua interface, é muito fácil mudar a representação interna sem que o cliente, usuário, perceba a diferença Estaremos preocupados em separar design de implementação, Java é uma linguagem boa de programar em termos de design e em termos de implementação.

Programar tendo em vista o design é também chamado de “programming in the large”, enquanto que programar tendo em vista implementação, codificação é chamado de “programming in the small”. Alguns programadores experientes afirmam que Java se parece com C quando estamos preocupados com codificação, mas quando estamos preocupados com design, Java se assemelha a Smalltalk.

Com encapsulamento você será capaz de criar componentes de software reutilizáveis, seguros, fáceis de modificar.

Encapsulando Métodos e Atributos Até agora não nos preocupávamos com o modo de acesso de declarações de uma classe, pois,

mesmo sem saber o porquê você foi avisado para qualificar todos os atributos e métodos de suas classes como public o que significa que eles são acessíveis, visíveis, em qualquer local de seu código. Por visível entenda o seguinte: se o atributo x do objeto UmPonto não é visível por exemplo fora de sua classe, então não faz sentido escrever em main: UmPonto.x=0; .

Mas então como controlar o acesso de atributos e métodos em uma classe? Simples, através das palavras reservadas private, public e protected cujos significados quando qualificando métodos e

Page 79: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 79

atributos (private e public podem também qualificar classes) são descritos abaixo:

public

Estes atributos e métodos são sempre acessíveis em todos os métodos de todas as classes. Este é o nível menos rígido de encapsulamento, que equivale a não encapsular.

private

Estes atributos e métodos são acessíveis somente nos métodos(todos) da própria classe. Este é o nível mais rígido de encapsulamento.

protected

Estes atributos e métodos são acessíveis nos métodos da própria classe e suas subclasses, o que será visto em Herança 0.

Nada especificado equivale a “package”

ou “friendly”

Estes atributos e métodos são acessíveis somente nos métodos das classes que pertencem ao “package” em que foram criados. Este modo de acesso é também chamado de “friendly”.

(existem outros qualificadores, não relacionados com encapsulamento que serão explicados depois)

Protected será explicado no tópico ”Herança”, pois este não terá grande utilidade neste momento, por hora vamos focalizar nossa atenção em private e public que qualificam os atributos e métodos de uma classe quanto ao tipo de acesso (onde eles são visíveis). Public, private e protected podem ser vistos como qualificadores ou “specifiers”.

Fica fácil entender essas declarações se você pensar no seguinte: esses qualificadores se aplicam aos métodos e atributos que vem imediatamente após eles. Agora vamos entender o que é private e o que é public. Vamos supor que você instanciou (criou) um objeto do tipo Ponto em seu programa:

Ponto meu; //Declaração da variável

meu=new Ponto();//gerando a instancia

No exemplo Código 30 - Código da classe Ponto vimos a maneira correta de se utilizar o encapsulamento, veja que é impossível acessar a variável conforme o código abaixo:

meu.x=(float)5.0; //Não dá para executar, x é privado

Você pode escrever: meu.move(5.0,5.0); porque sua declaração (move) está como public na classe, em qualquer lugar se pode escrever meu.move(5.0,5.0);.

Quando Utilizar Encapsulamento? Em muitos livros você vai encontrar “Use encapsulamento sempre...”, em outros o leitor encontra

uma lambança de código terrível, fica a pergunta: Quando utilizar o encapsulamento?

O programador deve ter bom censo, visto que estamos trabalhando com dispositivos de baixo recurso, eu particularmente utilizo a seguinte regra:

Uma regra de negócio: Alguma regra que não permite a entrada de qualquer valor, exemplo idade de uma pessoa, esta variável não pode ser negativa;

Quando a variável somente Leitura ou somente Escrita: Em alguns casos o valor da variável não pode ser alterado, imagine o atributo razao na classe Cliente, em algumas forças de vendas este atributo não pode ser alterado, ele está somente para leitura.

Se a sua variável se enquadra em alguma destas cláusulas então se deve utilizar o conceito de encapsulamento.

Herança Neste tópico apresentaremos o conceito de herança, fundamental para programação orientada a

objetos e um dos fatores de sucesso desta como muito mais que uma simples maneira de organizar melhor seu código.

Um dos aspectos que distinguem objetos de procedimentos e funções é que o tempo de existência

Page 80: Apostila Android Gratuita

80 Desenvolvendo Aplicações com Java para Android

de um objeto pode ser maior do que o do objeto que o criou. Isto permite que em sistemas distribuídos objetos criados em um local, sejam passados através da rede para outro local e armazenados lá quem sabe na memória ou mesmo em um banco de dados.

Hierarquia de Tipos Neste tópico mostraremos como construir hierarquias de tipo por generalização/especialização.

Para entender o que é generalização especialização e as regras de atribuição entre elementos dessas hierarquias, acompanhe a seguinte comparação:

Se você vai a um restaurante e pede o prato de frutos do mar, é natural que você aceite uma lagosta com catupiry, ou então filé de badejo. Mas se o garçom lhe serve uma salada de tomates isto não se encaixa no pedido. Por outro lado, se o seu pedido for peixe, uma lagosta com catupiry, embora muito saborosa não serve mais, assim como a salada. Note que peixe e lagosta são especializações de frutos do mar.

Generalização e Especialização são ferramentas para lidar com complexidade, elas são abstrações. Os sistemas do mundo real apresentam complexidade muito maior que ordenar um prato listado em um cardápio. O uso de generalização e especialização permite controlar a quantidade de detalhes presente nos seus modelos do mundo real, permite capturar as características essenciais dos objetos e tratar os detalhes de forma muito mais organizada e gradual.

Existe muito mais para falar sobre herança, principalmente no que diz respeito a polimorfismo de inclusão e acoplamento dinâmico de mensagens, tópicos estes que serão abordados em separado.

Uma Hierarquia Simples Construiremos uma hierarquia de tipos simples para demonstrar herança pública em Java. Vamos

antes entender o modelo (trecho de um diagrama de classe) da UML.

Figura 97 - Diagrama de Classes

O diagrama acima representa a hierarquia de classes, neste exemplo e foi obtido a partir da janela de edição de uma ferramenta case para programação orientada a objetos.

A classe ponto que está no topo da hierarquia é chamada de classe base, enquanto que as classes ponto_reflete e ponto_move são chamadas classes filhas ou herdeiras. As classes da hierarquia são simples, ponto_move apresenta o método move, já abordado neste material, ponto_reflete apresenta o método (reflete) que inverte o sinal das coordenadas.

Dada a simplicidade das classes o leitor poderia se perguntar, porque não juntar as três em uma só. A pergunta faz sentido, mas e se quiséssemos criar uma classe Ponto que não se movesse, apenas refletisse e outra que só se movesse? E se quiséssemos projetar nosso programa segundo uma hierarquia de especialização/generalização da classe Ponto? O exemplo mostra como fazê-lo.

Na herança as classes filhas passam a atender métodos e atributos public e protected da classe pai (base), as classes filhas podem acrescentar métodos, atributos e até redefinir métodos herdados (veremos mais tarde). Por isso é que se diz que as classes subclasses garantem pelo menos o comportamento “behaviour” das superclasses, podendo acrescentar mais características. Os atributos encapsulados (private) da classe pai não são acessíveis diretamente na classe filha a não ser que sejam qualificados como protected ou public.

Page 81: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 81

Construtores e herança No construtor de uma classe filha o programador pode incluir a chamada do construtor da classe pai

existente nela. Para referenciar a classe pai use a “keyword” super de modo análogo a this (objeto corrente).

1 //Veja no inicio do livro como obter os fontes 2 package br.com.softpalm.heranca; 3 4 /** 5 * Classe Area é capaz de armazenar valores de base e altura 6 * de qualquer coisa que tenha uma medida real não negativa 7 * @author Wellington 8 * @version 1.0 9 */ 10 public class Area { 11 12 /** Base da area */ 13 private int base = 0; 14 /** Altura da area */ 15 private int altura = 0; 16 17 /** 18 * Construtor da area 19 * @param base A area não pode ter uma base negativa 20 * @param altura A area não pode ter uma latura negativa 21 * @throws Exception Erros 22 */ 23 public Area(int base, int altura) throws Exception 24 { 25 if(base < 0 || altura < 0) 26 throw new Exception("Valores negativos."); 27 this.base = base; 28 this.altura = altura; 29 } 30 31 //Usando a teoria de encapsulamento 32 public int getBase() 33 { 34 return this.base; 35 } 36 public int getAltura() 37 { 38 return this.altura; 39 } 40 41 public void setBase(int base) throws Exception 42 { 43 if(base < 0) 44 throw new Exception("A base não pode ser negativa."); 45 this.base = base; 46 } 47 public void setAltura(int altura) throws Exception 48 { 49 if(altura < 0) 50 throw new Exception("A altura não pode ser negativa."); 51 this.altura = altura; 52 }

Page 82: Apostila Android Gratuita

82 Desenvolvendo Aplicações com Java para Android

53 /** 54 * Area total da figura 55 * @return retorna a Base x Altura 56 */ 57 public int areaTotal() 58 { 59 return this.base*this.altura; 60 } 61 }

Código 33 - Código da class Area

No código acima, implementamos uma classe capaz de abstrair as propriedades de algo que no mundo real chamamos de área retangular, tudo que for um retângulo pode ser expresso pela classe acima. Todo retângulo não pode ter lados negativos, pois não há áreas com valores negativos no mundo real.

Abaixo implementamos uma classe que herda as propriedades da superclasse Area. Porem esta nova classe faz chamada ao construtor na superclasse (ver linha 14).

1 //Veja no inicio do livro como obter os fontes 2 package br.com.softpalm.heranca; 3 4 public class AreaCampoFutebol extends Area{ 5 6 /** 7 * Construtor da classe AreaCampoFutebol 8 * @param base base do campo, será a linha de fundo 9 * @param altura altura do campo, será a lateral 10 * @throws Exception Valores inválidos lançam exception 11 */ 12 public AreaCampoFutebol(int base,int altura) throws Exception 13 { 14 super(base,altura); 15 16 if(base < 75 || base > 90) 17 throw new Exception("A base do campo deve ser um valor

entre 75 e 90"); 18 if(altura < 75 || altura > 90) 19 throw new Exception("A altura do campo deve ser um valor

entre 90 e 120"); 20 } 21 }

Código 34 - Código da classe AreaCampoFutebol

1 //Veja no inicio do livro como obter os fontes 2 package livro.poo.heranca; 3 4 /** 5 * Classe utilizada para demonstrar o uso da classe AreaCampoFutebol 6 * @author Wellington 7 * 8 */ 9 public class UsaCampoFutebol { 10 11 public static void main(String[] args) 12 {

Page 83: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 83

13 try 14 { 15 //Segundo o Inmetro as dimensões de um campo são: 16 //Extensão (altura): 17 //valor máximo: 120m 18 //valor mínimo: 90m 19 //Largura (base): 20 //valor máximo: 90m 21 //valor mínimo: 75m 22 23 AreaCampoFutebol area = new AreaCampoFutebol(50,120); 24 System.out.println("A área total é: " +

area.areaTotal()); 25 } 26 catch(Exception ex) 27 { 28 System.out.println("Um erro foi encontrado, descrição: "

+ ex.getMessage()); 29 } 30 } 31 }

Código 35 - Classe utilizada para demonstração

Executando o código da classe UsaCampoFutebol obtemos o resultado expresso na imagem abaixo.

Figura 98 - Exceção se um valor não estiver na especificação

Protected Quando vimos o tópico encapsulamento, foi mencionado que private era o modo de

encapsulamento mais restritivo, seguido de protected, package e depois public (o mais aberto). Naquele tópico mostramos um exemplo para cada tipo de encapsulamento, exceto protected que depende da existência de uma hierarquia para ser demonstrado.

Igual ao exemplo anterior, mas agora tornando os atributos da classe pai acessíveis para as classes filhas através do uso de protected. Protected deixa os atributos da classe pai visíveis, acessíveis “hierarquia abaixo”. Mas para o restante do programa tem o mesmo efeito que private.

Outra frase sobre protected: “A herança permite que uma subclasse ganhe acesso a declarações protected de sua superclasse, mas o usuário não percebe isso, para o usuário (uma classe externa) o que continua existindo é o que é public”.

Interfaces Java por motivos de simplicidade, abandona a idéia de herança múltipla, cedendo lugar ao uso de

interfaces. Interfaces são um conjunto de métodos e constantes (não contém atributos). Os métodos definidos na interface são “ocos” ou desprovidos de implementação. Classes podem dizer que implementam uma interface, estabelecendo um compromisso, uma espécie de contrato, com seus clientes no que se refere a prover uma implementação para cada método da referida interface.. Ao cliente, pode ser dada a definição da interface, ele acaba não sabendo o que a classe é, mas sabe o que faz. Quem programa em Objective C, deve ver as interfaces como algo semelhante ao conceito de protocolos.

Neste exemplo usaremos uma interface de nome imprimível para capturar as características comuns as classe que podem ser imprimidas em algum dispositivo de saída de dados.

Page 84: Apostila Android Gratuita

84 Desenvolvendo Aplicações com Java para Android

1 //Exemplo de código 2 public interface Imprimivel { //alem das classes, so interfaces pode

ocupar um arquivo 3 final char nlin='\n'; //nova linha 4 public String toString(); 5 6 //forma preferida para impressao na tela 7 8 public void toSystemOut(); 9 }

Código 36 - Exemplo de Código Fonte

No exemplo acima criamos uma interface chamada Imprimível, ela será utilizada mais adiante.

1 //Exemplo de código 2 public class Produto implements Imprimivel { 3 //um produto comercial qualquer 4 protected String descricao; 5 protected int quantidade; 6 7 public Produto(String d,int q) 8 { 9 descricao=d; 10 quantidade=q; 11 } 12 13 public String toString() 14 { 15 return new String(" "+descricao+" "+quantidade); 16 } 17 //forma preferida para impressao na tela 18 19 public void toSystemOut() 20 { 21 System.out.print(descricao + quantidade); 22 } 23 }

Código 37 - Exemplo de Código

Na classe acima, estamos utilizando a implementação da interface Imprimível.

O paradigma de orientação a objetos está refletido na capacidade de herança e encapsulamento das interfaces. No caso deste exemplo, a interface foi declarada como public, mas se nada fosse especificado ela pertenceria ao package dela, ou seja os modos de encapsulamento são semelhantes aos de classes.

Uma interface poderia estender a interface Imprimivel:

interface Imprimivel2 extends Imprimivel {

}

Interfaces tem sido representadas por retângulos de bordas arredondadas ligadas as classes que as implementam por linhas tracejadas.

Page 85: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 85

Muitos confundem interfaces com classes e o ato de implementar uma interface com o ato de estender ou herdar uma classe. Por isso a relação entre interfaces e herança será explicada só agora, depois que você já pensou no assunto.

Uma classe Produto2 herda da classe Produto(nosso exemplo) que implementa a interface Imprimivel. A classe produto já fez a parte difícil que é implementar a interface, agora a classe Produto2 pode optar por aceitar ou redefinir os métodos herdados, ou seja: “A interface é um dos itens que é herdado de uma classe, assim como os atributos e métodos”.

Polimorfismo e Classes Abstratas Existem várias classificações e tipos de polimorfismo. C++ apresenta vários tipos de polimorfismo .

Java apresenta um conjunto mais reduzido evitando principalmente polimorfismos ad-hoc.

Polimorfismo, do grego: muitas formas. Polimorfismo é a capacidade de um operador executar a ação apropriada dependendo do tipo do operando. Aqui operando e operador estão definidos num sentido mais geral: operando pode significar argumentos atuais de um procedimento e operador o procedimento, operando pode significar um objeto e operador um método, operando pode significar um tipo e operador um objeto deste tipo.

Redefinição de Métodos para uma Classe Herdeira Este exemplo já foi apresentado em Error! Reference source not found.. Também trata-se de um

polimorfismo, pode ser classificado como polimorfismo de inclusão. Um método é uma redefinição de um método herdado, quando está definido em uma classe construída através de herança e possui o mesmo nome, valor de retorno e argumentos de um método herdado da classe pai. A assinatura do método tem que ser idêntica, ou seja, teremos redefinição quando uma classe filha fornece apenas uma nova implementação para o método herdado e não um novo método.

Se a classe filha fornecer um método de cabeçalho ou assinatura parecida com a do método herdado (difere ou no número ou no tipo dos argumentos, ou então no tipo do valor de retorno) então não se trata mais de redefinição, trata-se de uma sobrecarga, pois criou-se um novo método. Uma chamada ao método herdado não mais é interceptada por esse novo método de mesmo nome. O método tem o mesmo nome, mas é ligeiramente diferente na sua assinatura (o corpo ou bloco de código {} não importa), o que já implica que não proporciona o mesmo comportamento (behaviour) do método da superclasse.

Page 86: Apostila Android Gratuita

86 Desenvolvendo Aplicações com Java para Android

77 7 Interface com o Usuário

Objetivo Deste Apêndice • Entender o comportamento de uma aplicação em Android;

• Conhecer a ideia por traz do conceito Activity;

• Conhecer os elementos básicos de interface;

• Abstrair dicas de usabilidade.

Introdução Uma aplicação não reside isolada em um equipamento, geralmente a aplicação interage com

outras aplicações em busca de atingir alguns resultados (funcionalidades). No próprio sistema operacional temos aplicações que podem interagir com sua aplicação e vice-versa, desta forma sua aplicação deve ter a capacidade de receber eventos do sistema como por exemplo de uma ligação telefônica ou de um controlador GPS.

Imagine que o usuário esteja no meio de um jogo, e recebe uma ligação. A aplicação que neste caso é um jogo não pode sair de cena, e como fica o status do jogo, vai continuar executando enquanto o usuário está no telefone? E quando voltar?

Para satisfazer isso a aplicação deve ter um ciclo de vida que recebe eventos do Sistema Operacional, essa ideia não é explorada no mundo dos Desktops.

View Na plataforma Android a interface com o usuário está baseada no uso de View e ViewGroup.

Existem muitos tipos de Views, o importante que se deve saber neste momento é que todas herdam de View.

A classe View serve de base para subclasses chamadas widgets que oferecem uma forma de implementar interfaces, tais como caixas de texto e botões. A classe ViewGroup serve de base para subclasses chamadas layouts que oferece a base das interfaces.

Um objeto View é uma estrutura de dados, cujas propriedades armazenam dados do layout e determinada área de interface. A View também é capaz de gerenciar suas propriedades como proporção, posição, foco, aparência (baseado no status), scrolling.

Activity Um Activity é um componente do aplicativo que fornece uma tela no qual o usuário podem interagir,

a fim de realizar alguma tarefa como discar o telefone, tomar um foto, envie um e-mail, ou ver um mapa. Cada Activity controla uma janela na qual se pode desenhar sua interface com o usuário. A

Page 87: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 87

janela normalmente preenche a tela, mas pode ser menor do que a tela e flutuar em cima de outras janelas.

Um aplicativo normalmente consiste de múltiplas Activities que são fracamente ligadas umas as outras. Normalmente, uma Activity em um aplicativo é especificada como a Activity Main, que é apresentada ao usuário ao iniciar o aplicativo pela primeira vez, no exemplo acima essa Activity Main será chamada de Gerenciador. Cada Activity pode começar outra Activity, a fim de executar várias ações diferentes. Cada vez que uma começa a Activity anterior é interrompida, mas o sistema preserva a Activity em uma pilha (pilha de retorno).

Ciclo de vida de uma Activity Vimos que as Activities são gerenciados como uma pilha, quando uma nova Activity é iniciada ela

assume o topo da pilha e se torna a Activity em execução. A Activity anterior (que estava em execução antes desta nova Activity) permanece abaixo e só retornará a ser a Activity em execução se a mais recente for finalizada.

Uma Activity pode assumir um estado, essencialmente temos quatro estados possíveis:

• Se uma Activity estiver em primeiro plano (no topo da pilha), ele está ativo e em execução.

• Se a Activity perdeu o foco, mas ainda é visível (ou seja, uma nova Activity não preencheu toda a tela ou possui transparência), então a Activity inferior está no estado de pausa. Uma Activity em pausa ainda está presente na memória e consequentemente na pilha (pois mantém todas as informações do estado e dos membros, e sem contar que ainda persiste no gerenciador de janelas), mas podem ser mortos pelo sistema em situações extremas de baixa memória;

• Se uma Activity é totalmente obscurecida por outra Activity, então ela está parada (stop). Ela ainda mantém todas as informações de estados e membros, no entanto, já não é visível para o usuário e assim que a janela está oculta e que esta pode ser eliminada pelo sistema no caso de falta de memória.

• Se uma Acivity está em pausa ou parada, o sistema pode reivindicar a memória utilizada por ela, para isso pode finalizar a thread responsável por tal Activity. Quando ele é exibido novamente para o usuário, deve ser completamente reiniciado e restaurado ao seu estado anterior.

O diagrama a seguir mostra os caminhos importantes entre ações que pode alterar os estados de uma Activity. Os retângulos quadrados representam métodos (eventos) que você pode utilizar para implementar operações ou ações especiais em momentos específicos de troca de estado. As elipses coloridas são os estados mais importantes que uma Activity pode assumir.

Page 88: Apostila Android Gratuita

88 Desenvolvendo Aplicações com Java para Android

Há três sequencia de ações que devemos monitorar: vida de uma Activity, tempo visível de uma

Activity e Activity no topo da pilha.

Vida de uma Activity

A vida de uma Activity acontece entre a primeira chamada para onCreate (Bundle) até a chamada do finally() que resulta no evento onDestroy(). Uma Activity irá fazer toda a configuração do estado de suas propriedades no OnCreate() e liberar todos os recursos remanescentes em onDestroy().

Figura 99 - Ciclo de vida de uma Activity

Temo de visibilidade de uma Activity O tempo de vida visível de uma Activity acontece entre uma chamada para onStart() até uma

chamada correspondente para onStop(). Durante este período o usuário pode ver a Activity na tela, embora não possa estar em primeiro plano e interagir com o usuário. Entre estes dois métodos que você pode manter os recursos que são necessários para mostrar a atividade para o usuário.

Page 89: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 89

Figura 100 - Visibilidade de uma Activity

Activity no topo da pilha

O tempo de vida do primeiro plano (topo da pilha) de uma Activity acontece entre uma chamada para onResume() até uma chamada correspondente para onPause(). Durante esse tempo, a Activity está na frente de todas as outras atividades e pode interagir com o usuário.

Figura 101 - Activity no topo da pilha

O ciclo de vida de uma Activity é definida pelos eventos, todos estes eventos invocam métodos na Activity e é nestes métodos que implementamos nossos códigos para executar as funcionalidades requeridas. Logo abaixo temos uma classe Activity, repare que temos as implementações dos métodos expostos nas figuras acima.

1 public class Activity extends ApplicationContext { 2 3 protected void onCreate(Bundle savedInstanceState); 4 5 protected void onStart(); 6 7 protected void onRestart(); 8 9 protected void onResume(); 10 11 protected void onPause(); 12 13 protected void onStop(); 14 15 protected void onDestroy(); 16 }

onCreate(): Chamado quando a Activity é criada pela primeira vez. Isto é onde você pode: criar pontos de vista, vincular dados em listas, carregar dados, etc.. Esse método também fornece a você um pacote contendo o estado previamente congelado da atividade, se houvesse um;

onRestart(): Chamado após uma Activity ser parada (stop), ela prepara a Activity para retomada do topo da pilha;

onStart(): Chamado quando a Activity está se tornando visível para o usuário;

onResume(): Chamado quando a Activity vai começar a interagir com o usuário. Neste ponto, sua atividade está no topo da pilha de atividade.

onPause(): Chamado quando o sistema está prestes a começar a retomar uma Activity anterior. Isso normalmente é usado para salvar alterações não salvas da Activity corrente. Implementações deste método deve ser muito rápida porque a próxima Activity não será iniciada até que esse método retorne.

onStop(): Chamado quando a Activity já não é visível para o usuário, porque outra Activity está cobrindo toda a tela. Isso pode acontecer ou porque uma nova Activity que está sendo iniciada ou é uma já existente está sendo trazida à frente da pilha.

onDestroy(): A última chamada recebida pela Activity antes de ser destruída, isso porque a Activity foi finalizada pelo método finally() ou o espaço da memória está sendo requerido pelo sistema. Você

Page 90: Apostila Android Gratuita

90 Desenvolvendo Aplicações com Java para Android

pode distinguir entre estas duas opções através do método isFinishing().

Atenção: No próximo exemplo (após estudar sobre o padrão de interface) vamos demonstrar com detalhes o ciclo de vida de uma Activity.

Editor de Layout Um ponto interessante na tecnologia adotada pelo Android é a forma que é desenvolvido a

interface, se você é um programador Java que está acostumado a criar interfaces pelo código verá que nesta plataforma as interfaces por padrão são feitas em arquivos .xml.

Atenção: Eu disse por padrão, porque é possível desenvolver interfaces toda via código porem pelos exemplos e pela documentação oficial isso não é comum.

Vamos criar um exemplo chamado Exemplo003 no qual vamos criar dois formulários simples e navegar de um para o outro. Também vamos aproveitar para demonstrar a sequência de métodos do ciclo de vida de uma Activity.

Figura 102 - Botão que cria um projeto

Crie o projeto com as seguintes propriedades:

New Android Project

Project name Exemplo003

Build Target Android 2.2

Application Name Exemplo003

Package name br.com.softpalm.layout

Create Activity (selecionado) Main

Min SDK Version 8

Quando o projeto é criado alguns arquivos são gerados, ente eles encontramos um arquivo .xml chamado main.xml e um Main.java (ver figura abaixo).

Figura 103 - Arquivo XML e Activity

Estes dois arquivos representam (na mesma sequência) o arquivo de interface e a Activity controladora. Nada liga um ao outro, logo esta Activity Main.java pode carregar quantos arquivos .xml

Page 91: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 91

o programador quiser, alguns programas exemplos na Internet (no próprio repositório do Android) aponta para o uso de vários XML de laytou para uma Activity somente.

Neste livro vou abordar uma tática diferente, mesmo não havendo o elo entre a Activity e o arquivo de layout XML vou manter: para cada arquivo de layout XML vou criar uma Activity.

Pense: Imagine 15 janelas (arquivos XML) utilizando a mesma Activity, os componentes de interface possuem métodos, pense em todos os métodos no mesmo código.

Vamos aprender Como criar uma Activity e um arquivo de layout XML. Primeiro crie uma classe dentro do pacote, no nosso caso pacote br.com.softpalm.layout.

Fique atento ao nome, sempre com primeira letra maiúscula pois é uma classe, veja na imagem

abaixo que estou informando uma superclasse. Isso porque nossa classe deverá herdar de android.app.Activity.

Figura 104 - Criando a classe Activity

O código gerado fica (procurar em Project Explorer a classe Tela) é:

1 package br.com.softpalm.layout; 2 3 import android.app.Activity; 4 5 public class Tela extends Activity { 6 7 }

Vamos agora registrar no Manifest a nossa Activity. Clique no arquivo AndroidManifest.xml (ver figura abaixo) escolha a aba Application e veja a lista de Activities da sua aplicação.

Page 92: Apostila Android Gratuita

92 Desenvolvendo Aplicações com Java para Android

Figura 105 - Editor AndroidManifest

Para adicionar então o registro da Activity clique em Add... (ver figura acima) para adicionar uma nova Activity.

Figura 106 - Registrando uma Activity

Agora temos que selecionar a classe (código Java) associado a esse registro, selecione Activity (clicando em Browser).

Figura 107 - Configuração da Activity

Encontre a classe Tela (nossa Activity) e clique em OK.

Figura 108 - Localizando a classe Activity

Lembre-se de escrever um texto em Label (Figura 107). Agora vamos criar o arquivo de layout XML,

Page 93: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 93

conforme dito para cada layout vamos utilizar um arquivo de layout XML e uma Activity.

Figura 109 - Botão que adicona um XML

Quando instalamos o pluguin do Android três botões foram adicionados na nossa barra (ver figura acima), clique em Adicionar XML.

Figura 110 - Adicionando um arquivo XML

Dê um nome ao seu resource, repare que estou utilizando o nome minúsculo para acompanhar o padrão dos exemplos Android. Clique em Finish. O arquivo gerado pode ser encontrado em Exemplo003 | res | layout conforme figura abaixo. Dê um duplo clique no arquivo main.xml, vamos começar a adicionar objetos a interface.

Page 94: Apostila Android Gratuita

94 Desenvolvendo Aplicações com Java para Android

Figura 111 - Editor de Layout

Foi aberto o Editor de Layout (ver figura acima), repare que podemos ver a tela e também simular alterando os parâmetros. Isso é bom para poder testar vários ambientes com várias configurações sem ter que fazer o Deploy (capítulos anteriores) para ver.

Arraste um Button da Palette para a tela, conforme figura abaixo. Mantenha o Button selecionado e veja as propriedades na aba Properties (ver figura abaixo). Procure a propriedade Id e altere para: @+main/btnNavegar conforme figura abaixo. Aproveite e também altere o Text para Navegar.

Atenção: Se não encontrar a aba Properties (ver figura abaixo) recorra ao Apêndice 3 como o Apêndice 3 é genérico saiba que a aba que procura está em Geral | Properties.

Figura 112 - Editor de Layout

Page 95: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 95

Você deve estar se perguntando, porquê dar um Id tão complexo, nas demais linguagens Ids eram palavras simples. Vamos mais a fundo para entender. Repare que comecei o Id com main, veja no arquivo R.java temos várias constantes que são geradas automaticamente pela ferramenta. Veja (ver figura abaixo) que temos “public static final class main” e dentro desta classe temos a constante btnNavegar. Só de olhar para este arquivo podemos entender o resto do Id.

Figura 113 - Código da classe R

Lembre-se: Esse arquivo não pode ser alterado pelo programador manualmente. Então nosso layout main ficará assim:

Figura 114 - Layout do primeiro formulário

Proximo passo e adicionar um evento para o botão, neste evento nós vamos navegar para a próxima Activity. Acesse o arquivo Main.java e edite o código abaixo.

1 package br.com.softpalm.layout; 2 3 import android.app.Activity; 4 import android.content.Intent; 5 import android.os.Bundle; 6 import android.view.View; 7 import android.widget.Button; 8 9 public class Main extends Activity { 10 /** Called when the activity is first created. */ 11 @Override 12 public void onCreate(Bundle savedInstanceState) { 13 super.onCreate(savedInstanceState); 14 15 // Carrega o arquivo de layout XML chamado main.xml 16 setContentView(R.layout.main); 17 18 // Criando o evento para o botão

Page 96: Apostila Android Gratuita

96 Desenvolvendo Aplicações com Java para Android

19 // primeiro vamos pegar o botão 20 Button bt = (Button) this.findViewById(R.main.btnNavegar); 21 22 // agora vamos adicionar o evento 23 bt.setOnClickListener(new View.OnClickListener() { 24 25 @Override 26 public void onClick(View v) { 27 btnNavegar_Click(v); 28 } 29 }); 30 } 31 32 // Criei este método só para tratar o evento 33 public void btnNavegar_Click(View v) { 34 // Arqui eu inicio a Activity Tela 35 this.startActivity(new Intent(this, Tela.class)); 36 } 37 38 // O código abaixo implementa os eventos 39 // do ciclo de vida da Activity só para testes 40 protected void onStart() { 41 super.onStart(); 42 System.out.println("Start"); 43 } 44 45 protected void onRestart() { 46 super.onRestart(); 47 System.out.println("Restart"); 48 } 49 50 protected void onResume() { 51 super.onResume(); 52 System.out.println("Resume"); 53 } 54 55 protected void onPause() { 56 System.out.println("Pause"); 57 super.onPause(); 58 } 59 60 protected void onStop() { 61 System.out.println("Stop"); 62 super.onStop(); 63 } 64 65 protected void onDestroy() { 66 System.out.println("Destroy"); 67 super.onDestroy(); 68 } 69 }

Código 38 - Código da classe Main.java

Já podemos executar a aplicação, execute a aplicação no emulador e mude para a perspectiva Debug. Veja que sua aplicação será carregada e no output deverá aparecer Start e Resume (ver figura abaixo).

Page 97: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 97

Figura 115 - Output

Isso porque (já abordado no ciclo de vida) primeiro será executado onCreate() seguido de onStart() e onResult().

Agora no emulador clique no botão Navegar para chamar a outra Activity. Conforme teoria abordada no ciclo de vida quando a nova Activity assume o topo da pilha a Activity (em execução) invoca na sequencia os eventos onPause() e onStop().

Figura 116 - Output

Vamos agora fazer o botão voltar na segunda tela, para isso abra o arquivo tela.xml em layout e adicione um botão. Para esse botão altere o Id para Id @+tela/btnVoltar e o texto para Voltar.

Figura 117 - Layout do segundo formulário

Agora vamos adicionar o evento para o botão, abra o arquivo Tela.java em src. Edite o código abaixo.

1 package br.com.softpalm.layout; 2 3 import android.app.Activity; 4 import android.os.Bundle; 5 import android.view.View; 6 import android.widget.Button; 7 8 public class Tela extends Activity { 9 public void onCreate(Bundle savedInstanceState) { 10 super.onCreate(savedInstanceState); 11 12 // Carrega o arquivo de layout XML chamado tela.xml 13 setContentView(R.layout.tela); 14

Page 98: Apostila Android Gratuita

98 Desenvolvendo Aplicações com Java para Android

15 // Criando o evento para o botão 16 // primeiro vamos pegar o botão 17 Button bt = (Button) this.findViewById(R.tela.btnVoltar); 18 19 // agora vamos adicionar o evento 20 bt.setOnClickListener(new View.OnClickListener() { 21 22 @Override 23 public void onClick(View v) { 24 btnNavegar_Click(v); 25 } 26 }); 27 } 28 29 public void btnNavegar_Click(View v) 30 { 31 this.finish(); 32 } 33 }

Código 39 - Código da classe Tela.java (Revisão svn 9)

Repare que basta finalizar a Activity que ela sai do topo da pilha e volta a dar foco ao formulário anterior.

Quando o formulário anterior volta a ser o primeiro da pilha, novamente ele roda na sequência onRestart(), onStart() e onResume(). Faça assim, fique clicando em Navegar e Voltar sempre analisando o output.

android.widget O pacote android.widget reune elementos gráficos para serem utilizados para interação humano

aplicação, neste capítulo vamos abordar os principais componentes gráficos e ao final abordar a construção dos nossos próprios Widgets.

TextView TextView é utilizado para exibir um texto e permitir a sua edição. Porem por padrão sua

configuração não permite a edição, substitui o Label utilizado nas outras tecnologias.

Atenção: Para permitir a edição de textos utilize o componente EditText.

Figura 118 - TextView na Palette

EditText O controle EditText herda de TextView (visto acima), sua configuração permite a edição de texto por

padrão, é similar ao TextBox (Framework .NET) ou do JTextFied (Java).

Figura 119 - EditText na Palette

Page 99: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 99

Button Controle utilizado para disponibilizar ações ao usuário e pode assumir o comportamento clicável

(click-button) ou pressionado com estado (push-button). Por padrão o comportaménto é click-button.

Figura 120 - Button na Palette

Vamos agora criar um projeto para demonstrar o uso do TextView, EditText e Button. Neste novo projeto vamos exigir um texto e ao clicar no botão o texto será transformado e um texto todo maiúsculo. Então os dados do novo projeto são:

New Android Project

Project name Exemplo004

Build Target Android 2.2

Application Name Exemplo004

Package name br.com.softpalm.layout.text

Create Activity (selecionado) Main

Min SDK Version 8

Arraste da Palette um objeto TextView, EditText e um Button conforme figura abaixo.

Altere o Id do TextView para “@+main/txvLabel” e Text para “Digite um texto:”. Do componente EditText altere o Id para “@+main/edtText”. Do Button o Id para “@+main/btnExecutar” e Text “Executar”.

Figura 121 - Layout do formulário main.xml

Se preferir pode ir por XML conforme código abaixo.

1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:orientation="vertical" 4 android:layout_width="fill_parent" 5 android:layout_height="fill_parent"> 6 <TextView 7 android:id="@+main/txvLabel" 8 android:layout_width="wrap_content" 9 android:layout_height="wrap_content" 10 android:text="Digite um texto: "> 11 </TextView> 12 <EditText 13 android:layout_height="wrap_content" 14 android:id="@+main/edtText" 15 android:layout_width="match_parent"> 16 </EditText> 17 <Button

Page 100: Apostila Android Gratuita

100 Desenvolvendo Aplicações com Java para Android

18 android:text="Executar" 19 android:id="@+main/btnExecutar" 20 android:layout_width="wrap_content" 21 android:layout_height="wrap_content"> 22 </Button> 23 </LinearLayout>

Atenção: Se não sabe como ver o formulário na view XML basta selecionar a aba main.xml.

Próximo passo é editar o código fonte que vai executar a ação. O código da classe Main.java é:

1 package br.com.softpalm.layout.Text; 2 3 import android.app.Activity; 4 import android.os.Bundle; 5 import android.view.View; 6 import android.widget.Button; 7 import android.widget.EditText; 8 // Revisão SVN 10 9 public class Main 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 // relacionando XML com código 17 edtText = (EditText)this.findViewById(R.main.edtText); 18 btnExecutar = (Button) this.findViewById(R.main.btnExecutar); 19 20 // Criando o evento 21 btnExecutar.setOnClickListener(new View.OnClickListener() { 22 23 @Override 24 public void onClick(View v) { 25 btnExecutar_Click(v); 26 } 27 }); 28 } 29 30 /** 31 * Executa a ação Click do botão 32 * @param v é a View que está sendo invocada 33 */ 34 public void btnExecutar_Click(View v) 35 {

Page 101: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 101

36 String texto = edtText.getText().toString(); 37 edtText.setText(texto.toUpperCase()); 38 } 39 40 // Elementos da interface 41 private Button btnExecutar ; 42 private EditText edtText ; 43 }

Alguns pontos importantes que podemos citar é que o getText() da linha 36 não retorna um texto em String, retorna na verdade uma classe Editable, por isso precisamos do toString().

Outro ponto que podemos citar é o comentário Javadoc feito na linha 30, veja mais sobre Javadoc na Internet.

Execute a aplicação, escreva algum texto e pressione o botão, veja que o texto vai ser alterado.

Usabilidade: Está claro que quando queremos exibir um texto onde o usuário não pode editar utilizamos TextView e quando precisamos de uma caixa para edição de um texto usamos EditText.

ToggleButton ToggleButton é um botão que exibe um estado "ON" ou "OFF" no qual o usuário pode pressionar e

alterar o estado caso queira.

Figura 122 - ToggleButton na Palette

Usabilidade: Utilize o ToggleButton para solicitar um “Sim” ou “Não” e quando uma resposta é obrigatória. Deixe a opção padrão marcada de acordo com sua necessidade.

Para deixar claro o uso do ToggleButton vamos criar um projeto simples, conforme tabela abaixo:

New Android Project

Project name Exemplo005

Build Target Android 2.2

Application Name Exemplo005

Package name br.com.softpalm.layout.button

Create Activity (selecionado) Main

Min SDK Version 8

O usuário vai ter um ToggleButton na tela, e a medida que ele pressiona ou libera vamos escrever no output a ação executada.

Arraste da Palette um objeto ToggleButton conforme figura abaixo.

Figura 123 - Layout do exemplo

Se preferir (assim como eu) utilize o Editor XML para editar o arquivo main.xml.

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

Page 102: Apostila Android Gratuita

102 Desenvolvendo Aplicações com Java para Android

2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:orientation="vertical" 4 android:layout_width="fill_parent" 5 android:layout_height="fill_parent" 6 android:background="#ffffff" 7 > 8 <ToggleButton 9 android:text="ToggleButton" 10 android:layout_width="wrap_content" 11 android:layout_height="wrap_content" 12 android:id="@+main/tgbOnOff" 13 android:textOff="Estado Off" 14 android:textOn="Estado On"> 15 </ToggleButton> 16 </LinearLayout>

Repare que temos na linha 13 e 14 o texto que será exibido caso esteja pressionado ou liberado. Por padrão pressionado é ON e liberado é OFF.

Agora vamos editar o código executável do arquivo Main.java em src.

1 package br.com.softpalm.button; 2 3 import android.app.Activity; 4 import android.os.Bundle; 5 import android.view.View; 6 import android.widget.ToggleButton; 7 8 public class Main extends Activity { 9 /** Called when the activity is first created. */ 10 @Override 11 public void onCreate(Bundle savedInstanceState) { 12 super.onCreate(savedInstanceState); 13 setContentView(R.layout.main); 14 15 tgbOnOff = (ToggleButton)this.findViewById(R.main.tgbOnOff); 16 17 // Utilizando o evento Click 18 tgbOnOff.setOnClickListener(new View.OnClickListener() 19 { 20 public void onClick(View v) { 21 tgbOnOff_Click(v); 22 } 23 }); 24 } 25 26 public void tgbOnOff_Click(View v) 27 { 28 if (tgbOnOff.isChecked()) 29 System.out.println("Pressionado"); 30 else 31 System.out.println("Liberado"); 32 } 33 34 ToggleButton tgbOnOff; 35 }

Na linha 28 estamos usando o método isChecked() para verificar se o componente de interface está pressionado ou liberado. No output (Perspective Debug) podemos ver o resultado de nossas ações.

Page 103: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 103

Figura 124 - Output do Emulador

RadioButton e RadioGroup Um RadioButton é um botão de dois estados que pode ser marcado ou desmarcado. Quando o

RadioButton está desmarcado, o usuário pode pressionar e marcar. Um comportamento interessante é que depois de marcado o RadioButton não pode ser desmarcado pelo usuário pela interface (diretamente).

O que ocorre é que um RadioButton nunca está sozinho, não faz sentido usar um RadioButton isolado. Utiliza-se grupos de RadioButtons que estão associados em um RadioGroup, quando o usuário marca um RadioButton o RadioGroup automaticamente desmarca os demais. Utiliza-se o RadioGroup para gerenciar um conjunto de RadioButton no qual exigimos uma escolha do usuário dentre o grupo, ou seja, exigir uma escolha somente.

Figura 125 - RadioGroup e RadioButton na Palette

Vamos criar um projeto para demonstrar o uso do RadioGroup, crie um projeto Android conforme tabela abaixo:

New Android Project

Project name Exemplo006

Build Target Android 2.2

Application Name Exemplo006

Package name br.com.softpalm.layout.radio

Create Activity (selecionado) Main

Min SDK Version 8

O usuário vai ter um RadioGroup na tela, e a medida que ele marca as opções vamos escrever na própria tela usando uma janelinha Toast (vamos estudar mais a frente).

O layout do formulário é simples, basta acompanhar o XML abaixo, repare que apenas altreis os Ids.

1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:orientation="vertical" 4 android:layout_width="fill_parent" 5 android:layout_height="fill_parent" 6 > 7 <RadioGroup android:id="@+main/rdgGrupo" 8 android:layout_width="wrap_content" 9 android:layout_height="wrap_content">

Page 104: Apostila Android Gratuita

104 Desenvolvendo Aplicações com Java para Android

10 <RadioButton 11 android:layout_width="wrap_content" 12 android:text="RadioButton" 13 android:layout_height="wrap_content" 14 android:id="@+main/rdgGrupoOp01" 15 android:checked="true"> 16 </RadioButton> 17 <RadioButton 18 android:layout_width="wrap_content" 19 android:text="RadioButton" 20 android:layout_height="wrap_content" 21 android:id="@+main/rdgGrupoOp02"> 22 </RadioButton> 23 <RadioButton android:layout_width="wrap_content" 24 android:text="RadioButton" 25 android:layout_height="wrap_content" 26 android:id="@+main/rdgGrupoOp03"> 27 </RadioButton> 28 </RadioGroup> 29 </LinearLayout>

Veja que as Tags RadioButton estão todas internas a Tag RadioGroup. Outro ponto interessante é a linha 15 na qual estamos marcando a opção 1 como “marcado”.

Agora vamos digitar o código que faz o mecanismo funcionar, abra o arquivo Main.java em src e codifique o código abaixo.

1 package br.com.softpalm.layout.radio; 2 3 import android.app.Activity; 4 import android.os.Bundle; 5 import android.view.View; 6 import android.widget.RadioButton; 7 import android.widget.Toast; 8 9 /** 10 * 11 * @author Wellington 12 * Revisão SVN 11 13 */ 14 public class Main extends Activity { 15 /** Called when the activity is first created. */ 16 @Override 17 public void onCreate(Bundle savedInstanceState) { 18 super.onCreate(savedInstanceState); 19 setContentView(R.layout.main); 20 21 // Como sempre, pegando os objetos da interface e 22 // armazenando em atributos da classe 23 this.rdgGrupoOp01 =

(RadioButton)this.findViewById(R.main.rdgGrupoOp01); 24 this.rdgGrupoOp02 =

(RadioButton)this.findViewById(R.main.rdgGrupoOp02); 25 this.rdgGrupoOp03 =

(RadioButton)this.findViewById(R.main.rdgGrupoOp03); 26 27 // Criando os eventos, só que em vez de criar um evento 28 // para cada componente conforme os demais exemplos 29 // vou criar um único tratador de evento (ver o código 30 // mais abaixo)

Page 105: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 105

31 this.rdgGrupoOp01.setOnClickListener(this.rdgGrupo_Click); 32 this.rdgGrupoOp02.setOnClickListener(this.rdgGrupo_Click); 33 this.rdgGrupoOp03.setOnClickListener(this.rdgGrupo_Click); 34 35 // Marcar como a Opção 1 como padrão 36 this.rdgGrupoOp01.setChecked(true); 37 } 38 39 /** 40 * Tratador do evento Click para todos as opções Radio 41 */ 42 private RadioButton.OnClickListener rdgGrupo_Click = new

RadioButton.OnClickListener() { 43 public void onClick(View v) { 44 String str = "Opção 1 : " + rdgGrupoOp01.isChecked() +

"\n"; 45 str += "Opção 2 : " + rdgGrupoOp02.isChecked() + "\n"; 46 str += "Opção 3 : " + rdgGrupoOp03.isChecked(); 47 48 // O Toast será estudado mais a frente, apenas use ele 49 // para exibir uma pequena janela com um texto 50 Toast.makeText(Main.this, str,

Toast.LENGTH_SHORT).show(); 51 } 52 }; 53 54 // Atributos da classe 55 private RadioButton rdgGrupoOp01, rdgGrupoOp02, rdgGrupoOp03; 56 }

Note que por estar usando o mesmo evento em três componentes decidi criar o evento fora e relacionar o mesmo evento. Nas linhas 44, 45 e 46 podemos ver como é fácil saber se um radio está ou não marcado.

Você deve ter ficado impressionado com o elemento Toast em execução, repare que ao clicar nas opções ele aparece e desaparece, mais a frente vamos detalhar o Toast.

Usabilidade: Usamos o RadioGroup para exigir do usuário uma opção somente e obrigatóriamente.

CheckBox Ao contrário do RadioButton o CheckBox pode estar sozinho, posso ter mais de um CheckBox

marcado ao mesmo tempo, posso até não ter nenhum marcado. Por isso não requer controlador de grupo.

Figura 126 - CheckBox na Palette

Vamos agora criar um projeto para demonstrar o uso do CheckBox, crie um projeto de acordo com os dados abaixo.

New Android Project

Project name Exemplo007

Build Target Android 2.2

Page 106: Apostila Android Gratuita

106 Desenvolvendo Aplicações com Java para Android

Application Name Exemplo007

Package name br.com.softpalm.layout.check

Create Activity (selecionado) Main

Min SDK Version 8

Neste programa o usuário vai marcar CheckBox dizendo se tem gatos e cachorros.

Sempre começamos com a edição do arquivo XML de layout, no nosso caso só vamos ter main.xml no projeto. Adicione dois CheckBox conforme figura abaixo.

Figura 127 - Layout do formulário main.xml

Para isso vamos usar o XML abaixo no arquivo main.xml.

1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:orientation="vertical" 4 android:layout_width="fill_parent" 5 android:layout_height="fill_parent" 6 > 7 <CheckBox 8 android:id="@+main/ckbCachorro" 9 android:layout_width="wrap_content" 10 android:layout_height="wrap_content" 11 android:text="Possui Cachorro?"> 12 </CheckBox> 13 <CheckBox 14 android:id="@+main/ckbGato" 15 android:layout_width="wrap_content" 16 android:layout_height="wrap_content" 17 android:text="Possui Gato?"> 18 </CheckBox> 19 </LinearLayout>

Simples, nada de novo. Se quiser que um CheckBox esteja marcado utilize a propriedade android:checked conforme exemplo do RadioButton.

1 package br.com.softpalm.layout.check; 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 /** 10 * Revisão SVN 12 11 * @author Wellington 12 * 13 */ 14 public class Main extends Activity { 15 /** Called when the activity is first created. */ 16 @Override

Page 107: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 107

17 public void onCreate(Bundle savedInstanceState) { 18 super.onCreate(savedInstanceState); 19 setContentView(R.layout.main); 20 21 // Como sempre, pegando os objetos da interface e 22 // armazenando em atributos da classe 23 this.ckbCachorro =

(CheckBox)this.findViewById(R.main.ckbCachorro); 24 this.ckbGato =

(CheckBox)this.findViewById(R.main.ckbGato); 25 26 // Criando os eventos, só que em vez de criar um evento 27 // para cada componente conforme os demais exemplos 28 // vou criar um único tratador de evento (ver o código 29 // mais abaixo) 30 this.ckbCachorro.setOnClickListener(this.rdgGrupo_Click); 31 this.ckbGato.setOnClickListener(this.rdgGrupo_Click); 32 } 33 34 /** 35 * Tratador do evento Click para todos os CheckBox 36 */ 37 private CheckBox.OnClickListener rdgGrupo_Click = new

CheckBox.OnClickListener() { 38 public void onClick(View v) { 39 String str = "Possui cachorros : " +

ckbCachorro.isChecked() + "\n"; 40 str += "Possui gatos : " + ckbGato.isChecked(); 41 42 // O Toast será estudado mais a frente, apenas use ele 43 // para exibir uma pequena janela com um texto 44 Toast.makeText(Main.this, str,

Toast.LENGTH_SHORT).show(); 45 } 46 }; 47 48 // Atributos da classe 49 private CheckBox ckbCachorro, ckbGato; 50 }

AutoCompleteTextView Assim como a EditText o AutoCompleteTextView permite que o usuário digite uma determinada

informação, porem o AutoCompleteTextView exibe opções de palavras a medida que o usuário digita a palavra desejada a aplicação sujere opções.

Usabilidade: Em dispositivos móveis a Interação Humano Computador é uma das prioridades visto que a entrada de dados por parte do usuário é demorado.

Imagine que o usuário escreveu "Cad", o programa automaticamente pode sugerir algumas palavras, tais como Cadeira, Cadê, Cadência, etc.. O programador pode gerar uma lista de possíveis palavras para facilitar a usabilidade.

Usabilidade: Para caixa de texto com palavras simples o AutoCompleteTextView é o componente indicado.

Quando você disponibiliza opções facilita o entendimento de aplicações de retaguarda, imagine um sistema de inventariado patrimonial, cadeira pode ser escrito de diferentes formas, exemplos: Ca deira, cadera, |cadeira, etc.. Isso porque o usuário final utiliza um equipamento de baixa qualidade de usabilidade, muito restrito. Se ele escrever Cad e já aparecer na listagem Cadeira ele vai selecionar, vai ser mais rápido e vai padrozinar os dados que serão tratados pela retaguarda.

Page 108: Apostila Android Gratuita

108 Desenvolvendo Aplicações com Java para Android

MultiAutoCompleteTextView O MultiAutoCompleteTextView extende de AutoCompleteTextView, logo o

MultiAutoCompleteTextView disponibiliza ao usuário uma série de opções, porem neste componente temos a opção de utilizar um MultiAutoCompleteTextView.Tokenizer para selecionar as opções sugeridas.

Para fixar o MultiAutoCompleteTextView e AutoCompleteTextView vamos criar um projeto exemplo, neste projeto o usuário deverá digitar algumas palavras e o device deverá ajudar exibindo uma lista de possíveis palavras. Crie um projeto baseado nas configurações da tabela abaixo.

New Android Project

Project name Exemplo008

Build Target Android 2.2

Application Name Exemplo008

Package name br.com.softpalm.layout.auto

Create Activity (selecionado) Main

Min SDK Version 8

Adicione um controle AutoCompleteTextView e um MultiAutoCompleteTextView, altere o arquivo main (XML) conforme a listagem abaixo.

1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:orientation="vertical" 4 android:layout_width="fill_parent" 5 android:layout_height="fill_parent" 6 android:background="#ffffff"> 7 <AutoCompleteTextView 8 android:layout_height="wrap_content" 9 android:id="@+main/txtAuto" 10 android:layout_width="match_parent" 11 > 12 </AutoCompleteTextView> 13 <MultiAutoCompleteTextView 14 android:completionThreshold="1" 15 android:layout_height="wrap_content" 16 android:id="@+main/txtMulti" 17 android:layout_width="match_parent"> 18 </MultiAutoCompleteTextView> 19 </LinearLayout>

Nesta aplicação vamos demonstrar como o AutoCompleteTextView e o MultiAutoCompleteTextView auxiliam o usuário na entrada de dados, outro ponto importante que pretendemos destacar é a padronização da entrada. Se você pedir para usuários de aplicações móveis digitar a palavra “Cadeira” pode ser que você tenha surpresas, experiências anteriores em projetos de inventariado demonstraram que existem várias formas de se escrever “cadeira”, veja, neste texto foi digitado “Cadeira” e “cadeira”, mas não ficaria surpreso com “caddeira”, “cadira”, “c adeira”, (acredite existem mais de 100 formas diferentes).

O impacto deste problema é maior na retaguarda, que tem a função de tratar os dados para uma possível aplicação de negócio, algumas técnicas de Inteligência Artificial podem corrigir isso porem prefiro atuar na linha de frente (na aplicação móvel) exigindo um texto mais formatado. Porem obrigar usuário a digitar direito é como “obrigar um Elefante a criar asas e voar”, então o recurso de auto-completar é um trunfo que o programador pode utilizar (um porque existem outras formas).

Vou começar montando um atributo na classe Main.java do tipo array de String (linha 30), neste array vamos adicionar as possíveis opções que eu acredito que o usuário encontre quando estiver em campo. Porêm nada impede do sistema “aprender” e criar esta lista baseado nas experiências do

Page 109: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 109

usuário (em 2012 lanço um livro de Inteligência Artificial para plataforma móvel).

1 package br.com.softpalm.auto; 2 3 import android.app.Activity; 4 import android.os.Bundle; 5 import android.widget.ArrayAdapter; 6 import android.widget.AutoCompleteTextView; 7 import android.widget.MultiAutoCompleteTextView; 8 // Revisão SVN 13 9 public class Main extends Activity { 10 11 public void onCreate(Bundle savedInstanceState) { 12 super.onCreate(savedInstanceState); 13 setContentView(R.layout.main); 14 15 // Criando um Adapter para associar a um array de opções mais

prováveis 16 ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,

android.R.layout.simple_dropdown_item_1line, OPCOES); 17 18 // Resgatando o objeto (definido no XML) 19 AutoCompleteTextView txtAutoComplete =

(AutoCompleteTextView)this.findViewById(R.main.txtAuto); 20 MultiAutoCompleteTextView txtMultiAutoComplete =

(MultiAutoCompleteTextView)this.findViewById(R.main.txtMulti); 21 22 // Passando o Adapter para os dois objetos 23 txtAutoComplete.setAdapter(adapter); 24 txtMultiAutoComplete.setAdapter(adapter); 25 26 // Passando um Tokenizer para o Multi 27 txtMultiAutoComplete.setTokenizer(new

MultiAutoCompleteTextView.CommaTokenizer()); 28 } 29 30 private static final String[] OPCOES = new String[] { 31 "Cadeira", "Braço", "Cor", "Encosto", "Mola", "Estofada",

"Azul", "Vermelha" , "Rodinha" 32 }; 33 }

Nas linhas 19 e 20 estamos resgatando a referência dos objetos, nada de novo até ai. Porem nas linhas 23 e 24 passamos para os controles de interface um objeto Adapter.

Este objeto foi criado na linha 16, utilizamos as opções (array de String) e um DropDown para exibir as opções (parâmetro simple_dropdown_item_1line).

Até este ponto os dois tipos de controles são iguais, agora vamos passar para o MultiAutoComplete um Tokenizer que será utilizado para escolher as opções e adicionar a opção selecionada a caixa de texto.

Vou neste primeiro exemplo usar o Tokenizer padrão, que completa a palavra e adiciona virgula seguido de espaço. Vamos aos testes que deverá ficar mais claro.

Page 110: Apostila Android Gratuita

110 Desenvolvendo Aplicações com Java para Android

Figura 128 - MultiAutoCompleteTextView e AutoCompleteTextView

No campo AutoCompleteTextView vamos digitar Ca e vamos ver se ele exibe a opção Cadeira conforme esperado.

Figura 129 - Análise do comportamento do AutoCompleteTextView

Repare na figura acima que na caixa de digitação foi digitado Ca e apareceu um DropDown List com as opções definidas no array OPCOES. Foi exibido em um DropDown List porque no código linha 16 quando definimos o Adapter o parâmetro simple_dropdown_item_1line, existem outros parâmetros que podem alterar o layout da lista de opções, como o select_dialog_multichoice que exibe um MultiChoice conforme figura abaixo.

Figura 130 - Uso do select_dialog_multichoice

Vamos agora escolher a palavra cadeira e digitar na sequência de Bra conforme figura abaixo (a ideia e digitar a frase Cadeira de Braço).

Figura 131 - AutoCompleteTextView com duas palavras

Repare que não aparece o DropDown List, porque já fizemos a escolha da cadeira.

Usabilidade: Utiliza-se o AutoCompleteTextView para dar a opção de escrita de uma palavra. Vamos agora passar para o MultiAutoCompleteTextView porque nosso objetivo é escrever a frase:

Cadeira de Braço. Vamos digitar Ca no MultiAutoCompleteTextView.

Figura 132 - Digitando Ca no MultiCompleteTextView

Repare que a figura acima é semelhante a Figura 129 exceto que o DropDown Lista apareceu acima do controle, mas isso foi apenas por posicionamento do controle. Selecione Cadeira na lista do

Page 111: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 111

DropDown List.

Figura 133 - MultiCompleteTextView

Por padrão ele adicionou o Token virgula “,” e um espaço para você começar a digitar a próxima palavra. Vamos digitar Bra e ver se aparece o DropDown List.

Figura 134 MultiCompleteTextView

Repare que aparece o DropDown List para que você escolha a sua segunda opção. Mas não é o que eu queria, desta forma vai ficar Cadeira, Braço e não Cadeira de Braço. Para uma máquina o uso da vírgulá é muito melhor do que a frase que estou propondo, se servir você já pode parar por ai. Mas digamos que seja obrigatório a frase completa Cadeira de Braço, vamos ver como fazer nosso Token.

Crie uma classe dentro do pacote br.com.softpalm.auto chamada EspacoTokenizer, conforme figura abaixo.

Figura 135 - Project Explorer

Agora vamos criar nosso Tokenizer conforme código abaixo.

1 package br.com.softpalm.auto; 2 3 import android.widget.MultiAutoCompleteTextView.Tokenizer; 4 5 // Vamos herdar de android.widget.MultiAutoCompleteTextView.Tokenizer 6 public class EspacoTokenizer implements Tokenizer { 7 8 // Precisamos sobrescrever 3 métodos, o primeiro está relacionado 9 // com a localicação do final do Token 10 @Override 11 public int findTokenEnd(CharSequence text, int cursor) { 12 int pos = text.toString().indexOf(' ', cursor); 13 return (pos < 0) ? (text.length() - 1) : (pos - 1); 14 } 15 16 // O segundo está relacionado com o início da sequência 17 @Override 18 public int findTokenStart(CharSequence text, int cursor) { 19 int pos = text.toString().lastIndexOf(' ', cursor); 20 return (pos < 0) ? 0 : (pos + 1); 21 }

Page 112: Apostila Android Gratuita

112 Desenvolvendo Aplicações com Java para Android

22 23 // O terceiro deve avaliar a palavra escolhida e escolher 24 // o Token que será usado após 25 @Override 26 public CharSequence terminateToken(CharSequence text) { 27 String textStr = text.toString(); 28 29 // Se o texto excolhido finaliza com espaço então não vamos fazer

nada 30 // caso contrário vamos adicionar um espaço no final 31 if(textStr.endsWith(" ")) 32 return textStr; 33 else 34 return textStr + " "; 35 } 36 }

O método que deverá adicionar nosso Token espaço é o terminateToken() que se uma palavra que não termina com espaço for escolhida vamos adicionar no else.

Agora falta voltar no código da classe Main (que já foi feito) e alterar uma única linha, por motivos de explicação vou recolocar todo o código da classe com um destaque para a linha alterada.

1 package br.com.softpalm.auto; 2 3 import android.app.Activity; 4 import android.os.Bundle; 5 import android.widget.ArrayAdapter; 6 import android.widget.AutoCompleteTextView; 7 import android.widget.MultiAutoCompleteTextView; 8 // Revisão SVN 14 9 public class Main extends Activity { 10 11 public void onCreate(Bundle savedInstanceState) { 12 super.onCreate(savedInstanceState); 13 setContentView(R.layout.main); 14 15 // Criando um Adapter para associar a um array de opções mais

prováveis 16 ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,

android.R.layout.simple_dropdown_item_1line, OPCOES); 17 18 // Resgatando o objeto (definido no XML) 19 AutoCompleteTextView txtAutoComplete =

(AutoCompleteTextView)this.findViewById(R.main.txtAuto); 20 MultiAutoCompleteTextView txtMultiAutoComplete =

(MultiAutoCompleteTextView)this.findViewById(R.main.txtMulti); 21 22 // Passando o Adapter para os dois objetos 23 txtAutoComplete.setAdapter(adapter); 24 txtMultiAutoComplete.setAdapter(adapter); 25 26 // LINHA ALTERADA <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< 27 // Repare que estou fazendo uma instancia de EspacoTokenizer() 28 txtMultiAutoComplete.setTokenizer(new EspacoTokenizer()); 29 } 30 31 private static final String[] OPCOES = new String[] { 32 "Cadeira", "Braço", "Cor", "Encosto", "Mola", "Estofada",

"Azul", "Vermelha" , "Rodinha"

Page 113: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 113

33 }; 34 }

Vamos agora executar a aplicação e ver o seu comportamento. Digite Ca e escolha a opção Cadeira no DropDown List, depois digite de e logo em seguida Br (ver figura abaixo).

Figura 136 - EspacoTokenizer

Repare que ele exibe a segunda opção Braço, escolha e vamos ter nossa frase.

Spinner Este componente possui um nome diferente em cada tecnologia, não vou explicar de imediato o que

ele faz, vou apenas dizer seus nomes em outras tecnologias e vocês já vão associar:

Em Java podemos chamar ele de JComboBox, em Visual Studio .NET chamamos de DropDownList quando estamos programando para Web Application e ComboBox quando estamos desenvolvendo aplicações Windows Applicaton, em HB++ chamamos de ComboBox e em C++ para Palm temos que fazer.

É um controle que permite a seleção de itens de uma lista, porem seu estado adormecido tem a aparência de uma caixa (com a descrição selecionada) associado a um botão, neste botão uma imagem de um triangulo.

Figura 137 - Layout do Spinner

Quando pressionado o Spinner abre uma caixa de seleção com vários itens em forma de lista (ver figura abaixo), basta o usuário selecionar e esta será a opção exibida na descrição.

Figura 138 - Lista de um Spinner

Na Palette procure por Spinner.

Page 114: Apostila Android Gratuita

114 Desenvolvendo Aplicações com Java para Android

Figura 139 - Spinner na Palette

Para fixar o uso do Spinner vamos desenvolver um exemplo com o seu uso e comentar algumas dicas de Usabilidade.

Vamos criar um projeto exemplo, neste projeto o usuário deverá escolher uma palavra de uma lista de palavras. Crie um projeto baseado nas configurações da tabela abaixo.

New Android Project

Project name Exemplo009

Build Target Android 2.2

Application Name Exemplo009

Package name br.com.softpalm.layout.spinner

Create Activity (selecionado) Main

Min SDK Version 8

Adicione um controle Spinner, altere o arquivo main (XML) conforme a listagem abaixo.

1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:orientation="vertical" 4 android:layout_width="fill_parent" 5 android:layout_height="fill_parent" 6 android:background="#ffffff"> 7 <Spinner android:layout_width="match_parent" 8 android:id="@+id/spinner1" 9 android:layout_height="wrap_content"> 10 </Spinner> 11 </LinearLayout>

Agora que adicionamos o Spinner no modelo de design vamos partir para a edição do código fonte da Activity, abra o arquivo Main.java. Edite o código abaixo.

1 package br.com.softpalm.layout; 2 3 import android.app.Activity; 4 import android.os.Bundle; 5 import android.view.View; 6 import android.widget.AdapterView; 7 import android.widget.ArrayAdapter; 8 import android.widget.Spinner; 9 import android.widget.Toast; 10 11 /** 12 * Activity que controla o arquivo main.xml 13 * @author Wellington 14 * 15 * SVN: 16 * 17 * Atenção: o implements da linha abaixo é adicionado para poder

Page 115: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 115

18 * tratar os eventos do Spinner dentro da própria classe 19 * porem é obrigatório implementar os métodos onItemSelected

e 20 * onNothingSelected conforme podem ser observados neste

código 21 */ 22 public class Main extends Activity implements

AdapterView.OnItemSelectedListener{ 23 @Override 24 public void onCreate(Bundle savedInstanceState) { 25 super.onCreate(savedInstanceState); 26 setContentView(R.layout.main); 27 28 // Resgatando a referência do objeto 29 Spinner spinner = (Spinner) findViewById(R.id.spinner1); 30 31 // Criando um Adapter com os itens do array 32 ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,

android.R.layout.simple_dropdown_item_1line, OPCOES); 33 34 // Passando o Adapter com as opções para o Spinner 35 spinner.setAdapter(adapter); 36 37 // Criando o envento Selected 38 spinner.setOnItemSelectedListener(this); 39 } 40 41 /** 42 * Evento que ocorre quando algum item é selecionado 43 */ 44 public void onItemSelected(AdapterView<?> parent, View v, int

position, long id) { 45 // Exibindo a seleção feita pelo usuário 46 Toast.makeText(parent.getContext(), "Você escolheu: " +

OPCOES[position], Toast.LENGTH_LONG).show(); 47 } 48 49 /** 50 * Evento que ocorre quando a lista é aberta mais o usuário não

seleciona nada 51 */ 52 public void onNothingSelected(AdapterView parent) { 53 // Não faça nada 54 } 55 56 // Array montado só para ter as opções 57 private static final String[] OPCOES = new String[] { "Cadeira",

"Braço", "Cor", "Encosto", "Mola", "Estofada", "Azul", "Vermelha" , "Rodinha"};

58 }

Ao executar a aplicação e selecionar um item uma mensagem deverá ser exibida, conforme figura abaixo.

Page 116: Apostila Android Gratuita

116 Desenvolvendo Aplicações com Java para Android

Figura 140 - Spinner com elementos

O evento do Spinner só deve ser usado quando a ação do usuário sobre ele influenciar a tela ou os atributos da classe. Se for uma escolha com posterior ação de salvar (em um botão por exemplo) então pegue o valor somente neste momento. Use o método getSelectedItemPosition().

Spinner s = (Spinner)findViewById(R.id.spinner1); int x = s.getSelectedItemPosition();

Data e Hora A manipulação de Data e Hora é uma tarefa muito complicada, devido a formatação das diferentes

culturas, o que gera sempre uma batalha para analisar a portablidade entre aplicações e repositórios.

Por se tratar de uma plataforma que será utilizada por pessoas para gerenciamento pessoa é natural que tenha vários componentes destinados a manipulação de Data e Hora.

DatePicker Componete destinado a edição de uma data contendo Ano, Mês e Dia. Possui botões grandes, visto

que nesta plataforma não seu usa as famosas “canetinhas” e sim as pontas dos dedos. Na figura abaixo fiz questão de adicionar toda a tela para que se tenha ideia do espaço ocupado pelo componente em sua configuração padrão.

Figura 141 - DatePicker

TimePicker Está evidente que o DatePicker não edita Hora e Minuto (é que em muitas plataformas um núnico

componente edita Data e Hora).

Para editar Hora e Minuto utilizamos o TimePicker, sua aparência é semelhante ao DatePicker conforme podemos observar na figura abaixo.

Page 117: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 117

Figura 142 - DatePicker e TimePicker

Perdemos quase uma tela toda, em tópicos futuros quando abordar formulários vamos aprender a criar formulários só para edição de Data e Hora.

New Android Project

Project name Exemplo010

Build Target Android 2.2

Application Name Exemplo010

Package name br.com.softpalm.layout.date

Create Activity (selecionado) Main

Min SDK Version 8

Vamos começar editando o arquivo XML de layout (main.xml), edite o layout conforme a listagem abaixo.

1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:orientation="vertical" 4 android:layout_width="fill_parent" 5 android:layout_height="fill_parent" 6 android:background="#ffffff"> 7 <DatePicker android:id="@+main/dtpData" 8 android:layout_width="wrap_content" 9 android:layout_height="wrap_content"> 10 </DatePicker> 11 <TimePicker android:id="@+main/pthHora" 12 android:layout_width="wrap_content" 13 android:layout_height="wrap_content"> 14 </TimePicker> 15 <Button android:text="Exibir" 16 android:id="@+main/btnVer" 17 android:layout_width="wrap_content" 18 android:layout_height="wrap_content"> 19 </Button> 20 </LinearLayout>

O objetivo é permitir que o usuário selecione uma data e uma hora e clique no botão, quando clicar vamos exibir uma mensagem com os valores selecionados no DatePicker e TimePicker.

Vamos então editar a Activity relacionada com o arquivo main.xml.

1 package br.com.softpalm.layout.date; 2 3 import android.app.Activity; 4 import android.os.Bundle;

Page 118: Apostila Android Gratuita

118 Desenvolvendo Aplicações com Java para Android

5 import android.view.View; 6 import android.view.View.OnClickListener; 7 import android.widget.Button; 8 import android.widget.DatePicker; 9 import android.widget.TimePicker; 10 import android.widget.Toast; 11 12 /** 13 * Activity que gerencia o arquivo main.xml 14 * @author Wellington 15 * 16 * SVN: 16 17 * 18 */ 19 public class Main extends Activity { 20 /** Called when the activity is first created. */ 21 @Override 22 public void onCreate(Bundle savedInstanceState) { 23 super.onCreate(savedInstanceState); 24 setContentView(R.layout.main); 25 26 // Recuperando objeto Data 27 DatePicker dtpData =

(DatePicker)this.findViewById(R.main.dtpData); 28 29 // Alterando o objeto data para exibir o dia em que um dos

autores nasceu 30 dtpData.updateDate(1979, 05, 12); 31 32 // Resgatando o controle Button e criando um evento par ele 33 Button btnVer = (Button)this.findViewById(R.main.btnVer); 34 btnVer.setOnClickListener(new OnClickListener() { 35 public void onClick(View v) { 36 btnVer_Click(v); 37 } 38 }); 39 } 40 41 /** 42 * Evento que ocorre quando botão é pressionado 43 */ 44 public void btnVer_Click(View v) 45 { 46 // Resgatando a referência 47 DatePicker dtpData =

(DatePicker)this.findViewById(R.main.dtpData); 48 TimePicker pthHora =

(TimePicker)this.findViewById(R.main.pthHora); 49 50 // Utilizando os métodos getMonth(), getDatyOfMonth(), getYear(),

getCurrentHour() e getCurrentMinute 51 // para pegar os valores dos controles alterados pelo usuário 52 Toast.makeText(this, "Data: " + dtpData.getDayOfMonth() + "/" +

dtpData.getMonth() + "/" + dtpData.getYear() + "\nHora: " + pthHora.getCurrentHour() + ":" + pthHora.getCurrentMinute(), 30).show();

53 } 54 }

Page 119: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 119

Comentário do Autor: Senti a falta de um método getDate() e achei estranho o updateDate(), esperava um setDate() para manter o padrão, porem foi fácil o uso.

O resultado da execução da nossa aplicação pode ser vista na figura abaixo.

Figura 143 - DatePicker e TimePiker

CalendarView CalendarView é um Widget desenvolvido para exibir e selecionar uma ou mais datas.

Versão: Este componente só pode ser utilizado a partir da versão 11 da API (Android 3.0).

Figura 144 - CalendarView

Chronometer Classe que implementa um temporizador simples. Iniciamos a contagem a partir da chamada do

método start() e paralisamos a contagem chamando o método stop().

Vamos então criar um cronometro simples, um botão que inicia a contagem e outro que para.

New Android Project

Project name Exemplo011

Build Target Android 2.2

Application Name Exemplo011

Package name br.com.softpalm.layout.date

Create Activity (selecionado) Main

Min SDK Version 8

Vamos começar editando o arquivo XML de layout (main.xml), edite o layout conforme a listagem abaixo.

Page 120: Apostila Android Gratuita

120 Desenvolvendo Aplicações com Java para Android

1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout 3 xmlns:android="http://schemas.android.com/apk/res/android" 4 android:orientation="vertical" 5 android:layout_width="fill_parent" 6 android:layout_height="fill_parent" 7 android:background="#ffffff"> 8 <Chronometer 9 android:text="Chronometer" 10 android:id="@+main/chrCronometro" 11 android:layout_width="wrap_content" 12 android:layout_height="wrap_content" 13 android:background="#000000"> 14 </Chronometer> 15 <Button 16 android:text="Iniciar/Parar" 17 android:id="@+main/btnIniciarParar" 18 android:layout_width="wrap_content" 19 android:layout_height="wrap_content"> 20 </Button> 21 <Button 22 android:text="Zerar Contador" 23 android:id="@+main/btnZerar" 24 android:layout_width="wrap_content" 25 android:layout_height="wrap_content"> 26 </Button> 27 </LinearLayout>

Vamos resgatar as referências dos objetos definidos no arquivo XML e criar os eventos necessário. Lembrando que um botão deve iniciar a contagem se a contagem estiver parada ou parar a contagem caso já esteja iniciada.

Já o segundo botão deve reiniciar a contagem em 00:00.

1 package br.com.softpalm.date; 2 3 import android.app.Activity; 4 import android.os.Bundle; 5 import android.os.SystemClock; 6 import android.view.View; 7 import android.view.View.OnClickListener; 8 import android.widget.Button; 9 import android.widget.Chronometer; 10 11 /** 12 * Activity responsável por gerenciar o arquivo main.xml 13 * @author Wellington 14 * 15 * SVN: 16 */ 17 public class Main extends Activity { 18 /** 19 * Váriavel usada para guardar o status do Cronometro 20 */ 21 private boolean ligado = false; 22 23 @Override 24 public void onCreate(Bundle savedInstanceState) { 25 super.onCreate(savedInstanceState); 26 setContentView(R.layout.main);

Page 121: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 121

27 28 // Fazer as referências para os objetos no XML 29 this.btnIniciarParar =

(Button)this.findViewById(R.main.btnIniciarParar); 30 this.btnZerar = (Button)this.findViewById(R.main.btnZerar); 31 this.chronometer =

(Chronometer)this.findViewById(R.main.chrCronometro); 32 33 // Eventos do botão 34 this.btnIniciarParar.setOnClickListener( new OnClickListener(){ 35 public void onClick(View v) 36 { 37 btnIniciarParar_Click(v); 38 } }); 39 this.btnZerar.setOnClickListener( new OnClickListener(){ 40 public void onClick(View v) 41 { 42 btnZerar_Click(v); 43 } }); 44 } 45 46 public void btnIniciarParar_Click(View v) 47 { 48 // Os métodos Start() e Stop() alteram o status do Cronometro 49 if(ligado) 50 this.chronometer.stop(); 51 else 52 this.chronometer.start(); 53 54 // Comutar o valor apenas 55 ligado = !ligado; 56 } 57 58 public void btnZerar_Click(View v) 59 { 60 this.chronometer.stop(); 61 62 // Zeramos o contador usando stBase() 63 this.chronometer.setBase(SystemClock.elapsedRealtime()); 64 ligado = false; 65 } 66 67 // Objetos 68 Button btnIniciarParar; 69 Button btnZerar; 70 Chronometer chronometer; 71 }

A sequência de imagem abaixo demonstra a funcionalidade da aplicação Exemplo011.

a) clique em iniciar b) depois de um tempo zere o contador

c) contador zerado

Page 122: Apostila Android Gratuita

122 Desenvolvendo Aplicações com Java para Android

Figura 145 - Sequência de telas da aplicação Exemplo011

Imagens e Mídia Por se tratar de um dispositivo voltado a um público que busca entretenimento a plataforma Android

possui vários componentes dedicados a exibição de imagens e mídias.

O uso do vídeo pode ser útil até em aplicações coorporativas como uma Força de Vendas, pense que o cliente esteja com receio de comprar um novo produto, um vídeo sobre o produto pode mudar sua opinião. Pene em um usuário de “primeira viagem”, talvez um vídeo possa explicar partes complexas do sistema.

ImageView ImageView é uma classe que reúne membros destinados a exibição de imagem. Uma boa

ferramenta para exibição de imagens de produtos e serviços para o cliente.

Uma imagem pode ser carregada dentro da própria aplicação como uma Resource ou ser carregado a partir de um caminho dentro do Android, geralmente utilizamos o cartão.

Quando desenvolvia aplicações para plataforma Palm OS (princípio em C++) eu tinha que ter todo o cuidado com a qualidade da imagem, se eu adicionasse imagens com alta qualidade e minha aplicação fosse executada em um equipamento com baixa resolução ocorria um problema. A solução era procurar nas variáveis do sistema a informação sobre resolução e escolher a imagem adequada. Quando conheci a ferramenta da Handheld-Basic vi que esta ao exibir a imagem realizava a validação e procurava a melhor imagem sem precisar de programação por parte do desenvolvedor, mas para isso eu deveria criar as imagens nas mais diferentes resoluções, isso funcionava e era bom.

É difícil desenvolver aplicações quando o host que deverá executar nossa aplicação possui as mais diversas variedades. Como a plataforma Android surge após as plataformas Symbian, Palm OS, Windows CE, etc. esta pode implementar casos de sucesso já ocorrido. A plataforma Android no ponto de vista dos autores deste livro é a plataforma mais adaptada as diversidades, lógico que se sua aplicação requer o recurso GPS e o hardware do cliente não possui, é natural que não funcione.

Você pode organizar os recursos (Resources) do projeto Android baseado em vários critérios de configurações, incluindo a língua, a região, as características da tela, métodos de entrada, etc.. A plataforma Android possui um mecanismo muito robusto para o carregamento dos recursos apropriados em tempo de execução, imagine que precisamos exibir um logo na tela inicial, podemos criar três versões do logo com densidades diferentes, seriam adicionados nas pastas:

TODO: IMAGEM

A pasta drawable-hdpi requeresse a imagens de alta densidade, a pasta drawable-mdpi de média densidade e drawable-hdpi de baixa densidade. Então nossas três versões de logo ficarão em:

/res/drawable-ldpi/meuLogo.png

/res/drawable-mdpi/meuLogo.png

/res/drawable-hdpi/meuLogo.png

Vamos criar um projeto com 3 imagens diferentes, com o mesmo nome e testar em várias densidades diferentes, você deve estar se perguntando o porque ter três imagens diferentes e não três versões da mesma imagem para densidades diferentes, isso porque quero que veja que ele escolhe uma imagem baseado na densidade, se usar imagens parecidas não vamos ver a diferença. Abaixo temos as três imagens.

drawable-ldpi drawable-mdpi drawable-hdpi

Figura 146 - Imagens em densidades diferentes

Vamos então criar um novo projeto conforme a descrição abaixo.

New Android Project

Page 123: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 123

Project name Exemplo012

Build Target Android 2.2

Application Name Exemplo012

Package name br.com.softpalm.layout.image

Create Activity (selecionado) Main

Min SDK Version 8

Vamos então distribuir as imagens acima (ver Figura 146) nas pastas conforme descrito, para isso utilize o Windows Explorer navegando até os diretórios do projeto e colando. Agora é preciso atualizar o projeto no Eclipse, para isso selecione o projeto e clique no botão refresh.

Figura 147 - Atualizando o projeto

Veja que as imagens apareceram.

Figura 148 - Project Explorer

Vamos começar editando o código do arquivo XML de layout (main.xml), edite o layout conforme a listagem abaixo.

1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:orientation="vertical" 4 android:layout_width="fill_parent" 5 android:layout_height="fill_parent" 6 android:background="#ffffff"> 7 <ImageView 8 android:layout_height="wrap_content" 9 android:layout_width="wrap_content" 10 android:src="@drawable/logo" 11 android:id="@+main/imgLogo">

Page 124: Apostila Android Gratuita

124 Desenvolvendo Aplicações com Java para Android

12 </ImageView> 13 </LinearLayout>

Veja que na linha 10 estamos carregando o arquivo logo sem especificar a densidade, durante a execução a aplicação deverá pegar este ID e carregar a versão correta da imagem. Existe também a possibilidade de carregar via código, mais a frente vamos demonstrar. O que já temos é suficiente para demonstrar a troca de imagem baseado na resolução.

Vamos executar a aplicação no emulador e ver qual imagem ele carregou.

Figura 149 - Imagem exibida em baixa densidade

Carregou a imagem de baixa densidade, vou agora demonstrar como configurar a densidade do emulador, abra o Android SDK and AVD Manager conforme figura abaixo.

Figura 150 - Acessando o Android SDK and AVD Manager

Selecione a configuração do seu emulador, vamos editar os parâmetros do emulador.

Figura 151 - Lista de emuladores

Mas lembre-se de fechar o emulador antes, clique no botão editar.

Repare que em Hardware temos a propriedade Abstracted LCD densidty com o valor 120. Vamos alterar para 300 e salvar a configuração.

Figura 152 - Alterando a densidade

Execute novamente a aplicação para carregar o emulador com a nova configuração.

Figura 153 - Imagem exibida em alta densidade

A imagem mudou, isso porque estamos em alta densidade, 300 já é hdpi. Você pode agora ficar alterando estes valores (lembre-se que o padrão para 2.2 é 120) e testando suas imagens.

Agora vamos carregar uma nova imagem (como Resource) através de um evento de um botão.

Page 125: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 125

Vamos começar alterando o arquivo main.xml.

1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:orientation="vertical" 4 android:layout_width="fill_parent" 5 android:layout_height="fill_parent" 6 android:background="#ffffff"> 7 <ImageView 8 android:layout_height="wrap_content" 9 android:layout_width="wrap_content" 10 android:src="@drawable/logo" 11 android:id="@+main/imgLogo"> 12 </ImageView> 13 <Button 14 android:text="Carregar" 15 android:id="@+main/btnCarregar" 16 android:layout_width="wrap_content" 17 android:layout_height="wrap_content"> 18 </Button> 19 </LinearLayout>

Repare que apenas adicionamos um botão, vamos agora editar um evento para o botão, este evento vamos trocar a imagem, para isso adicionei no projeto mais uma imagem, desta vez uma foto que será capaz de assustar baratas tanto em ldpi quanto em hdpi, vou chamar essa foto de wellington.jpg.

O evento do botão será editado na Activity Main.java conforme imagem abaixo.

1 package br.com.softpalm.layout.image; 2 3 import android.app.Activity; 4 import android.os.Bundle; 5 import android.view.View; 6 import android.view.View.OnClickListener; 7 import android.widget.Button; 8 import android.widget.ImageView; 9 10 /** 11 * 12 * @author Wellington 13 * 14 * SVN: 19 15 */ 16 public class Main extends Activity { 17 /** Called when the activity is first created. */ 18 @Override 19 public void onCreate(Bundle savedInstanceState) { 20 super.onCreate(savedInstanceState); 21 setContentView(R.layout.main); 22 23 Button btnCarregar =

(Button)this.findViewById(R.main.btnCarregar); 24 25 btnCarregar.setOnClickListener( new OnClickListener(){ 26 27 public void onClick(View v) 28 { 29 btnCarregar_Click(v); 30 } 31 });

Page 126: Apostila Android Gratuita

126 Desenvolvendo Aplicações com Java para Android

32 } 33 34 public void btnCarregar_Click(View v) 35 { 36 ImageView img = (ImageView) this.findViewById(R.main.imgLogo); 37 38 // Usamos o método setImageResource() par alterar a imagem quando 39 // ela está anexada ao projeto 40 img.setImageResource(R.drawable.wellington); 41 } 42 }

Ao executar a aplicação e clicar no botão você verá que a imagem foi trocada, pronto, primeira aplicação capaz de dar susto em baratas, coloque um doce perto do equipamento e espere que a barata pise no botão, a imagem será trocada e será menos uma.

Vamos voltar a falar sério agora, se você quer desenvolver uma aplicação de força de vendas e quer exibir a foto dos produtos, recomendo que carregue dinamicamente a partir de um cartão. Geralmente o caminho para o cartão interno é /sdcard/ ou se preferir use o cartão externo /extcard/.

Para acessar o sdcard do emulador vou ensinar a utilizar uma Perspectiva nova, não vou entrar em detalhes agora pois vamos ter um capítulo só para ela, chama-se perspectiva DDMS, você já está acostumado a acessar as perspectivas Debug e Java conforme figura abaixo.

Figura 154 - Duas perspectivas

Para acessar a perspectiva DDMS vamos precisar ativar ela, em Window | Open Perspective | DDMS conforme figura abaixo.

Figura 155 - Acessando perspectivas não visíveis

Apareceu a nova opção, conforme figura abaixo.

Figura 156 - Três perspectivas

Vamos agora navegar na estrutura interna do emulador e adicionar a figura wellington.jpg dentro da pasta /sdcard/. Para isso selecione o emulador, clique na aba File Explorer e cole o arquivo na pasta sdcard conforme seqüência abaixo.

Figura 157 - DDMS

Page 127: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 127

Agora sabemos aonde está nossa figura, próximo passo é criar um novo projeto para carregar esta figura quando necessário.

New Android Project

Project name Exemplo013

Build Target Android 2.2

Application Name Exemplo013

Package name br.com.softpalm.layout.image

Create Activity (selecionado) Main

Min SDK Version 8

O arquivo main.xml será igual ao utilizado no projeto anterior, vamos adicionar ele aqui para manter o padrão do livro, você pode copiar e colar se quiser.

1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:orientation="vertical" 4 android:layout_width="fill_parent" 5 android:layout_height="fill_parent" 6 android:background="#ffffff"> 7 <ImageView 8 android:layout_height="wrap_content" 9 android:layout_width="wrap_content" 10 android:src="@drawable/icon" 11 android:id="@+main/imgLogo"> 12 </ImageView> 13 <Button 14 android:text="Carregar" 15 android:id="@+main/btnCarregar" 16 android:layout_width="wrap_content" 17 android:layout_height="wrap_content"> 18 </Button> 19 </LinearLayout>

O código da Activity responsável pela manipulação do arquivo main.xml está descrita abaixo.

1 package br.com.softpalm.layout.image; 2 3 import java.io.File; 4 5 import android.app.Activity; 6 import android.graphics.Bitmap; 7 import android.graphics.BitmapFactory; 8 import android.os.Bundle; 9 import android.view.View; 10 import android.view.View.OnClickListener; 11 import android.widget.Button; 12 import android.widget.ImageView; 13 14 /** 15 * 16 * @author Wellington 17 * 18 * SVN: 19 */ 20 public class Main extends Activity { 21 /** Called when the activity is first created. */ 22 @Override

Page 128: Apostila Android Gratuita

128 Desenvolvendo Aplicações com Java para Android

23 public void onCreate(Bundle savedInstanceState) { 24 super.onCreate(savedInstanceState); 25 setContentView(R.layout.main); 26 27 Button btnCarregar =

(Button)this.findViewById(R.main.btnCarregar); 28 29 btnCarregar.setOnClickListener( new OnClickListener(){ 30 31 public void onClick(View v) 32 { 33 btnCarregar_Click(v); 34 } 35 }); 36 } 37 38 public void btnCarregar_Click(View v) 39 { 40 ImageView img = (ImageView) this.findViewById(R.main.imgLogo); 41 42 // Caminho da imagem, você pode montar dinamicamente 43 // com informações vindas do SQLite que vamos estudar 44 String imgPath = "/sdcard/wellington.jpg"; 45 46 // Cria um File para validar se existe arquivo 47 File imgFile = new File(imgPath); 48 if(imgFile.exists()){ 49 // Criamos um Bitmap, sei que está pensado que é um jpg, mas

funciona 50 Bitmap myBitmap = BitmapFactory.decodeFile(imgPath); 51 52 // Usamos o método setImageBitmap() par alterar a imagem 53 // quando ela está anexada ao projeto 54 img.setImageBitmap(myBitmap); 55 } 56 else 57 { 58 // Imagem padrão, pois não existe a imagem que

procuramos 59 img.setImageResource(R.drawable.icon); 60 } 61 } 62 }

Você pode criar pastas com o rótulo igual ao ID do produto e listar as fotos, se não tiver a pasta então carrega a imagem padrão.

Figura 158 - Exemplo 13

ImageButton Quando programava para plataforma Palm OS a questão “Botão com Imagem” sempre foi algo

complicado de se implementar, geralmente criávamos imagens e aguardávamos o evento Mouse Up sobre a imagem. Isso era ruim, pois o evento clique não é somente composto pelo Mouse Up, ele é composto por Mouse Down e Mouse Up em um determinado intervalo de tempo.

Page 129: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 129

Outra questão interessante está relacionado a Interação Humano Computador, utilizar muitas imagens e com escala reduzida pode confundir usuários de primeira viagem, veja na imagem abaixo que uma ToolBar de botões foi desenvolvida, repare que o segundo elemento (da esquerda para a direita) dá para saber que é um disquete e que provavelmente vai salvar algo. Agora o que significa o nono elemento da barra?

Figura 159 - Toolbar

Outro ponto importante é que o botão com o disquete para uma pessoa com a mesma experiência que os autores do livro entendem como persistência de algo, já para a nova geração disquete não está em seus conhecimentos pois não conviveram, apenas sabem que é algo que se salva, no futuro nem isso será associado.

A plataforma Android possui um problema para botões e componentes muito pequenos e tão acoplados como esta barra, o problema é que não se utiliza canetas para aplicar sobre touchscreen, é a ponta do dedo. Se o usuário não tiver um equipamento bom este terá dificuldades para selecionar uma ação, o que causa certo nervosismo. Não estamos dizendo que você deva evitar o uso, apenas evitar o mau uso destes recursos.

Por padrão o ImageButton realmente é uma junção de botão e imagem, logo terá bordas como um botão e uma imagem dentro, conforme imagem Figura 160 a. Esta imagem é resultado do código baixo.

1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:orientation="vertical" 4 android:layout_width="fill_parent" 5 android:layout_height="fill_parent" 6 android:background="#ffffff" > 7 8 <ImageButton 9 android:layout_width="wrap_content" 10 android:layout_height="wrap_content" 11 android:id="@+id/imageButton1" 12 android:src="@drawable/icon" 13 > 14 </ImageButton> 15 </LinearLayout>

a) Botão com borda b) Botão sem borda

Figura 160 - Estilos de botões

Podemos alterar o estilo do ImageButton de acordo com nessas necessidades, a Figura 160 b é

Page 130: Apostila Android Gratuita

130 Desenvolvendo Aplicações com Java para Android

resultado da listagem abaixo.

1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:orientation="vertical" 4 android:layout_width="fill_parent" 5 android:layout_height="fill_parent" 6 android:background="#ffffff" > 7 8 <ImageButton 9 android:layout_width="wrap_content" 10 android:layout_height="wrap_content" 11 android:id="@+id/imageButton1" 12 android:src="@drawable/icon" 13 android:background="#ffffff" 14 android:layout_marginTop="5dip" 15 android:layout_marginBottom="5dip" 16 > 17 </ImageButton> 18 </LinearLayout>

Três propriedades foram adicionadas, background que significa cor de fundo, marginTop e marginBottom definem as margens do controle.

Gallery Gallery é um widget que exibe uma lista de imagens na horizontal na qual o usuário pode interagir

rolando. Na figura abaixo temos várias imagens, para visualizar as demais basta rolar com as mãos e as imagens se movimentarão.

Esse componente é ideal para exibir várias imagens de um produto.

Figura 161 - Gallery

Porem a construção da aplicação não é tão trivial quanto as demais anteriores, requer um pouco mais de conhecimento sobre o ambiente. Então vamos iniciar um novo projeto.

New Android Project

Project name Exemplo014

Build Target Android 2.2

Application Name Exemplo014

Package name br.com.softpalm.layout.image

Create Activity (selecionado) Main

Min SDK Version 8

O arquivo main.xml deve ser editado conforme a listagem abaixo.

Page 131: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 131

1 <?xml version="1.0" encoding="utf-8"?> 2 <Gallery xmlns:android="http://schemas.android.com/apk/res/android" 3 android:id="@+main/gllImagens" 4 android:layout_width="fill_parent" 5 android:layout_height="fill_parent" 6 android:background="#ffffff"> 7 </Gallery>

Agora vamos começar com algumas particularidades, vamos criar um arquivo resource XML que deve definir um atributo, par isso clique com o botão direito do mouse sobre e escolha New | Other conforme figura abaixo.

Figura 162 - Adicionando um arquivo XML

Escolha Android XML File conforme figura abaixo.

Figura 163 - Android XML File

O nome deste arquivo deverá ser attrs.xml, salve e entre no editor para editar seu conteúdo, utilize para isso a listagem abaixo.

8 <?xml version="1.0" encoding="utf-8"?> 9 <resources> 10 <declare-styleable name="Exemplo014"> 11 <attr name="android:galleryItemBackground" /> 12 </declare-styleable> 13 </resources>

Este é um recurso personalizado pode ser aplicado a um layout. Neste caso, será aplicado aos itens individuais colocados no Gallery. A tag <attr/> define um atributo específico para o aplicativo, e neste caso, refere-se a um atributo existente na plataforma chamado galleryItemBackground, que define um estilo de borda para os itens da galeria. Na próxima etapa, você verá como este atributo é

Page 132: Apostila Android Gratuita

132 Desenvolvendo Aplicações com Java para Android

referenciado e, posteriormente, aplicadas a cada item na galeria

Precisamos agora adicionar quatro imagens nas pastas de resources drawable, vou utilizar as seguintes imagens JPG:

Imagem

Nome Imagem1 Imagem2 Imagem3 Imagem4

Quando trabalhamos com a caixa de seleção utilizamos um Adapter do próprio ambiente, adicionamos ao Adapter a lista de strings. Agora vamos criar nosso próprio Adapter pois temos mais detalhes para customizar.

Crie uma classe nova chamada ImageAdapter e edite o código desta conforme a listagem abaixo.

1 package br.com.softpalm.layout; 2 3 import android.content.Context; 4 import android.content.res.TypedArray; 5 import android.view.View; 6 import android.view.ViewGroup; 7 import android.widget.BaseAdapter; 8 import android.widget.Gallery; 9 import android.widget.ImageView; 10 11 /** 12 * 13 * @author Wellington 14 * 15 */ 16 public class ImageAdapter extends BaseAdapter { 17 int galleryItemBackground; 18 19 //Interface com as informações globais do ambiente da aplicação. 20 // Esta é uma classe abstrata, cuja implementação é fornecida pelo

sistema Android. 21 // Ele permite acesso a aplicações específicas recursos e classes. 22 private Context context; 23 24 // Um array de referências para resources 25 private Integer[] resourceId = { 26 R.drawable.imagem1, 27 R.drawable.imagem2, 28 R.drawable.imagem3, 29 R.drawable.imagem4 30 }; 31 32 // O construtor deverá receber o context para recuperar informações 33 // do ambiente, em especial galleryItemBackground 34 public ImageAdapter(Context context) { 35 this.context = context; 36 37 // Pegando o array de atributos de um resource (ver listagem

attrs.xml)

Page 133: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 133

38 TypedArray array = context.obtainStyledAttributes(R.styleable.Exemplo014);

39 40 // Obtendo um id de resource que está no atributo 41 galleryItemBackground = array.getResourceId(

R.styleable.Exemplo014_android_galleryItemBackground, 0); 42 43 array.recycle(); 44 } 45 46 public int getCount() { 47 return resourceId.length; 48 } 49 50 public Object getItem(int position) { 51 return position; 52 } 53 54 public long getItemId(int position) { 55 return position; 56 } 57 /** 58 * Retorna uma View que será exibida a imagem, vamos então 59 * retornar uma ImageView 60 */ 61 public View getView(int position, View convertView, ViewGroup

parent) { 62 ImageView imageView = new ImageView(this.context); 63 64 imageView.setImageResource(resourceId[position]); 65 imageView.setLayoutParams(new Gallery.LayoutParams(120, 120)); 66 imageView.setScaleType(ImageView.ScaleType.FIT_XY); 67 imageView.setBackgroundResource(galleryItemBackground); 68 69 return imageView; 70 } 71 }

Veja que no getView() estou apenas retornando uma ImageView, se fosse preciso eu poderia criar uma View composta de vários componentes gráficos e retornar. Se as imagens estão vindo de um banco ou de um cartão SD então é na linha 64 que você deverá alterar para carregar a imagem e anexar ao ImageView.

Está faltando somente editar nossa Activity responsável por gerenciar o arquivo main.xml, abra o arquivo Main.java e codifique o código abaixo.

1 package br.com.softpalm.layout; 2 3 import android.app.Activity; 4 import android.os.Bundle; 5 import android.view.View; 6 import android.widget.AdapterView; 7 import android.widget.AdapterView.OnItemClickListener; 8 import android.widget.Gallery; 9 import android.widget.Toast; 10 11 /** 12 * @author Wellington 13 * 14 * SVN:

Page 134: Apostila Android Gratuita

134 Desenvolvendo Aplicações com Java para Android

15 */ 16 public class Main extends Activity { 17 /** Called when the activity is first created. */ 18 @Override 19 public void onCreate(Bundle savedInstanceState) { 20 super.onCreate(savedInstanceState); 21 setContentView(R.layout.main); 22 23 Gallery g = (Gallery) findViewById(R.main.gllImagens); 24 25 // Assim como nos Lists é um Adapter que exibe as opções e o 26 // layout das opções, vamos construir nosso próprio adapter 27 // para ober o resultado que procuramos 28 g.setAdapter(new ImageAdapter(this)); 29 30 // Se clicar sobre uma imagem vamos exibir um texto 31 g.setOnItemClickListener(new OnItemClickListener() { 32 public void onItemClick(AdapterView parent, View v, int

position, long id) { 33 gllImagens_Click(parent, v, position, id); 34 } 35 }); 36 } 37 38 public void gllImagens_Click(AdapterView parent, View v, int

position, long id) 39 { 40 // Vamos apenas exibir a posição, mas seria interessante 41 // se fosse ampliada a imagem através do auxílio de um segundo

formulário 42 Toast.makeText(this, "" + position, Toast.LENGTH_SHORT).show(); 43 44 } 45 }

Ao executar a aplicação você poderá ver as imagens, corra o dedo sobre a tela para a horizontal como se estivesse passando uma página, veja que as imagens se movimentam.

Se você precisar exibir a imagem ampliada pode alterar o método gllImagens_Click(), na qual em vez de exibir o Toast você pode exibir um segundo formulário com a imagem ampliada.

Listas e Tabelas Um ponto forte na plataforma Android é a variedade de elementos de interface, lógico que se

comparado com a plataforma Palm OS ou Windows Mobile, também o que podemos esperar de uma plataforma que nasce após anos do surgimento da plataforma móvel.

Um grupo de controles que são muito usados são os de listagem, isso porque tudo temos que listar para escolha do usuário, evite fazer o usuário ficar digitando, sempre proponha algo para se selecionar, e se não tiver dê a oportunidade do usuário criar opções na lista.

ListView No nosso próximo exemplo vamos exibir uma lista simples, de uma única coluna apenas com

nomes.

Atenção: Se tiver que usar mais de uma coluna de texto use o GridView, mesmo que o ListView possa atender a esta necessidade.

O ListView é o componente ideal, simples e de fácil manipulação exibe uma coluna única, geralmente 6 itens por tela, então nada de fazer lista com mais de 60 elementos. Neste nosso exemplo vamos listar as equipes que “Ayrton Senna” competiu. Vamos ver se você é brasileiro.

Crie o Projeto conforme tabela abaixo.

Page 135: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 135

New Android Project

Project name Exemplo016

Build Target Android 2.2

Application Name Exemplo016

Package name br.com.softpalm.layout.lista

Create Activity (selecionado) Main

Min SDK Version 8

Agora vamos adicionar um ListView na interface main.xml conforme listagem abaixo.

1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:orientation="vertical" 4 android:layout_width="fill_parent" 5 android:layout_height="fill_parent"> 6 7 <ListView 8 android:layout_height="wrap_content" 9 android:id="@+main/lstEquipes" 10 android:layout_width="match_parent"> 11 </ListView> 12 </LinearLayout>

Agora vamos editar o arquivo de código associado, abra o arquivo Main.java e edite o código abaixo.

1 package br.com.softpalm.layout.lista; 2 3 import android.app.Activity; 4 import android.os.Bundle; 5 import android.view.View; 6 import android.widget.AdapterView; 7 import android.widget.AdapterView.OnItemClickListener; 8 import android.widget.ArrayAdapter; 9 import android.widget.ListView; 10 import android.widget.Toast; 11 // SVN: 20 12 public class Main extends Activity { 13 14 // Equipes que tiveram o prazer de trabalhar com Ayrton Senna 15 private String[] equipes = { "Toleman", "Lotus", "McLaren", "Williams"

}; 16 ListView lstEquipes; 17 18 @Override 19 public void onCreate(Bundle savedInstanceState) { 20 super.onCreate(savedInstanceState); 21 setContentView(R.layout.main); 22 23 lstEquipes = (ListView) this.findViewById(R.main.lstEquipes); 24 25 // Para adicionar valores no ListView você vai precisar de um

Adapter 26 // dessa vez vou usar o Adapter padrão, mas no próximo exemplo 27 // vamos criar nosso próprio adapter 28 lstEquipes.setAdapter(new ArrayAdapter<String>(this, 29 android.R.layout.simple_list_item_1,

Page 136: Apostila Android Gratuita

136 Desenvolvendo Aplicações com Java para Android

equipes)); 30 31 // Criando o evento, daqui para baixo já estamos carecas de saber

como funciona 32 lstEquipes.setOnItemClickListener(new OnItemClickListener() { 33 @Override 34 public void onItemClick(AdapterView<?> a, View v, int

position, 35 long id) { 36 lista_ItemClick(v, position); 37 } 38 }); 39 } 40 41 public void lista_ItemClick(View v, int position) 42 { 43 Toast.makeText(Main.this, "Equipe: " +

lstEquipes.getItemAtPosition(position), 300).show(); 44 } 45 }

Você pode executar a aplicação, clique nos itens que deverá exibir uma mensagem. Agora digamos que você queira abstrair os itens de uma fonte não fixa, por exemplo uma base SQLite, HTTP/WebService, arquivo txt, etc..

Vou demonstrar como alterar esta classe Main.java (revisão svn 20), vamos alterar a forma de carregamento utilizando o método Add.

1 package br.com.softpalm.layout.lista; 2 3 import android.app.Activity; 4 import android.os.Bundle; 5 import android.view.View; 6 import android.widget.AdapterView; 7 import android.widget.AdapterView.OnItemClickListener; 8 import android.widget.ArrayAdapter; 9 import android.widget.ListView; 10 import android.widget.Toast; 11 12 public class Main extends Activity { 13 14 ListView lstEquipes; 15 16 @Override 17 public void onCreate(Bundle savedInstanceState) { 18 super.onCreate(savedInstanceState); 19 setContentView(R.layout.main); 20 21 lstEquipes = (ListView) this.findViewById(R.main.lstEquipes); 22 23 // Repare que não estamos passando um array, estamos apenas

criando um Adapter 24 ArrayAdapter<String> array = new ArrayAdapter<String>(this, 25 android.R.layout.simple_list_item_1); 26 27 lstEquipes.setAdapter(array); 28 29 // Aqui você vai fazer um laço (for, while, do...while) em alguma

fonte de dados e usar o método Add do adapter para adicionar, vou aqui criar 4 Adds apenas para ilustrar, no capítulo de SQLite vamos usar novamente porem

Page 137: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 137

dentro de um laço 30 array.add("Toleman"); 31 array.add("Lotus"); 32 array.add("McLaren"); 33 array.add("Williams"); 34 35 // Criando o evento, daqui para baixo já estamos carecas de saber

como funciona 36 lstEquipes.setOnItemClickListener(new OnItemClickListener() { 37 @Override 38 public void onItemClick(AdapterView<?> a, View v, int

position, 39 long id) { 40 lista_ItemClick(v, position); 41 } 42 }); 43 } 44 45 public void lista_ItemClick(View v, int position) 46 { 47 Toast.makeText(Main.this, "Equipe: " +

lstEquipes.getItemAtPosition(position), 300).show(); 48 } 49 }

Execute a aplicação (revisão SVN 21) e veja que terá o mesmo resultado do exemplo em que usamos um array de strings.

Agora vamos melhorar nosso exemplo, digamos que você queira exibir uma seleção, através de um

check simples. Temos duas alternativas a opção de exibir uma imagem de um círculo ou um

quadrado . A opção do círculo descreve implicitamente que só pode haver um selecionado na lista e a opção do quadrado descreve que muitos podem ser selecionados.

Vamos alterar o código Main.java e vamos usar seleção simples com a imagem do círuculo.

1 package br.com.softpalm.layout.lista; 2 3 import android.app.Activity; 4 import android.os.Bundle; 5 import android.view.View; 6 import android.widget.AdapterView; 7 import android.widget.AdapterView.OnItemClickListener; 8 import android.widget.ArrayAdapter; 9 import android.widget.ListView; 10 import android.widget.Toast; 11 12 public class Main extends Activity { 13 // Revisão SVN: 22 14 ListView lstEquipes; 15 16 @Override 17 public void onCreate(Bundle savedInstanceState) { 18 super.onCreate(savedInstanceState); 19 setContentView(R.layout.main); 20 21 lstEquipes = (ListView) this.findViewById(R.main.lstEquipes); 22 23 // A opção simple_list_item_single_choice no construtor abaixo 24 // cria uma view para cada item com um objeto circular

Page 138: Apostila Android Gratuita

138 Desenvolvendo Aplicações com Java para Android

25 // que representa uma seleção simples (no máximo 1 elemento) 26 ArrayAdapter<String> array = new ArrayAdapter<String>(this, 27 android.R.layout.simple_list_item_single_choice); 28 29 lstEquipes.setAdapter(array); 30 array.add("Toleman"); 31 array.add("Lotus"); 32 array.add("McLaren"); 33 array.add("Williams"); 34 35 // A linha abaixo é muito importante, não adianta somente 36 // escolher o valor simple_list_item_single_choice no construtor 37 // do Adapter, você precisa informar ao list que seu modo será 38 // seleção simples (no máximo 1 elemento) 39 lstEquipes.setChoiceMode(ListView.CHOICE_MODE_SINGLE); 40 41 42 lstEquipes.setOnItemClickListener(new OnItemClickListener() { 43 @Override 44 public void onItemClick(AdapterView<?> a, View v, int

position, 45 long id) { 46 lista_ItemClick(v, position); 47 } 48 }); 49 } 50 51 public void lista_ItemClick(View v, int position) 52 { 53 Toast.makeText(Main.this, "Equipe: " +

lstEquipes.getItemAtPosition(position), 300).show(); 54 } 55 }

Execute a aplicação, escolha um item, agora escolha outro. Veja que o primeiro é desmarcado, isso porque ele somente aceita seleção simples.

Nosso próximo passo é transformar este exemplo em seleção múltipla, para isso vamos usar a imagem do quadrado que descreve implicitamente ao usuário que ele pode selecionar mais de um elemento.

1 package br.com.softpalm.layout.lista; 2 3 import android.app.Activity; 4 import android.os.Bundle; 5 import android.view.View; 6 import android.widget.AdapterView; 7 import android.widget.AdapterView.OnItemClickListener; 8 import android.widget.ArrayAdapter; 9 import android.widget.ListView; 10 import android.widget.Toast; 11 12 public class Main extends Activity { 13 // Revisão SVN: 23 14 ListView lstEquipes; 15 16 @Override 17 public void onCreate(Bundle savedInstanceState) { 18 super.onCreate(savedInstanceState); 19 setContentView(R.layout.main);

Page 139: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 139

20 21 lstEquipes = (ListView) this.findViewById(R.main.lstEquipes); 22 23 // A opção simple_list_item_multiple_choice no construtor abaixo 24 // cria uma view para cada item com um objeto quadrado 25 // que representa uma seleção múltipla 26 ArrayAdapter<String> array = new ArrayAdapter<String>(this, 27

android.R.layout.simple_list_item_multiple_choice); 28 29 lstEquipes.setAdapter(array); 30 array.add("Toleman"); 31 array.add("Lotus"); 32 array.add("McLaren"); 33 array.add("Williams"); 34 35 // A linha abaixo é muito importante, não adianta somente 36 // escolher o valor simple_list_item_multiple_choice no

construtor 37 // do Adapter, você precisa informar ao list que seu modo será 38 // seleção múltipla 39 lstEquipes.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); 40 41 42 lstEquipes.setOnItemClickListener(new OnItemClickListener() { 43 @Override 44 public void onItemClick(AdapterView<?> a, View v, int

position, 45 long id) { 46 lista_ItemClick(v, position); 47 } 48 }); 49 } 50 51 public void lista_ItemClick(View v, int position) 52 { 53 Toast.makeText(Main.this, "Equipe: " +

lstEquipes.getItemAtPosition(position), 300).show(); 54 } 55 }

Execute a aplicação, selecione vários itens e veja que ele não desmarca, isso porque o controle aceita seleção múltipla.

ExpandableListView Vimos neste capítulo como criar listas simples, porem existem casos em que precisamos criar listas

e sub-listas, um exemplos:

• Uma lista de computadores em que dá para se ver os itens como lista;

• Uma lista de carros com descrição dos acessórios em lista;

• Uma lista de produtos com uma sub-lista de alternativas concorrente.

A interface seria semelhante a imagem abaixo.

Page 140: Apostila Android Gratuita

140 Desenvolvendo Aplicações com Java para Android

No exemplo acima eu criei uma lista principal (chamada grupo) que tem os itens Família e Animais.

Cada um elemento da lista principal possui uma lista secundária chamadas de filhos. Na figura acima podemos ver que o elemento 0 da lista principal foi pressionado abrindo 5 elementos da lista secundária. Já o elemento 1 da lista principal encontra-se recolhido.

Gosto sempre de demonstrar um exemplo prático e funcional, então vamos iniciar um novo projeto.

New Android Project

Project name Exemplo015

Build Target Android 2.2

Application Name Exemplo015

Package name br.com.softpalm.layout.lista

Create Activity (selecionado) Main

Min SDK Version 8

Como de costume vamos implementar a interface, ou seja, o arquivo main.xml de acordo com a listagem abaixo.

1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:orientation="vertical" 4 android:layout_width="fill_parent" 5 android:layout_height="fill_parent" 6 android:background="#ffffff"> 7 <ExpandableListView 8 android:id="@+main/expLista" 9 android:layout_height="wrap_content" 10 android:layout_width="match_parent"> 11 </ExpandableListView> 12 </LinearLayout>

O exemplo é simples, apenas estamos adicionando um elemento ExpandableListView, nenhum segredo.

Agora o próximo passo é o segredo do objeto, vamos criar uma classe que vai controlar o comportamento e a aparência da lista, como sempre ensino a criar estas classes que herdam de Adapter para que o leitor conheça o poder do controle.

Crie uma classe e adicione ao pacote principal, chame este classe de “MyExpandableListAdapter” e codifique a listagem abaixo.

1 package br.com.softpalm.lista; 2 3 import android.app.Activity; 4 import android.graphics.Color; 5 import android.graphics.Typeface; 6 import android.view.Gravity;

Page 141: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 141

7 import android.view.View; 8 import android.view.ViewGroup; 9 import android.widget.AbsListView; 10 import android.widget.BaseExpandableListAdapter; 11 import android.widget.TextView; 12 13 public class MyExpandableListAdapter extends BaseExpandableListAdapter 14 { 15 // Vamos criar um objeto Activity na qual possui o objeto de interface 16 public Activity main; 17 18 // ATENÇÃO: Neste exemplo vou adicionar os dados em um array mas você

pode extrair dados de uma base de dados 19 // Vamos criar um Array com os itens famílha e um de animais, 20 // esses dois grupos deverão conter elementos 21 private String[] groups = { "Família", "Animais" }; 22 23 // Vamos criar agora uma madriz de 2xN, 2 pois temos dois grupos 24 private String[][] children = { 25 { "Wallace", "Wellington", "Wanderson", "Jordelina", "José"

}, 26 { "Pipinho", "Katy Maria", "Betão", "Penelopinha",

"Mimizão", "Meuzinho" } 27 }; 28 29 // Construtor 30 public MyExpandableListAdapter(Main main) 31 { 32 this.main = main; 33 } 34 35 // Retorna um elemento da matriz dado o grupo e a posição do filho 36 public Object getChild(int groupPosition, int childPosition) { 37 return children[groupPosition][childPosition]; 38 } 39 40 // Retorna a posição do filho, obrigatório pois estamos 41 // herdando de BaseExpandableListAdapter 42 public long getChildId(int groupPosition, int childPosition) { 43 return childPosition; 44 } 45 46 // Número de filhos em um grupo 47 public int getChildrenCount(int groupPosition) { 48 return children[groupPosition].length; 49 } 50 51 // Retorna uma TextView para montagem da lista 52 // então nossa lista será composta por TextView 53 public TextView getGenericView() { 54 // LayoutParams é um objeto utilizado para passar parâmetros

para o layout MATCH_PARENT é o tamanho do elemento, utilizado a partir da API 8 neste caso vamos usar tamanho 25, mais lembre-se que quanto maior

55 // lista menos elementos porem quanto menor fica mais difícil selecionar

56 AbsListView.LayoutParams lp = new AbsListView.LayoutParams( 57 ViewGroup.LayoutParams.MATCH_PARENT, 25); 58

Page 142: Apostila Android Gratuita

142 Desenvolvendo Aplicações com Java para Android

59 // Cria a TextView para a Activity e passa os parametros 60 TextView textView = new TextView(main); 61 textView.setLayoutParams(lp); 62 63 // Vamos centralizar o texto 64 textView.setGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT); 65 66 // dar 5 pixels para a esquerda para não colar na tela 67 textView.setPadding(5, 0, 0, 0); 68 return textView; 69 } 70 71 // Cada elemento é uma TextView que por sua vez herda de View 72 // neste exemplo apenas retornamos o próprio TextView, você pode 73 // customizar esta view e adicionar ImageView entre outros

elementos 74 // gráficos 75 public View getChildView(int groupPosition, int childPosition,

boolean isLastChild, View convertView, ViewGroup parent) { 76 77 // Pega o TextView genérico 78 TextView textView = getGenericView(); 79 80 // Altera as propriedades para os elementos filhos (matriz) 81 textView.setPadding(30, 0, 0, 0); 82 textView.setText(getChild(groupPosition,

childPosition).toString()); 83 textView.setTextColor(Color.BLUE); 84 return textView; 85 } 86 87 // Retorna um grupo dado sua posição no array 88 public Object getGroup(int groupPosition) { 89 return groups[groupPosition]; 90 } 91 92 // Retorna o numero de grupos existentes no array de grupos 93 public int getGroupCount() { 94 return groups.length; 95 } 96 97 // Retorna o numero da posição do grupo 98 public long getGroupId(int groupPosition) { 99 return groupPosition; 100 } 101 102 // Retorna uma View para o grupo, vimos que existe o getChildView 103 // esse método faz a mesma coisa porem par grupos, você pode 104 // querer ter um layout diferente para grupo 105 public View getGroupView(int groupPosition, boolean isExpanded, View

convertView, ViewGroup parent) { 106 TextView textView = getGenericView(); 107 108 // Para manter o layout diferente vou exibir o número de filhos 109 textView.setText(getGroup(groupPosition).toString() + " (" +

getChildrenCount(groupPosition) + ")"); 110 111 // Será vermelho

Page 143: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 143

112 textView.setTextColor(Color.RED); 113 textView.setTextSize(14); 114 115 // Terá a fonte em negrito 116 textView.setTypeface(Typeface.DEFAULT, Typeface.BOLD); 117 return textView; 118 } 119 120 // Todos podem ser selecionados 121 public boolean isChildSelectable(int groupPosition, int

childPosition) { 122 return true; 123 } 124 public boolean hasStableIds() { 125 return true; 126 } 127 }

Criamos primeiro a classe MyExpandableListAdapter pois precisamos de uma instancia desta classe no código da classe Main.java. Abra o arquivo Main.java e edite conforme listagem abaixo.

1 package br.com.softpalm.lista; 2 3 import android.app.Activity; 4 import android.os.Bundle; 5 import android.view.View; 6 import android.widget.ExpandableListAdapter; 7 import android.widget.ExpandableListView; 8 import android.widget.ExpandableListView.OnChildClickListener; 9 import android.widget.ExpandableListView.OnGroupClickListener; 10 import android.widget.Toast; 11 12 public class Main extends Activity { 13 14 // Criamos um objeto MyExpandableListAdapter 15 ExpandableListAdapter mAdapter; 16 17 @Override 18 public void onCreate(Bundle savedInstanceState) { 19 super.onCreate(savedInstanceState); 20 setContentView(R.layout.main); 21 22 // Fazemos a instancia passando esta activity 23 mAdapter = new MyExpandableListAdapter(this); 24 25 // Pegamos a referência para o objeto na interface 26 ExpandableListView expLista =

(ExpandableListView)findViewById(R.main.expLista); 27 28 // Passamos o adapter para este objeto de interface 29 expLista.setAdapter(mAdapter); 30 31 // Criamos o evento Click para os itens da lista secundária

(filhos) 32 expLista.setOnChildClickListener(new OnChildClickListener() { 33 34 @Override 35 public boolean onChildClick(ExpandableListView parent, View

v, int groupPosition, int childPosition, long id)

Page 144: Apostila Android Gratuita

144 Desenvolvendo Aplicações com Java para Android

36 { 37 return exp_ChildClick(parent, v, groupPosition,

childPosition, id); 38 } 39 }); 40 41 // Criamos o evento Click para os itens da lista principal

(grupos) 42 expLista.setOnGroupClickListener(new OnGroupClickListener() { 43 44 @Override 45 public boolean onGroupClick(ExpandableListView parent, View

v, int groupPosition, long id) { 46 47 return exp_GroupClick(parent, v, groupPosition, id); 48 } 49 }); 50 } 51 52 // Apenas para exibir uma mensagem 53 public boolean exp_ChildClick(ExpandableListView parent, View v, int

groupPosition, int childPosition, long id) 54 { 55 Toast.makeText(this, "Lista Secundária\r\n\r\n" + parent + ",\r\n

" + v + ",\r\n (" + groupPosition + "|" + childPosition + "),\r\n " + id, 500).show();

56 57 // Nenhum evento mais deve ocorrer para o click no filho 58 return true; 59 } 60 61 public boolean exp_GroupClick(ExpandableListView parent, View v, int

groupPosition, long id) 62 { 63 Toast.makeText(this, "Lista Primária\r\n\r\n" + parent + ",\r\n "

+ v + ",\r\n " + groupPosition + ",\r\n " + id, 500).show(); 64 65 // Muito importante, estamos retornado false pois quer dizer 66 // que o evento não deve ser parado, se colocar true a lista 67 // de filhos não será aberta, faça o teste 68 return false; 69 } 70 }

Você pode usar o Adapter criado aqui em qualquer tela, pois toda interface herda de Ativity, talvez a sua única alteração é no carregamento do Array e da Matriz com os elementos. Sei que não parece tão simples como deveria ser (se comparado com os ambientes Microsoft) mas lembre-se que é uma API que está em evolução.

GridView

GridView é um componente que permite exibir linhas e colunas, imagine uma planilha Excel. Ideal para exibir informações do tipo (são apenas alguns exemplos):

• Lista de produtos;

• Vendas realizadas;

• Produtos adquiridos;

Quando me deparei com o GridView na plataforma Android encontrei um componente rico e flexível, porem também me deparei com a complexidade de programação, tanto que neste tópico vou criar vários projetos para deixar bem claro como manipular este componente.

Page 145: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 145

Nosso primeiro exemplo será uma aplicação com um GridView que deverá ter três colunas (Código, Descrição e Valor) no qual vou exibir alguns produtos.

New Android Project

Project name Exemplo017

Build Target Android 2.2

Application Name Exemplo017

Package name br.com.softpalm.layout.grid

Create Activity (selecionado) Main

Min SDK Version 8

Se você programa em Delphi ou alguma linguagem de alto nível da Microsoft está acostumado a clicar com o botão direito do mouse sobre o DataGrid (GridView) e editar as colunas. Aqui na plataforma Android vamos ter que criar (para este exemplo, existem formas mais complexas que não utilizam XML) um arquivo XML que deverá ter três TextViews, um para cada coluna (Código, Descrição e Preço).

Veja na imagem abaixo que na barra existe um botão que adiciona um arquivo XML (ver imagem abaixo).

Uma nova janela será aberta, digite no campo File o nome row.xml e finalize o processo, repare que

em Layout será criado um arquivo row.xml (ver figura abaixo).

Selecione o novo arquivo e entre no editor XML conforme imagem abaixo.

Vamos criar um LinearLayout (que será discutido no futuro) com três TextViews, repare que os IDs

revelam quais colunas vamos exibir.

1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout 3 xmlns:android="http://schemas.android.com/apk/res/android" 4 android:paddingTop="4dip" 5 android:paddingBottom="6dip" 6 android:layout_width="fill_parent" 7 android:layout_height="wrap_content" 8 android:orientation="horizontal"> 9 10 <TextView android:id="@+row/CODIGO_CELL" 11 android:layout_width="50dip" 12 android:textColor="#000000" 13 android:layout_height="wrap_content"/>

Page 146: Apostila Android Gratuita

146 Desenvolvendo Aplicações com Java para Android

14 15 <TextView android:id="@+row/DESCRICAO_CELL" 16 android:layout_width="wrap_content" 17 android:textColor="#000000" 18 android:layout_height="wrap_content"

android:layout_weight="1"/> 19 20 <TextView android:id="@+row/VALOR_CELL" 21 android:layout_width="60dip" 22 android:textColor="#000000" 23 android:gravity="right" 24 android:layout_height="wrap_content"

android:layout_weight="1"/> 25 </LinearLayout>

Agora vamos editar o arquivo main.xml que deverá conter o GridView, para isso utilize a listagem abaixo.

1 <?xml version="1.0" encoding="utf-8"?> 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 3 android:orientation="vertical" 4 android:layout_width="fill_parent" 5 android:layout_height="fill_parent" 6 android:background="#ffffff"> 7 <GridView 8 android:id="@+main/grdLista" 9 android:layout_width="match_parent" 10 android:layout_height="wrap_content"> 11 </GridView> 12 </LinearLayout>

Repare que adicionamos um GridView porem não fizemos nenhuma referência ao row.xml, mas se o row.xml deverá ser exibido dentro do GridView como isso vai funcionar? Simples, o relacionamento entre o GridView e o row.xml será feito pelo intermediário “Adapter”, novamente trabalhando com Adapter, porem desta vez vamos usar um que já existe.

Vamos então alterar a Activity que controla o arquivo main.xml, abra o arquivo Main.java e edite o código abaixo.

1 package br.com.softpalm.grid; 2 3 import java.util.ArrayList; 4 import java.util.HashMap; 5 6 import android.app.Activity; 7 import android.os.Bundle; 8 import android.view.View; 9 import android.widget.AdapterView; 10 import android.widget.AdapterView.OnItemClickListener; 11 import android.widget.GridView; 12 import android.widget.SimpleAdapter; 13 import android.widget.Toast; 14 15 // Saiba mais sobre coleções de dados 16 // (1) =

(http://download.oracle.com/javase/1.4.2/docs/api/java/util/ArrayList.html) 17 // (2) =

(http://download.oracle.com/javase/1.4.2/docs/api/java/util/HashMap.html) 18 // Revisão SVN: 24 19 public class Main extends Activity { 20

Page 147: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 147

21 GridView grdLista; 22 @Override 23 public void onCreate(Bundle savedInstanceState) { 24 super.onCreate(savedInstanceState); 25 setContentView(R.layout.main); 26 27 grdLista = (GridView) findViewById(R.main.grdLista); 28 29 // Vamos criar um ArrayList (1) e os elementos deste ArrayList 30 // serão do tipo HashMap (2) 31 ArrayList<HashMap<String, String>> mylist = new

ArrayList<HashMap<String, String>>(); 32 33 // Vamos criar a primeira linha, se você quiser pode carregar 34 // dados de um SQLite e fazer um laço de repetição 35 HashMap<String, String> map = new HashMap<String, String>(); 36 map.put("codigo", "108"); 37 map.put("descricao", "Antena Yagui 8 elementos"); 38 map.put("valor", "5,60"); 39 mylist.add(map); 40 41 // Criar mais um só para exibir uma lista com 2 itens 42 map = new HashMap<String, String>(); 43 map.put("codigo", "110"); 44 map.put("descricao", "Antena Yagui 10 elementos"); 45 map.put("valor", "10,90"); 46 mylist.add(map); 47 48 // Agora vem a mágica, vamos criar um SimpleAdapter (já existe na 49 // API android) e vamos passar a lissta de elementos 50 // o row.xml e um dois arrays que farão a referência entre 51 // os TextViews do row.xml com as colunas definidas no HashMap 52 SimpleAdapter mSchedule = new SimpleAdapter(this, mylist,

R.layout.row, 53 new String[] { "codigo", "descricao", "valor" }, 54 new int[] { R.row.CODIGO_CELL, R.row.DESCRICAO_CELL,R.row.VALOR_CELL }); 55 // Repare que nas linhas acima eu posicionei só para o leitor

fazer 56 // a referência visual e enxergar como relacionamos os 57 // TextViews com as colunas do HashMap 58 59 // Daqui para frente é padrão, já discutimos em exemplos

anteriores 60 grdLista.setAdapter(mSchedule); 61 62 grdLista.setOnItemClickListener(new OnItemClickListener() { 63 @Override 64 public void onItemClick(AdapterView<?> a, View v, int

position, long id) { 65 grdLista_ItemClick(v, position); 66 } 67 }); 68 } 69 70 public void grdLista_ItemClick(View v, int position) { 71 72 // Esse ponto é interessante, como adicionamos HashMap 73 // os registros do Grid possuem HashMap, por isso

Page 148: Apostila Android Gratuita

148 Desenvolvendo Aplicações com Java para Android

74 // estou fazendo o CAST (HashMap<String, String>) 75 HashMap<String, String> map = (HashMap<String,

String>)grdLista.getItemAtPosition(position); 76 77 // Exibir mensagem padrão 78 Toast.makeText(Main.this,"Equipe: " + map.get("codigo"),

300).show(); 79 } 80 }

Se você recupera os dados de um SQLite, WebService, arquivo txt, etc.. basta criar um HashMap para cada elemento e adicionar ao ArrayList, talvez a única atenção “Mágica” está nos parâmetros do SimpleAdapter.

Execute a aplicação e clique em um item, veja, uma mensagem será exibida.

Figura 164 - Exemplo 17

Gerenciadores de Layout Gerenciadores de Layout controlam a disposição dos objetos de interface e suas dimensões, com o

uso correto deste recurso é possível desenvolver aplicações que se adaptem a qualquer disposição de interface.

Até o momento não configuramos a disposição dos elementos de interface, isso porque usamos o padrão, agora vamos exibir os principais gerenciadores de layout.

FrameLayout FrameLayout é um gerenciador de layout que organiza objetos de interface baseado nas

configurações individuais, se nenhuma configuração for feita no controle por padrão todos serão sobrepostos no canto superior esquerdo, veja o exemplo abaixo:

0 <?xml version="1.0" encoding="utf-8"?> 1 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 android:background="#ffffff" 3 android:id="@+id/frameLayout1" 4 android:layout_width="fill_parent" 5 android:layout_height="fill_parent" > 6 <TextView 7 android:text="TextView" 8 android:id="@+id/textView1" 9 android:layout_width="wrap_content" 10 android:layout_height="wrap_content"> 11 </TextView> 12 <Button 13 android:text="Button" 14 android:id="@+id/button1"

Page 149: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 149

15 android:layout_width="wrap_content" 16 android:layout_height="wrap_content"> 17 </Button> 18 </FrameLayout>

O layout esperado para o XML acima é exibido na imagem abaixo.

Figura 165 - FrameLayout com dois objetos

Veja que tanto o TextView quanto o Button foram alinhados no canto superior esquerdo, isso porque não definimos a posição de cada um, vamos então centralizar o TextView e posicionar o Button no canto inferior direito.

0 <?xml version="1.0" encoding="utf-8"?> 1 <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 android:background="#ffffff" 3 android:id="@+id/frameLayout1" 4 android:layout_width="fill_parent" 5 android:layout_height="fill_parent" > 6 <TextView 7 android:text="TextView" 8 android:id="@+id/textView1" 9 android:layout_width="wrap_content" 10 android:layout_height="wrap_content" 11 android:layout_gravity="center"> 12 </TextView> 13 <Button 14 android:text="Button" 15 android:id="@+id/button1" 16 android:layout_width="wrap_content" 17 android:layout_height="wrap_content" 18 android:layout_gravity="right|bottom"> 19 </Button> 20 </FrameLayout>

Na linha 11 estamos informando que o TextView deve ser centralizado no formulário, para isso informamos que layout_gravity possui o valor center. Já o botão associamos right com bottom para alinhar o botão no canto inferior direito.

Figura 166 - Dois objetos configurados

Page 150: Apostila Android Gratuita

150 Desenvolvendo Aplicações com Java para Android

Se você preferir fazer a configuração por XML então utilize o intellisense conforme imagem abaixo:

Figura 167 - Intellisense do Eclipse com opções de Gravity

Caso queira fazer a configuração pela interface (editor gráfico) então ative a aba de propriedade, para isso clique com o botão direito do mouse sobre o botão e escolha a opção Show in | Properties conforme figura abaixo.

Figura 168 - Ativando a aba de propriedades

Veja que a aba propriedades deverá ser exibida na parte inferior, vamos arrastar ela para o lado esquerdo do IDE.

Agora selecione o botão novamente e veja que a aba Properties deverá exibir todas as propriedades do objeto, redimensione as colunas de acordo com a sua necessidade.

Localize a propriedade layout_gravity conforme figura abaixo.

Page 151: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 151

Figura 169 - Propriedade do botão

Clique na propriedade e abra o editor conforme figura abaixo.

Figura 170 - Acessando editor da propriedade Gravity

Figura 171 - Valores possíveis para a propriedade Gravity

Agora vamos testar nosso formulário em outros layouts, vamos redimensionar a tela para ver, altere as propriedades do editor para poder simular.

Page 152: Apostila Android Gratuita

152 Desenvolvendo Aplicações com Java para Android

Figura 172 - Landscape

Na figura acima temos o mesmo formulário (Figura 166) porem com a opção Landscape ativada. Não importa qual configuração de lauyout o botão sempre estará sendo exibido no canto inferior direito e o TextView no centro da tela.

LinearLayout

Até o momento usamos em nossos exemplos sem abordar o gerenciador de layout LinearLayout com orientação vertical. LinearLayout permite organizar os componentes em uma linha vertical ou horizontal, essa orientação deve ser informada durante a programação.

Vamos demonstrar um exemplo, veja o XML abaixo.

0 <?xml version="1.0" encoding="utf-8"?> 1 <LinearLayout 2 xmlns:android="http://schemas.android.com/apk/res/android" 3 android:orientation="vertical" 4 android:layout_width="match_parent" 5 android:layout_height="match_parent" 6 android:background="#ffffff"> 7 <TextView 8 android:text="TextView" 9 android:id="@+id/textView1" 10 android:layout_width="wrap_content" 11 android:layout_height="wrap_content" 12 android:textColor="#000000"> 13 </TextView> 14 <EditText 15 android:layout_width="match_parent" 16 android:layout_height="wrap_content" 17 android:id="@+id/editText1"> 18 </EditText> 19 </LinearLayout>

Na linha 3 estamos definindo que a orientação dos componentes será feita na vertical, ou seja, um abaixo do outro conforme podemos ver na imagem abaixo.

Page 153: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 153

Figura 173 - LinearLayout com orientação vertical

Essa orientação é ótima quando temos que exibir um texto seguido de um Grid ou List.

Vamos agora ver como fica a orientação horizontal, para isso altere a linha 3 conforme XML abaixo.

0 <?xml version="1.0" encoding="utf-8"?> 1 <LinearLayout 2 xmlns:android="http://schemas.android.com/apk/res/android" 3 android:orientation="horizontal" 4 android:layout_width="match_parent" 5 android:layout_height="match_parent" 6 android:background="#ffffff"> 7 <TextView 8 android:text="TextView" 9 android:id="@+id/textView1" 10 android:layout_width="wrap_content" 11 android:layout_height="wrap_content" 12 android:textColor="#000000"> 13 </TextView> 14 <EditText 15 android:layout_width="match_parent" 16 android:layout_height="wrap_content" 17 android:id="@+id/editText1"> 18 </EditText> 19 </LinearLayout>

O resultado é exibido na imagem abaixo.

Figura 174 - LinearLayout com orientação horizontal

Esse tipo de orientação é ótimo para exibir um texto seguido de um componente de uma única linha.

TableLayout TableLayout posiciona controles em linhas e colunas, como se estivesse usando uma tabela no

Word. Para orientar na construção a API exige que você crie TableRow no qual os objetos são adicionados.

0 <?xml version="1.0" encoding="utf-8"?> 1 <TableLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 android:layout_width="fill_parent" 3 android:layout_height="fill_parent" 4 android:background="#ffffff" 5 android:stretchColumns="1"> 6 <TableRow> 7 <TextView

Page 154: Apostila Android Gratuita

154 Desenvolvendo Aplicações com Java para Android

8 android:text="Posicao [0,0]" 9 android:padding="3dip" /> 10 <TextView 11 android:text="Posicao [0,1]" 12 android:gravity="right" 13 android:padding="3dip" /> 14 </TableRow> 15 16 <TableRow> 17 <TextView 18 android:text="Posicao [1,0]" 19 android:padding="3dip" /> 20 <TextView 21 android:text="Posicao [1,1]" 22 android:gravity="right" 23 android:padding="3dip" /> 24 </TableRow> 25 </TableLayout>

Da linha 6 até a linha 14 estamos definindo a primeira ROW que terá duas colunas com dois TextView, já na linha 16 estamos iniciando uma segunda ROW também com dois objetos. O interessante é que posso ter uma linha com duas mais ou menos colunas que as outras.

Figura 175 - TableLayout com duas linhas e

duas colunas

Figura 176 - TableLayout com primeira linha

com duas colunas e com segunda linha com três colunas

RelativeLayout RelativeLayout organiza os componentes baseado na configuração individual de sua posição

referente ao Gerenciador de Layout (parent) ou outros controles. Desta forma quando um controle recebe alguma alteração de posição ou de dimensões os demais controles se reorganizam.

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

xmlns:android="http://schemas.android.com/apk/res/android" 2 android:layout_width="fill_parent" 3 android:layout_height="wrap_content" 4 android:background="#ffffff" 5 android:padding="10px" > 6 <TextView 7 android:text="Digite: " 8 android:id="@+id/label" 9 android:textColor="#000000" 10 android:layout_width="fill_parent" 11 android:layout_height="wrap_content" 12 android:layout_alignParentTop="true" 13 android:layout_alignRight="@+id/txtEntry"> 14 </TextView> 15 <EditText 16 android:layout_width="fill_parent" 17 android:id="@+id/txtEntry" 18 android:layout_height="wrap_content" 19 android:layout_below="@+id/label" 20 android:layout_centerHorizontal="true">

Page 155: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 155

21 </EditText> 22 <Button android:id="@+id/btnOk" 23 android:layout_width="wrap_content" 24 android:layout_height="wrap_content" 25 android:text="OK" 26 android:layout_below="@+id/txtEntry" 27 android:layout_alignRight="@+id/txtEntry"> 28 </Button> 29 <Button 30 android:id="@+id/btnCancelar" 31 android:layout_width="wrap_content" 32 android:layout_height="wrap_content" 33 android:text="Cancelar" 34 android:layout_alignBaseline="@+id/btnOk" 35 android:layout_alignBottom="@+id/btnOk" 36 android:layout_toLeftOf="@+id/btnOk"> 37 </Button> 38 </RelativeLayout>

Na linha 12 estou alinhado o TextView no topo do gerenciador de layout e estou associando na linha 13 este controle com um EditText que ainda não foi comentado. Na horizontal este TextView deverá preencher todo o espaço.

Na linha 20 estou forçando o EditText a assumir toda a linha horizontal.

Resta agora posicionar dois botões, o botão btnOK deverá ser exibido alinhado a direita (em relação ao EditText) e abaixo conforme linhas 26 e 27.

Já nas linhas 34 35 estou alinhado o botão btnCancel com o btnOk pela base inferior e a esquerda do btnOK. O resultado pode ser visto nas imagens abaixo.

Figura 177 - Layout em Landscape

Figura 178 - Layout em Portrait

Criando Interfaces Eficientes Android UI Tookit oferece vários gerenciadores de layouts que são fáceis de se usar, e na maioria

das vezes você precisará de usar somente um gerenciador dado a característica da interface que queira desenvolver.

Alterar as características básicas náo é a forma mais eficiente de se criar interfaces flexíveis para a plataforma Android, por exemplo o uso do abusivo de vários Gerenciadores LinearLayout em uma interface pode sobrecarregar o processamento que gasta recursos na inicialização da interface.

Vamos considerar um exemplo simples exposto no site oficial da plataforma Android, trata-se de um formulário com uma imagem alinhada a esquerda e dois textos conforme modelo baixo.

Figura 179 - Laytou proposto

(Android, 2011)

Para produzir este layout o XML utilizado é descrito abaixo.

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

Page 156: Apostila Android Gratuita

156 Desenvolvendo Aplicações com Java para Android

1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 android:layout_width="fill_parent" 3 android:layout_height="?android:attr/listPreferredItemHeight" 4 android:background="#ffffff" 5 android:padding="6dip"> 6 <ImageView 7 android:id="@+id/icon" 8 9 android:layout_width="wrap_content" 10 android:layout_height="fill_parent" 11 android:layout_marginRight="6dip" 12 android:src="@drawable/icon" /> 13 <LinearLayout 14 android:orientation="vertical" 15 android:layout_width="0dip" 16 android:layout_weight="1" 17 android:layout_height="fill_parent" 18 android:background="#ff0011"> 19 20 <TextView 21 android:layout_width="fill_parent" 22 android:layout_height="0dip" 23 android:layout_weight="1" 24 android:background="#222222" 25 android:gravity="center_vertical" 26 android:text="Primeiro TextView" /> 27 <TextView 28 android:layout_width="fill_parent" 29 android:layout_height="0dip" 30 android:layout_weight="1" 31 android:singleLine="true" 32 android:text="Outro TextView" /> 33 </LinearLayout> 34 </LinearLayout>

Temos dois LinearLayouts no exemplo acima, o mais geral controla a área branca da imagem baixo, sua orientação é horizontal, dentro deste LinearLayout encontramos um ImageView a esquerda e a direita um outro LinearLayout, este segundo LinearLayout possui uma orientação vertical e controla a área preta e vermelha no qual adicionamos dois TextViews.

Figura 180 - Layout formado por dois gerenciadores

Esse layout funciona, mas pode ser um desperdício se você instanciá-lo cada item da lista de um ListView. O mesmo layout pode ser rescrito usando um único gerenciador de layout, para este exemplo o portal oficial da plataforma indica o uso do RelativeLayout, será muito mais rápido instanciar um único gerenciador de layout por elemento da lista (lembre-se que um layout pode ser usado como item em coleções).

Segue o mesmo layout utilizando RelativeLayout.

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

xmlns:android="http://schemas.android.com/apk/res/android" 2 android:layout_width="fill_parent" 3 android:layout_height="?android:attr/listPreferredItemHeight" 4 android:background="#ffffff" 5 android:padding="6dip">

Page 157: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 157

6 <ImageView 7 android:id="@+id/icon" 8 android:layout_width="wrap_content" 9 android:layout_height="fill_parent" 10 android:layout_alignParentTop="true" 11 android:layout_alignParentBottom="true" 12 android:layout_marginRight="6dip" 13 android:src="@drawable/icon" /> 14 <TextView 15 android:id="@+id/secondLine" 16 android:layout_width="fill_parent" 17 android:layout_height="26dip" 18 android:layout_toRightOf="@id/icon" 19 android:layout_alignParentBottom="true" 20 android:layout_alignParentRight="true" 21 android:background="#ff0000" 22 android:singleLine="true" 23 android:ellipsize="marquee" 24 android:text="Outro TextView" /> 25 <TextView 26 android:layout_width="fill_parent" 27 android:layout_height="wrap_content" 28 android:layout_toRightOf="@id/icon" 29 android:layout_alignParentRight="true" 30 android:layout_alignParentTop="true" 31 android:layout_above="@id/secondLine" 32 android:layout_alignWithParentIfMissing="true" 33 android:background="#000000" 34 android:gravity="center_vertical" 35 android:text="Primeiro TextView" /> 36 </RelativeLayout>

Com apenas um gerenciador de layout foi possível construir a mesma interface, associando os elementos com RelativeLayout. O resultado pode ser visto abaixo.

Figura 181 - Mesmo layout porem com RelativeLayout

Page 158: Apostila Android Gratuita

158 Desenvolvendo Aplicações com Java para Android

88 8 Persistência de Dados

Objetivo Deste Apêndice •

• .

Introdução Uma aplicação voltada ao público corporativo geralmente requer que dados sejam armazenados em

algum repositório para posterior acesso. Um conjunto de dados organizados em bytes podem ser armazenados em arquivos gerenciados pela própria aplicação, um exemplo o padrão de armazenamento .cvs, .txt, .xml. Outra forma é utilizar APIs desenvolvidas por terceiros para gerenciar tais dados, desta forma a aplicação não controla o mecanismo de persistência dos bits no arquivo e nem sua formatação, tais mecanismos estão escritos na API que está sendo utilizada.

Neste capítulo vamos abordar o uso destas tecnologias para persistir dados e posteriormente a consulta dos mesos.

Persistência em Arquivos // TODO: fazer

SQLite Algumas plataformas as APIs mencionadas na introdução deste capítulo levam a serviços

oferecidos por outros programas, a complexidade deste ambiente garante que a informação não vai estar acoplada ao programa e que vários outros programas podem acessar estas informações. Tais sistemas de gerenciamento de dados são chamados de Sistemas de Gerenciamento de Banco de Dados orientado a serviços. Outras APIs como a API do SQLite funciona como um Sistema de Gerenciamento de Banco de Dados embutido, onde não encontramos um serviço disponibilizado por uma máquina (remota ou local), a própria API faz as transações com um arquivo utilizado para armazenamento de dentro da sua aplicação.

A vantagem de um banco de dados embutido é sua simplicidade que requer menos do ambiente no qual está sendo executado, não é preciso instalar nada, não é preciso configurar nenhum sistema operacional, ou seja, é muito simples. Se você está acostumado a utilizar sistemas de gerenciamento de dados baseado em serviços, tais como Oracle, Microsoft SqlServer, etc.. pode estar pensando o porque a simplicidade é a peça chave e porque perdemos a robustez do ambiente voltado a serviços.

A resposta é simples: problemas simples requerem soluções simples.

Page 159: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 159

O SQLite se propõe a trabalhar em diversos ambientes e plataformas, ele não está focado em uma plataforma específica ou em um produto, logo não pode se prender a requisitos complexos.

Se você trabalha com java ou .net está acostumado a criar uma conexão, criar um comando e executar, porem aqui na plataforma Android trabalhamos de forma diferente, construímos classes de apoio que serão utilizados durante a necessidade de desenvolvimento.

A principal classe de apoio deve estender de SQLiteOpenHelper, dentro dessa classe podemos sobrescrever o método onCreate() que nos permite criar tabelas, visto que não temos um cliente de SGBD para gerenciar o banco através de scripts.

0 public class DictionaryOpenHelper extends SQLiteOpenHelper { 1 2 private static final int DATABASE_VERSION = 2; 3 private static final String DICTIONARY_TABLE_NAME = "dictionary"; 4 private static final String DICTIONARY_TABLE_CREATE = "CREATE TABLE

" + DICTIONARY_TABLE_NAME + " (id INTEGER, name TEXT);"; 5 6 DictionaryOpenHelper(Context context) { 7 super(context, DATABASE_NAME, null, DATABASE_VERSION); 8 } 9 10 @Override 11 public void onCreate(SQLiteDatabase db) { 12 db.execSQL(DICTIONARY_TABLE_CREATE); 13 } 14 }

Durante a execução da sua aplicação você deverá criar instancias da classe DictionaryOpenHelper, ao fazer isso sua classe deverá chamar o construtor da super-classe (linha 7), na super-classe SQLiteOpenHelper (interno) será chamado o método onCreate() no qual a tabela será criada se necessário.

Para realizar a leitura ou escrita basta chamar resgatar o Database através dos métodos getWritableDatabase() e getRedabeDatabase(), tais métodos estão descritos abaixo:

getWritebleDatabase(): Abre ou cria uma conexão com o database que será usado para escrita, quando o banco é aberto com sucesso, o banco de dados é armazenado em cache, desta forma você pode chamar este método sempre que quiser escrever na base de dados.

getReadableDatabase(): Da mesma forma que o getWritableDatabase() este método abre a conexão com a fonte de dados porem prepara somente para a leitura.

Para realizar operações de consultas simples você deve usar o método query(), este método aceita vários parâmetros que permitem as consultas simples, normalmente você está acostumado a criar strings com cláusulas SQLs e disparar contra um SGBD, então a princípio o uso do método query() possa ser um pouco estranho, mas você logo irá se acostumar.

Para consultas mais avançadas como por exemplo o uso de aliases vamos utilizar uma classe chamada SQLiteQueryBuilder para construir nossas consultas.

Page 160: Apostila Android Gratuita

160 Desenvolvendo Aplicações com Java para Android

Page 161: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 161

A1A1 Apêndice 1 Habilitando Depuração

Objetivo Deste Apêndice Configurar o device para aceitar depuração por USB.

Introdução Ao entrar no Device, temos que configurar ele para permitir a depuração. Essa configuração

habilita um Listener que permite aos componentes do Android SDK se comuniquem com o Device. A configuração é simples:

1- No menu principal acesse os aplicativos (no device ) na Figura 182;

2- Selecione o aplicativo Settings conforme Figura 183;

3- Agora acesse as configurações dos Aplicativos (Figura 184);

4- Entre nas configurações de Desenvolvimento (Figura 185);

5- E habilite a depuração por USB (Figura 186).

Page 162: Apostila Android Gratuita

162 Desenvolvendo Aplicações com Java para Android

Figura 182 Área

principal

Figura 183 Settings

Figura 184 Acessando

Configuração de Aplicativos

Figura 185

Configurações de Desenvolvimento

Figura 186

Habilitando USB Debugging

Page 163: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 163

A2A2 Apêndice 2 Perspectiva no Eclipse

Objetivo Deste Apêndice Configurar o device para aceitar depuração por USB.

Introdução

Page 164: Apostila Android Gratuita

164 Desenvolvendo Aplicações com Java para Android

A3A3 Apêndice 3 Show View in Perspective

Objetivo Deste Apêndice Configurar o device para aceitar depuração por USB.

Introdução

Page 165: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 165

Page 166: Apostila Android Gratuita

166 Desenvolvendo Aplicações com Java para Android

Page 167: Apostila Android Gratuita

Desenvolvendo Aplicações com Java para Android 167