11. Capítulo 1
Preparando o Ambiente de
Desenvolvimento
1.1 Introdução
O desenvolvimento de aplicativos para a plataforma Android é feito na linguagem Java.
Para esta apostila serão utilizados os seguintes aplicativos e bibliotecas:
Ubuntu 10.04 ou 12.04
Java JDK 6 ou 7
Android SDK
Android 2.2 API 8
Eclipse Juno
ADT Plugin
Sqlite3
Sqliteman
Inkscape
Você pode estar se perguntando: ”Por que utilizar essa configuração?”. Bom, para
começar um ambiente de desenvolvimento precisa ser estável, e para isso nada melhor que
o http://releases.ubuntu.com/lucid/ (Ubuntu 10.04) ou ainda o http://releases.
ubuntu.com/precise/ (Ubuntu 12.04) por serem LTS.
A IDE Eclipse funciona independente do sistema operacional, então podemos utilizar
a versão mais recente. O mesmo para o plugin ADT.
Usaremos especificamente para os exemplos a seguir a versão 2.2 do Android. Essa
API é uma ótima escolha inicial, pois é a mais utilizada pelos aparelhos mais simples que
rodam Android. É claro que você poderá instalar outras versões e compilar seus aplicativos
para tablets, etc.
1
12. 2 CAPÍTULO 1. PREPARANDO O AMBIENTE DE DESENVOLVIMENTO
1.2 Instalação
A instalação do Java JDK 6 no Ubuntu 10.04 não é a mesma que no Ubuntu 12.04. Isso
porque na época de lançamento do lucid, em 2010, a empresa que desenvolvia o Java
era a Sun Microsystems, que tinha um canal nos repositórios do Ubuntu como parceira
(partner). Ainda em 2010 a empresa Oracle comprou a Sun junto com seu software e
hardware. Nesse ponto o canal de parceria foi desligado.
Discussões a parte, vamos ver as duas maneiras de instalar o Java.
1.2.1 Java JDK 6
A instalação do Java no Ubuntu 10.04 é bastante simples. Você apenas irá precisar habili-
tar repositório de terceiros, ou Partner. Isso pode ser feito através do aplicativo Synaptic.
No menu principal do Ubuntu clique em Sistema → Administração → Gerenciador
de pacotes Synaptic.
No menu do Synaptic clique em Configuração → Repositórios. Na aba Outro
Software temos vários itens que representam repositórios. Marque os dois repositórios que
terminam com partner. Feche e depois clique em Editar → Recarregar informações
dos pacotes ou simplesmente Ctrl + R.
Após a atualização dos pacotes existentes nos repositórios já é possível encontrar o
Java JDK 6. No campo de Pesquisa rápida digite: sun-java6. Clique com botão
direito no pacote sun-java6-jdk e selecione a opção Marcar para instalação. Depois
basta Aplicar as mudanças. Para isso clique em Editar → Aplicar as alterações
marcadas ou Ctrl + P.
Para a instalação no Ubuntu 12.04 temos que habilitar um repositório de terceiros,
também conhecido como PPA (Personal Package Archives). Abra um terminal e execute
os passos a seguir para adicionar um repositório e instalar o Java:
$ sudo su
# apt-add-repository ppa:flexiondotorg/java
# apt-get update
# apt-get install sun-java6-jdk
Um pouco de Linux
Para quem não está familiarizado com o ambiente Linux vamos a uma pequena explica-
ção. Nos comandos acima aparecem dois caracteres que não devem ser escritos mas que
representam algo importante no âmbito dos comandos, são eles $ e #. Estes caracteres
indicam qual o nível do usuário; $ significa usuário comum, # representa super usuário
(root). No comando sudo su é onde trocamos de usuário comum para super usuário.
Neste momento você terá que entrar com sua senha de login.
Java JDK 7
Segundo a página de Requerimentos do Sistema (http://developer.android.com/sdk/
requirements.html) do site oficial do Android, é necessário uso do Java 6. Caso você
queira utilizar o Java 7, você terá que configurar seu projeto Android para ser compilado
com suporte a versão 6.
13. 1.2. INSTALAÇÃO 3
A instalação do Java 7 no Ubuntu 12.04 pode ser feita da seguinte maneira:
$ sudo su
# add-apt-repository ppa:webupd8team/java
# apt-get update
# apt-get install oracle-jdk7-installer
Após criar o projeto clique com botão direito do mouse em seu projeto e selecione
Properties. Na lista de itens do lado esquerdo selecione Java Compiler. Daí basta clicar
em Enable project specific settings e logo abaixo escolher o nível de compilação em
Compiler compliance level, escolha 1.6.
1.2.2 Android SDK
Para o Android SDK comece pelo download http://developer.android.com/sdk/index.
html.
A instalação é feita apenas colocando o SDK em um diretório do sistema. Existem 2
bons locais para abrigar bibliotecas no Linux, são elas: /opt e /usr/local/lib. Nesse
exemplo vamos utilizar este último. Abra um terminal e vamos aos comandos.
Se você baixou o SDK para seu diretório Downloads, proceda da seguinte maneira:
$ cd /home/usuario/Downloads
$ tar -xf android-sdk r18-linux.tgz
¯
$ sudo su
# mv android-sdk-linux /usr/local/lib
# cd /usr/local/lib
# ln -s android-sdk-linux android-sdk
# cd android-sdk/tools
# ln -s android /usr/local/bin/android
Obs.: troque usuario na primeira linha pelo seu login do sistema.
O poder do Linux
Dê atenção ao uso do comando ln. Ele é responsável por criar links simbólicos. Isso é
muito útil quando se instala um aplicativo ou biblioteca, pois proporciona atualização sem
que outros ajustes sejam feitos. Neste caso basta linkar outra vez e pronto.
Note que no último comando temos um link simbólico para o diretório /usr/local/bin.
É nele que colocamos os executáveis globais, ou seja, que são vistos a partir de qualquer
outro diretório. Agora saindo do modo root e usando seu próprio usuário instalaremos a
API.
1.2.3 Android 2.2 API 8
Ainda no terminal, agora como usuário comum, vamos abrir o aplicativo que instala qual-
quer uma das API disponibilizadas pelo Android.
$ android
14. 4 CAPÍTULO 1. PREPARANDO O AMBIENTE DE DESENVOLVIMENTO
O aplicativo Android SDK and AVD Manager irá aparecer. Clique em Avaliable
packages e procure pela versão 2.2 API 8 do Android. Selecione e clique em Install
Selected. Após o download você pode verificar a versão instalada em Installed packages,
um dos itens é algo como SDK Plataform Android 2.2, API 8, revision 2.
Se você quiser aproveite para baixar outras versões para utilizar em projetos futuros.
1.2.4 Android Virtual Device (AVD)
Vamos aproveitar e criar nosso AVD para testar pela primeira vez nosso emulador. Ainda
no Android SDK and AVD Manager clique em Virtual devices, depois em New...
Dê um nome. Você pode usar qualquer nomenclatura, mas é interessante que tenha
algo haver com a versão. Assim, caso você tenha que testar seu código em outras versões
você poderá saber qual emulador utilizar. Por exemplo use android-2.2. Em Target
escolha a versão, neste caso Android 2.2 - API Level 8. Pronto, apenas clique em
Create AVD.
Dicas
A opção Skin indica qual a resolução da tela do aparelho. Como não é possível redimen-
sionar a janela, em alguns monitores a janela fica maior que a tela do seu monitor.
A opção Snapshot quando habilitada, serve para salvar o estado do emulador. Isso faz
com que da segunda inicialização em diante se torne mais rápida.
A opção SD Card é ideal caso sua aplicação necessite guardar dados como fotos, arqui-
vos. O AVD irá reservar um espaço em seu HD permitindo assim o acesso a dados pelo
emulador.
1.2.5 Eclipse Juno
O IDE Eclipse pode ser encontrada em http://www.eclipse.org/downloads/. Para o de-
senvolvimento de aplicativos para o Android a versão Eclipse IDE for Java Developers
é ideal. Mas se você tiver interesse em aplicativos Java para Web a opção é baixar a versão
Eclipse IDE for Java EE Developers.
Em todo caso as duas vão servir para o desenvolvimento, pois ambas vem com suporte
a Java.
O Eclipse não possui instalador, no caso ele já vem pré-compilado. Basta apenas
descompactar e executar o arquivo eclipse.
Para sua comodidade você pode adicionar o Eclipse no menu do Ubuntu. Isso pode
ser feito apenas clicando com o botão direiro do mouse no menu principal e escolhendo a
opção Editar menus. Ou você pode usar a dica do blog MAD3 Linux
(http://www.mad3linux.org) - http://va.mu/VSgR. Essa dica irá lhe mostrar como
adicionar um item ao menu visível a todos os usuários.
1.2.6 Plugin ADT
Para a instalação do plugin ADT vamos abrir o Eclipse, e em seu menu selecione Help →
Eclipse Marketplace...
Busque por adt e escolha o Android Development Tools for Eclipse da Google,
Inc., Apache 2.0 e clique em Install. O Eclipse irá pedir confirmação sobre os itens
15. 1.2. INSTALAÇÃO 5
a serem instalados, clique em Next. Agora basta aceitar os termos de uso e clicar em
Finish. Após o download e a instalação, reinicie o Eclipse.
No Eclipse Marketplace você pode encontrar outras ferramentas bastante úteis para
um bom desenvolvimento. Clique na aba Popular e veja as ferramentas mais baixadas,
talvez exista uma que você não conheça mas que sempre precisou.
Configurando o ADT
Agora que o plugin foi instalado temos que dizer ao Eclipse onde nós instalamos o Android
SDK. Isso pode ser feito clicando no menu Window → Preferences. Selecione Android
no painel lateral esquerdo. Em SDK Location clique em Browse... e indique o diretório
do SDK, caso não lembre, ele está em /usr/local/lib/android-sdk. Clique em Apply
na parte inferior direita para atualizar a lista de API’s disponíveis.
Caso você tenha mais dúvidas dê uma olhada na página oficial de instalação do plugin
ADT localizada em http://developer.android.com/sdk/eclipse-adt.html.
Testando o ADT
Para testar o Android Development Tools ou ADT crie um projeto Android. No menu
do Eclipse selecione File → New → Project...
Selecione Android Application Project e clique em Next. Dê um nome qualquer
ao seu aplicativo, por exemplo hello.android. Note que o ADT tenta dar um nome
ao seu pacote e ao diretório de arquivos a partir do nome que você digitou. Deixe como
está. Em Build SDK é preciso escolher qual API vamos utilizar, em nosso caso escolha
a Android 2.2 (API 8). Em Minimum Required SDK escolha a API 8: Android 2.2
(Froyo) indicando que a versão mínima é a API 8. Clique em Next.
Na versão do ADT para o Eclipse Juno, uma novidade apareceu. É possível criar o
ícone lançador logo ao criar o aplicativo. Selecione da maneira que achar melhor e clique
em Next. Depois clique em Finish.
Após isso clique com botão direito do mouse no projeto recém criado, e Run As →
Android Application. Se tudo tiver dado certo é possível ver no emulador sua primeira
aplicação rodando.
Dicas
Uma vez que você abriu o emulador não o feche. Você irá notar que ao abrir pela primeira
vez ele leva um tempo para isso. Neste caso ao atualizar o código-fonte apenas rode
o aplicativo novamente. O plugin ADT fará com que o aplicativo seja reinstalado no
emulador.
Faça o teste com alguns atalhos básicos:
Alt + Enter Maximiza o emulador. Ideal para demostrações.
Ctrl + F11 Muda a orientação do emulador, retrato ou paisagem.
F8 Liga/desliga a rede.
Outro elemento essencial é o LogCat. Ele faz parte do ADT e é responsável por mostrar
as mensagens de log do emulador. Caso você encontre problemas com seu código o LogCat
será seu melhor aliado. Para acessá-lo no Eclipse clique no menu Window → Show View
→ Other..., clique em Android → LogCat.
16. 6 CAPÍTULO 1. PREPARANDO O AMBIENTE DE DESENVOLVIMENTO
1.2.7 Sqlite3
Sendo o Sqlite o banco de dados embutido na plataforma Android, nada melhor do que
aprendermos um pouco sobre ele.
O Sqlite é um banco de dados relacional bastante utilizado por dispositivos e sistemas
embarcados por ser leve, robusto, de fácil configuração e, acima de tudo, livre. Para a
instalação, abra um terminal como root e:
$ sudo su
# apt-get install sqlite3
Após a instalação é possível utilizar o Sqlite via linha de comando. Faça logoff do
usuário root e faça os seguintes testes:
# exit
$ sqlite
SQLite version 2.8.17
Enter ".help"for instructions
sqlite>
Você deverá ver algo parecido. Para sair utilize o comando .exit. Veja outros detalhes
na página oficial do projeto: http://www.sqlite.org/.
Tipos de dados
Utilize a tabela abaixo para criar suas tabelas futuramente.
Nome Descrição
INTEGER valores inteiros, positivos ou negativos. Podem variar de 1 a 8 bytes.
REAL valores reais ou decimais.
TEXT usado para armazenar valores, não-limitado. Suporta várias codifica-
ções, por exemplo UTF-8.
BLOB objetos binários tais como imagens, arquivos de texto, etc. Também
possui tamanho não-limitado.
NULL representa falta de informação.
Tabela 1.1: Tipos de dados do Sqlite
1.2.8 Sqliteman
Para uma gerência mais produtiva usaremos o Sqliteman para acessar e modificar bancos
de dados. A instalação é feita via linha de comando. Abra um terminal e:
$ sudo su
# apt-get install sqliteman
17. 1.2. INSTALAÇÃO 7
Depois de instalado, acesse o aplicativo do menu principal do Ubuntu em Aplicativos
→ Escritório → Sqliteman. Faça alguns testes criando bancos de dados, depois crie
algumas tabelas. Ele possui assistentes que irão auxiliar nos primeiros momentos.
Por exemplo, crie uma base de dados e depois clique com o botão direito do mouse em
Tables. Utilize o assistente e veja como é simples criar tabelas no sqlite.
1 -- Distribuições Linux
2
3 CREATE TABLE distros (
4 _id INTEGER PRIMARY KEY,
5 nome TEXT NOT NULL,
6 interface TEXT NOT NULL DEFAULT ’Gnome3’ ,
7 deriva_de INTEGER REFERENCES distros(_id)
8 );
9
10 INSERT INTO distros VALUES (1, ’Debian’ , ’Gnome3’ , NULL);
11 INSERT INTO distros VALUES (2, ’Ubuntu’ , ’Unity’ , 1);
12 INSERT INTO distros VALUES (3, ’Linux Mint’ , ’Mate’ , 2);
13 INSERT INTO distros VALUES (4, ’Fedora’ , ’KDE’ , NULL);
14 INSERT INTO distros VALUES (5, ’Slackware’ , ’KDE’ , NULL);
15 INSERT INTO distros VALUES (6, ’Slax’ , ’KDE’ , 5);
16 INSERT INTO distros VALUES (7, ’Ubuntu Studio’ , ’XFCE’ , 2);
17 INSERT INTO distros VALUES (8, ’kUbuntu’ , ’KDE’ , 2);
18 INSERT INTO distros VALUES (9, ’xUbuntu’ , ’XFCE’ , 2);
Código-fonte 1: Exemplo de banco de dados [exemplo-bd.sql]
Observe que podemos fazer auto-relacionamento na tabela. Assim somos capazes de
executar a seguinte SQL, contando o número de distros que derivam de uma outra original.
Veja:
1 SELECT d._id, d.nome, d.interface,
2 (
3 SELECT SUM( CASE WHEN aux.deriva_de = d._id THEN 1 ELSE 0 END )
4 FROM distros aux
5 ) AS num_derivadas
6 FROM distros d
Código-fonte 2: Exemplo de query com subquery [exemplo-bd.sql]
Mais informações em: http://sqliteman.com/
1.2.9 Inkscape
Uma ótima ferramenta de desenho vetorial é o Inkscape. Ela será bastante útil pois o
desenvolvimento de aplicativos hoje em dia é baseado muito em figuras para facilitar a
navegação, identidade visual, entre outras coisas.
18. 8 CAPÍTULO 1. PREPARANDO O AMBIENTE DE DESENVOLVIMENTO
A instalação é feita de forma simples. Num terminal:
$ sudo su
# apt-get install inkscape
Para dicas de como criar ícones para os diversos elementos do Android veja a página
http://developer.android.com/design/style/iconography.html.
19. Capítulo 2
Exemplo prático
2.1 Primeira aplicação - Contatos
Baseado em 1.2.6 Testando o ADT, crie um novo aplicativo chamado Contatos. Use
contatos.app como o nome do pacote. Crie uma Activity inicial chamada MainActivity
e um layout inicial chamado main. Depois clique em Finish.
Este exemplo é bastante útil para aprendermos como funciona o Android. Você só
poderá criar algo se você souber utilizar bem as ferramentas.
2.1.1 AndroidManifest.xml
Este é o arquivo que define nossa aplicação, mapeia as Activity’s, entre outras configura-
ções. Ao finalizar a criação do projeto, inicialmente este arquivo deverá conter o seguinte
conteúdo:
1 <?xml version="1.0" encoding="UTF-8"?>
2 <manifest xmlns:android= "http://schemas.android.com/apk/res/android"
3 package= "contatos.app"
4 android:versionCode= "1"
5 android:versionName= "1.0" >
6 <uses-sdk android:minSdkVersion= "8" android:targetSdkVersion= "8" />
7 <application android:icon= "@drawable/icon" android:label= "@string/app_name" >
8 <activity android:name= ".MainActivity" android:label= "@string/app_name" >
9 <intent-filter>
10 <action android:name= "android.intent.action.MAIN" />
11 <category android:name= "android.intent.category.LAUNCHER" />
12 </intent-filter>
13 </activity>
14 </application>
15 </manifest>
Código-fonte 3: Projeto inicial [AndroidManifest.xml]
9
20. 10 CAPÍTULO 2. EXEMPLO PRÁTICO
2.1.2 Activity
Não existe método main visível ao programador no Android. Ao invés disso temos
Activity’s. Para que o Android saiba qual ele deve iniciar primeiro utilizamos um
intent-filter como visto no trecho de código acima da linha 09 a 12 . Para nossa
primeira Activity criaremos uma lista de contatos e um menu para criação de um novo
contato.
Para construir o layout inicial de nossa aplicação precisamos editar o arquivo main.xml
localizado em res/layout.
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 <ListView
7 android:id= "@+id/lv_contatos"
8 android:layout_width= "fill_parent"
9 android:layout_height= "wrap_content" />
10 </LinearLayout>
Código-fonte 4: Layout principal [res/layout/main.xml]
Deste momento em diante tenha em mente que os arquivos xml aqui descritos são
apenas para você poder comparar e ver se não esqueceu de nada. Todos os layout’s devem
ser criados usando a ferramenta ADT. Você irá notar que ao abrir o xml uma janela de
layout aparecerá. Para visualizar o xml ou o layout gráfico basta utilizar a aba inferior
esquerda.
Por fim, temos o menu. Clique com o botão direito do mouse em seu projeto e New →
Other... ou Ctrl + N. Procure por Android XML File. Em Resource Type escolha a
opção Menu. Chame-o de main menu.xml.
¯
1 <?xml version="1.0" encoding="UTF-8"?>
2 <menu xmlns:android= "http://schemas.android.com/apk/res/android" >
3 <item
4 android:id= "@+id/menu_add"
5 android:title= "Novo"
6 android:icon= "@android:drawable/ic_menu_add" />
7 </menu>
Código-fonte 5: Menu principal [res/menu/main menu.xml]
¯
Pronto, já temos nosso layout. Compile o projeto e vamos a próxima iteração.
21. 2.1. PRIMEIRA APLICAÇÃO - CONTATOS 11
Convenção de nomes para ícones
Observe que o ícone utilizado no menu vem junto com o SDK do Android. Você pode
visualizar os ícones em SDK INSTALL/plataforms/android-8/data/res/drawable-hdpi
¯
(substitua SDK INSTALL pelo diretório de instalação do SDK do Android, no nosso caso
¯
usr/local/lib/android-sdk, 1.2.2). Note que há namespaces ou prefixos em cada um
dos ícones. O Android recomenda a seguinte convenção:
Tipo de Recurso Prefixo Exemplo
Ícones ic ic adicionar.png
¯ ¯
Launcher icons ic launcher ic launcher calendario.png
¯ ¯ ¯ ¯
Menu e Action Bar ic menu ic menu ajuda.png
¯ ¯ ¯ ¯
Status bar icons ic stat notify ic stat notify msg.png
¯ ¯ ¯ ¯ ¯ ¯
Tab icons ic tab ic tab recente.png
¯ ¯ ¯ ¯
Dialog icons ic dialog ic dialog info.png
¯ ¯ ¯ ¯
Tabela 2.1: Convenção para nome dos ícones
Note que você não é obrigado a utilizar os prefixos citados acima, isto é apenas uma
convenção. Veja mais detalhes em http://developer.android.com/guide/practices/
ui_guidelines/icon_design.html.
Abra o arquivo MainActivity.java e vá ao método onCreate. Defina o layout como
sendo nosso main.xml. Para isso adicione o layout main ao final do método:
1 @Override
2 public void onCreate(Bundle icicle) {
3 super.onCreate(icicle);
4 setContentView(R.layout.main);
5 }
Código-fonte 6: Definir layout [MainActivity.java]
Cuidado: no ambiente Android temos uma classe chamada R. Ela existe tanto na biblio-
teca do Android como em cada projeto. Nesse caso faça o import da classe contatos.app.R.
A classe android.R é utilizada em outras situações, onde códigos pré-prontos foram dis-
ponibilizados pela equipe do Android.
Agora precisamos sobrescrever os métodos onCreateOptionsMenu e onOptionsItemSelected.
Eles irão criar o menu a partir de nosso layout e notificar quando os itens do menu forem
pressionados, respectivamente. Vamos ao código:
22. 12 CAPÍTULO 2. EXEMPLO PRÁTICO
1 @Override
2 public boolean onCreateOptionsMenu(Menu menu) {
3 new MenuInflater(this).inflate(R.menu.main_menu, menu);
4 return super.onCreateOptionsMenu(menu);
5 }
6
7 @Override
8 public boolean onOptionsItemSelected(MenuItem item) {
9 if (item.getItemId() == R.id.menu_add) {
10 irParaSalvar();
11 return true;
12 }
13 return super.onOptionsItemSelected(item);
14 }
15
16 private void irParaSalvar() {
17 // não implementado ainda ...
18 }
Código-fonte 7: Criando o menu [MainActivity.java]
2.1.3 Formulários
Agora vamos criar nosso formulário para criação e edição de contatos. Começaremos pelo
layout. Crie um arquivo xml em res/layout chamado salvar.xml.
Existem alguns pontos importantes para este trecho de código. Começando pelo layout
inicial, onde usaremos TableLayout. Esse layout é ideal para telas com estilo tabela.
Um detalhe importante para observarmos neste layout é que ele possui o atributo
stretchColumns com valor 1. Isso quer dizer que a coluna 1 da tabela terá o maior
tamanho possível, respeitando o tamanho mínimo das outras células. Para visualizar as
mudanças você pode tentar usar outros valores como 0 tornando a primeira coluna maior
que as demais, ou ainda * que fará com que todas as células tenham o mesmo tamanho.
23. 2.1. PRIMEIRA APLICAÇÃO - CONTATOS 13
1 <?xml version="1.0" encoding="UTF-8"?>
2 <RelativeLayout
3 android:id= "@+id/widget31"
4 android:layout_width= "fill_parent"
5 android:layout_height= "fill_parent"
6 xmlns:android= "http://schemas.android.com/apk/res/android" >
7 <TableLayout
8 android:id= "@+id/widget32"
9 android:layout_width= "fill_parent"
10 android:layout_height= "wrap_content"
11 android:orientation= "vertical"
12 android:stretchColumns= "1" >
13 <TableRow
14 android:id= "@+id/widget33"
15 android:layout_width= "fill_parent"
16 android:layout_height= "wrap_content"
17 android:orientation= "horizontal" >
18 <TextView
19 android:id= "@+id/textView1"
20 android:layout_width= "wrap_content"
21 android:layout_height= "wrap_content"
22 android:text= "Nome" ></TextView>
23 <EditText
24 android:id= "@+id/et_nome"
25 android:layout_width= "wrap_content"
26 android:layout_height= "wrap_content" ></EditText>
27 </TableRow>
28 <!-- faça mais duas TableRow’s contendo o Telefone e E-mail -->
29 <Button
30 android:id= "@+id/bt_salvar"
31 android:text= "Salvar"
32 android:layout_height= "wrap_content"
33 android:layout_width= "fill_parent" ></Button>
34 </TableLayout>
35 </RelativeLayout>
Código-fonte 8: Formulário principal [res/layout/salvar.xml]
Crie uma nova Activity chamada SalvarActivity dentro de contatos.app.view.
Para irmos de uma Activity para outra precisamos de um Intent. Um de seus constru-
tores recebe como parâmetros a instância da classe em que estamos, sendo que ela deve
implementar a interface Context e o nome da classe a qual deve ser mostrada. Veja como
implementar o método irParaSalvar da classe MainActivity:
24. 14 CAPÍTULO 2. EXEMPLO PRÁTICO
1 private void irParaSalvar() {
2 Intent intent = new Intent(MainActivity.this, SaveActivity.class);
3 startActivity(intent);
4 }
Código-fonte 9: Mudando de Activity [MainActivity.java]
Veremos agora como manipular EditText’s, que representam os campos de entrada
de dados. Abra o SalvarActivity e adicione o método carregar e crie atributos para
guardar os EditText’s:
1 private EditText etNome, etFone, etEmail;
2 /* ... */
3
4 @Override
5 public void onCreate(Bundle icicle) {
6 super.onCreate(icicle);
7 setContentView(R.layout.salvar);
8 carregar();
9 }
10
11 private void carregar() {
12 etNome = (EditText) findViewById(R.id.et_nome);
13 etTefone = (EditText) findViewById(R.id.et_telefone);
14 etEmail = (EditText) findViewById(R.id.et_email);
15 }
Código-fonte 10: Utilizando EditText’s [SalvarActivity.java]
Para que a Activity funcione precisamos mapeá-la no arquivo AndroidManifest.xml.
Adicione o conteúdo abaixo entre as tags application:
1 <activity android:name= ".view.SalvarActivity" ></activity>
Código-fonte 11: Mapear SalvarActivity [AndroidManifest.xml]
Utilize sempre o ADT e apenas confira se o arquivo está da maneira correta.
2.1.4 Construindo o Model da aplicação
Precisamos de um helper para fazer acesso ao banco de dados. O Android provê suporte a
bancos de dados Sqlite por padrão. Qualquer banco de dados que você criar será acessível
pelo nome por qualquer classe na sua aplicação, mas não fora dela.
Crie uma classe chamada ContatoHelper em contatos.app.model que extende de
SQLiteOpenHelper. Essa classe será capaz de ler e escrever no banco de dados graças aos
métodos getReadableDatabase() e getWritableDatabase(), respectivamente.
25. 2.1. PRIMEIRA APLICAÇÃO - CONTATOS 15
A princípio temos que criar um construtor passando como parâmetros o nome do banco
de dados e a versão da DDL (Data Definition Language). Logo em seguida precisamos
implementar os métodos onCreate, no qual iremos criar as tabelas e onUpdate, caso
tenhamos que alterar alguma tabela.
1 package contatos.app.model;
2
3 import android.content.Context;
4 import android.database.sqlite.SQLiteDatabase;
5 import android.database.sqlite.SQLiteOpenHelper;
6
7 public class ContatoHelper extends SQLiteOpenHelper {
8
9 private static final String DATABASE_NAME = "contatos.db" ;
10 private static final int VERSION = 1;
11
12 public ContatoHelper(Context context) {
13 super(context, DATABASE_NAME, null, VERSION);
14 }
15
16 @Override
17 public void onCreate(SQLiteDatabase db) {
18 db.execSQL( "CREATE TABLE contato (_id INTEGER PRIMARY KEY AUTOINCREMENT,"
19 + " nome TEXT, fone TEXT, email TEXT);" );
20 }
21
22 @Override
23 public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
24 // nada a fazer por enquanto ...
25 }
26 }
Código-fonte 12: Helper da aplicação [ContatoHelper.java]
Para a iteração de criação de um novo contato, ainda em ContatoHelper vamos adi-
cionar um método criar. Faça:
1 public void criar(ContentValues values) {
2 getWritableDatabase().insert( "contato" , "telefone" , values);
3 }
Código-fonte 13: Criar novo contato [ContatoHelper.java]
Agora temos que fazer a chamada do método criar da classe ContatoHelper em
SalvarActivity. Para isso temos que criar uma instância de ContatoHelper, adicionar
o botão salvar e adicionar um Listener de click (faça o import da classe
android.view.View.OnClickListener). Vamos ao código:
26. 16 CAPÍTULO 2. EXEMPLO PRÁTICO
1 /* ... */
2 private ContatoHelper helper;
3 private Button btSalvar;
4
5 @Override
6 public void onCreate(Bundle icicle) {
7 /* ... */
8 helper = new ContatoHelper(this);
9 carregar();
10 ir();
11 /* ... */
12 }
13
14 private void carregar() {
15 /* ... */
16 btSalvar = (Button) findViewById(R.id.bt_salvar);
17 }
18
19 private void ir() {
20 btSalvar.setOnClickListener(new OnClickListener() {
21
22 public void onClick(View view) {
23 ContentValues values = new ContentValues();
24 values.put( "nome" , etNome.getText().toString());
25 values.put( "telefone" , etTefone.getText().toString());
26 values.put( "email" , etEmail.getText().toString());
27 helper.criar(values);
28 finish();
29 }
30 });
31 }
32
33 @Override
34 protected void onDestroy() {
35 super.onDestroy();
36 helper.close();
37 }
Código-fonte 14: Fim da iteração criar contato [SalvarActivity.java]
Com essa implementação já é possível salvar contatos na base de dados.
2.1.5 Mostrando os dados na View
Após salvar os dados no banco, devemos ser capazes de obter tais informações e colocá-
las em forma de Lista. Para isso criaremos um novo layout que será responsável por
representar uma linha de nossa Lista. Essa linha deve ser semelhante a figura abaixo:
27. 2.1. PRIMEIRA APLICAÇÃO - CONTATOS 17
Figura 2.1: Layout linha da Lista
Para isso crie um arquivo chamado linha.xml em res/layout com o seguinte con-
teúdo.
1 <?xml version="1.0" encoding="UTF-8"?>
2 <LinearLayout xmlns:android= "http://schemas.android.com/apk/res/android"
3 android:layout_width= "fill_parent" android:layout_height= "wrap_content"
4 android:orientation= "horizontal" >
5 <ImageView
6 android:id= "@+id/linha_icone" android:layout_width= "wrap_content"
7 android:layout_height= "fill_parent" android:src= "@drawable/ic_launcher" >
8 </ImageView>
9 <LinearLayout
10 android:layout_width= "fill_parent" android:layout_height= "wrap_content"
11 android:orientation= "vertical" >
12 <TextView
13 android:id= "@+id/linha_nome" android:layout_width= "fill_parent"
14 android:layout_height= "wrap_content" android:textStyle= "bold"
15 android:ellipsize= "end" ></TextView>
16 <TextView
17 android:id= "@+id/linha_fone" android:layout_width= "fill_parent"
18 android:layout_height= "wrap_content" ></TextView>
19 <TextView
20 android:id= "@+id/linha_email" android:layout_width= "fill_parent"
21 android:layout_height= "wrap_content" ></TextView>
22 </LinearLayout>
23 </LinearLayout>
Código-fonte 15: Layout para cada linha da lista [res/layout/linha.xml]
Note a possibilidade de aninhar o LinearLayout. Fazendo isso é possível criar o
layout desejado fazendo com que alguns elementos sejam inseridos na horizontal, outros
na vertical.
Outro ponto interessante é o uso de negrito no TextView correspondente ao nome, na li-
nha 14 , e o uso de reticências caso o nome seja maior que a tela usando android:ellipsize="end"
na linha 15 .
28. 18 CAPÍTULO 2. EXEMPLO PRÁTICO
Agora vamos até ContatoHelper e adicionar o método listar. E também adiciona-
remos métodos para facilitar a obtenção dos valores de cada atributo.
1 public Cursor listar() {
2 return getReadableDatabase()
3 .rawQuery( "SELECT _id, nome, fone, email FROM contato ORDER BY nome" ,
4 null);
5 }
6
7 public String getNome(Cursor c) {
8 return c.getString(1);
9 }
10
11 public String getFone(Cursor c) {
12 return c.getString(2);
13 }
14
15 public String getEmail(Cursor c) {
16 return c.getString(3);
17 }
Código-fonte 16: Listar contatos existentes [ContatoHelper.java]
Os elementos de um Cursor são numerados iniciando de 0 (zero). Neste caso o 0 é a
coluna id. Note que ela não será usada pelo programador e sim pelo Android. Isto será
¯
visto com mais detalhes em 2.1.6 Editando dados existentes.
Para popular cada linha de nossa Lista vamos criar uma classe interna (inner class)
em MainActivity. Assim podemos fazer cache dos objetos aumentando a performance.
Use o sufixo Holder para esse tipo de classe.
1 private static class ContatoHolder {
2 private TextView nome, fone, email = null;
3
4 public ContatoHolder(View linha) {
5 nome = (TextView) linha.findViewById(R.id.linha_nome);
6 fone = (TextView) linha.findViewById(R.id.linha_fone);
7 email = (TextView) linha.findViewById(R.id.linha_email);
8 }
9
10 public void popularForm(Cursor c, ContatoHelper helper) {
11 nome.setText(helper.getNome(c));
12 fone.setText(helper.getFone(c));
13 email.setText(helper.getEmail(c));
14 }
15 }
Código-fonte 17: Classe Holder [MainActivity.java]
29. 2.1. PRIMEIRA APLICAÇÃO - CONTATOS 19
Levando em conta que estamos usando a interface Cursor em nosso Helper temos
que criar uma classe que extenda de CursorAdapter que será responsável por definir o
layout de cada linha da Lista. Crie uma classe interna chamada ContatoAdapter. Iremos
sobrescrever dois métodos, newView() e bindView(), que são responsáveis por inflar
(inflate) uma nova linha e reciclar uma linha existente, respectivamente.
1 private ContatoHelper helper;
2 /* ... */
3
4 private class ContatoAdapter extends CursorAdapter {
5
6 public ContatoAdapter(Cursor c) {
7 super(MainActivity.this, c);
8 }
9
10 @Override
11 public View newView(Context cntxt, Cursor cursor, ViewGroup vg) {
12 LayoutInflater inflater = getLayoutInflater();
13 View linha = inflater.inflate(R.layout.linha, vg, false);
14 ContatoHolder holder = new ContatoHolder(linha);
15 linha.setTag(holder);
16 return linha;
17 }
18
19 @Override
20 public void bindView(View view, Context cntxt, Cursor cursor) {
21 ContatoHolder holder = (ContatoHolder) view.getTag();
22 holder.popularForm(cursor, helper);
23 }
24 }
Código-fonte 18: Classe Adapter [MainActivity.java]
Com a introdução do Helper teremos que criar uma instância da classe Cursor para
popular nossa ListView. Vamos ao código-fonte:
30. 20 CAPÍTULO 2. EXEMPLO PRÁTICO
1 /* ... */
2 private Cursor model = null;
3 private ContatoAdapter adapter = null;
4 private ListView listView = null;
5
6 @Override
7 public void onCreate(Bundle icicle) {
8 /* ... */
9 helper = new ContatoHelper(this);
10 carregar();
11 }
12
13 private void carregar() {
14 listView = (ListView) findViewById(R.id.lv_contatos);
15 model = helper.listar();
16 startManagingCursor(model);
17 adapter = new ContatoAdapter(model);
18 listView.setAdapter(adapter);
19 }
20
21 @Override
22 protected void onDestroy() {
23 super.onDestroy();
24 model.close();
25 helper.close();
26 }
Código-fonte 19: Popular ListView [MainActivity.java]
Nunca esquecendo de fechar o helper ao sair, pois assim garantimos que a conexão
com o banco será fechada.
2.1.6 Editando dados existentes
Para a edição de informações usaremos o mesmo Activity do criar, ou seja, SalvarActivity.
Para isso precisamos passar um parâmetro para o Activity. Usaremos então um método
do Intent que é responsável por isso, putExtra(chave, valor).
Para uma passagem de parâmetros segura devemos usar um namespace para que não
colida com nenhum nome já utilizado pelo Android. Assim, vamos criar uma variável
estática do tipo String. Isso acontecerá quando o usuário pressionar a linha que ele
deseja editar. Podemos fazer isso utilizando a interface OnItemClickListener.
Vamos incrementar também o método irParaSalvar passando o parâmetro caso haja
um. Vamos ao código:
31. 2.1. PRIMEIRA APLICAÇÃO - CONTATOS 21
1 /* ... */
2 public static final String _ID = "contatos.app._ID" ;
3
4 @Override
5 public void onCreate(Bundle icicle) {
6 /* ... */
7 configurar();
8 }
9
10 private void irParaSalvar() {
11 irParaSalvar(null);
12 }
13
14 private void irParaSalvar(String id) {
15 Intent intent = new Intent(MainActivity.this, SalvarActivity.class);
16 if (id != null) {
17 intent.putExtra(_ID, id);
18 }
19 startActivity(intent);
20 }
21
22 private void configurar() {
23 listView.setOnItemClickListener(new OnItemClickListener() {
24 public void onItemClick(AdapterView<?> parent, View view,
25 int position, long id) {
26 irParaSalvar(String.valueOf(id));
27 }
28 });
29 }
Código-fonte 20: Passagem de parâmetros [MainActivity.java]
Agora é hora de tratar nosso parâmetro no SalvarActivity. Caso haja um parâmetro
precisamos obter os dados existentes no banco de dados para então editá-lo. Neste caso
precisaremos de mais dois métodos em ContatoHelper, que são ler e atualizar.
1 public Cursor ler(String id) {
2 return getReadableDatabase().rawQuery( "SELECT _id, nome, telefone, " +
3 "email FROM contato WHERE _id = ?" , new String[]{id});
4 }
5
6 public void atualizar(String id, ContentValues values) {
7 getWritableDatabase().update( "contato" , values, "_id = ?" , new String[]{id});
8 }
Código-fonte 21: Ler e atualizar dados existentes [ContatoHelper.java]
32. 22 CAPÍTULO 2. EXEMPLO PRÁTICO
O próximo passo é tratar no SalvarActivity caso o parâmetro tenha sido enviado
ou não. Caso positivo devemos carregar os dados existentes no banco de dados e depois
atualizá-los.
1 /* ... */
2 private String contatoId = null;
3
4 private void carregar() {
5 /* ... */
6 contatoId = getIntent().getStringExtra(MainActivity._ID);
7 if (contatoId != null) {
8 carregarContato();
9 }
10 }
11
12 private void carregarContato() {
13 Cursor cursor = helper.ler(contatoId);
14 cursor.moveToFirst();
15 etNome.setText(helper.getNome(cursor));
16 etFone.setText(helper.getFone(cursor));
17 etEmail.setText(helper.getEmail(cursor));
18 cursor.close();
19 }
20
21 private void ir() {
22 btSalvar.setOnClickListener(new OnClickListener() {
23 public void onClick(View view) {
24 ContentValues values = new ContentValues();
25 values.put( "nome" , etNome.getText().toString());
26 values.put( "telefone" , etTefone.getText().toString());
27 values.put( "email" , etEmail.getText().toString());
28 if (contatoId == null) {
29 helper.criar(values);
30 } else {
31 helper.atualizar(contatoId, values);
32 }
33 finish();
34 }
35 });
36 }
Código-fonte 22: Usando Activity para criar ou atualizar [SalvarActivity.java]
Com isso encerramos um CRUD básico, mas completo. A seguir temos implementa-
ções mais específicas que irão tornar nossa aplicação mais profissional.
33. Capítulo 3
Livro de Receitas
3.1 Mostrando Diálogos
No Android, podemos criar diálogos no Activity mostrando opções ao usuário, como por
exemplo, escolher itens de uma lista, ou responder sim ou não a uma ação, etc.
Vamos incrementar algumas partes de nosso código e tentar encaixar algumas funcio-
nalidades relacionadas.
3.1.1 Editar/Excluir ao clicar e segurar na ListView
Vamos implementar uma ação comum no mundo Android, que é a seguinte: ao clicar e
segurar num item da ListView, ele mostra opções editar e excluir, por exemplo. Isto pode
ser feito facilmente usando AlertDialog.Builder, uma classe com métodos pré-prontos
para serem usados por você.
Neste exemplo, precisaremos editar ContatoHelper e adicionar um método para de-
letar um contato, editar nosso MainActivity no método configurar e adicionar um
Listener que ao clicar e segurar num item da ListView um método é acionado. Vamos a
implementação:
1 public int deletar(String id) {
2 String whereClause = "_id = ?" ;
3 String[] whereArgs = {id};
4 return getWritableDatabase().delete( "contato" , whereClause, whereArgs);
5 }
Código-fonte 23: Deletar dados existentes [ContatoHelper.java]
23
34. 24 CAPÍTULO 3. LIVRO DE RECEITAS
1 /* ... */
2 private void configurar() {
3 /* ... */
4 listView.setOnItemLongClickListener(new OnItemLongClickListener() {
5 public boolean onItemLongClick(AdapterView<?> parent, View view,
6 int position, final long id) {
7 final String[] itens = { "Editar" , "Deletar" };
8 AlertDialog.Builder dialogo =
9 new AlertDialog.Builder(MainActivity.this);
10 dialogo.setTitle( "Opções" );
11 dialogo.setItems(itens, new OnClickListener() {
12 public void onClick(DialogInterface dialog, int which) {
13 switch (which) {
14 case 0: // editar
15 irParaSalvar(String.valueOf(id));
16 break;
17 case 1: // deletar
18 int linhasAfetadas = helper.deletar(String.valueOf(id));
19 if (linhasAfetadas > 0) {
20 exibirMensagem( "Contatos deletado com sucesso." );
21 carregar();
22 } else {
23 exibirMensagem( "Falha ao deletar contato." );
24 }
25 break;
26 }
27 }
28 });
29 dialogo.show();
30 return true;
31 }
32 });
33 }
34
35 private void exibirMensagem(String mensagem) {
36 Toast.makeText(this, mensagem, Toast.LENGTH_LONG).show();
37 }
Código-fonte 24: Adicionar Listener para click longo [MainActivity.java]
Note a necessidade de um novo método em MainActivity, o exibirMensagem. Ele é
bastante útil quando se quer exibir uma mensagem rapidamente e depois ela suma. Para
isso usamos a classe Toast.
35. 3.1. MOSTRANDO DIÁLOGOS 25
Interface como parâmetro de um método
Você já deve ter notado o uso de interface’s como parâmetro dos métodos, por exemplo
na linha 4 e 11 do código acima. Essa prática obriga ao programador implementar a
classe na passagem dos parâmetros.
Essa ideia vem de algumas linguagens de programação que possuem funções como
parâmetros para outras funções. Como o Java não suporta essa característica, a solução
veio em forma de uma interface, a qual o programador é obrigado a implementar seus
métodos. Com isso o método que recebe a interface como parâmetro sabe exatamente o
que ela tem disponível.
A partir dessa observação, podemos justificar o uso da palavra reservada final em
alguns parâmetros dos métodos acima. Isso acontece porque alguns parâmetros são utili-
zados dentro da implementação das interface’s.
Caso haja a necessidade de utilizar uma implementação em outra classe você pode criar
uma classe que implementa uma interface, por exemplo a interface OnItemLongClickListener.
Daí para a passagem do parâmetro apenas crie uma instância da classe. Por exemplo, supo-
nha que você tenha uma classe chamada OpcoesContato que implementa OnItemLongClickListener,
nesse caso a linha 4 se tornaria:
listView.setOnItemLongClickListener(new OpcoesContato());
3.1.2 Diálogo de confirmação
Deletar dados é uma ação que deve ser feita com cuidado, então sempre é bom confirmar
com o usuário se ele deseja realmente deletar, no nosso caso, um contato. Para isso
usaremos o AlertDialog.Builder mais uma vez, agora apenas com uma mensagem e os
botões Sim ou Não.
Ainda em MainActivity criaremos um outro AlertDialog.Builder no momento que
o usuário clicar em Deletar. Segue o trecho:
36. 26 CAPÍTULO 3. LIVRO DE RECEITAS
1 /* ... */
2 private void configurar() {
3 /* ... */
4 listView.setOnItemLongClickListener(new OnItemLongClickListener() {
5 public boolean onItemLongClick(AdapterView<?> parent, View view,
6 int position, final long id) {
7 /* ... */
8 dialogo.setItems(itens, new OnClickListener() {
9 public void onClick(DialogInterface dialog, int which) {
10 switch (which) {
11 case 0: // editar
12 irParaSalvar(String.valueOf(id));
13 break;
14 case 1: // deletar
15 AlertDialog.Builder confirmacao =
16 new AlertDialog.Builder(MainActivity.this);
17 confirmacao.setTitle( "Deletar" );
18 confirmacao.setMessage( "Deseja realmente deletar este contato?" );
19 confirmacao.setPositiveButton( "Sim" , new OnClickListener() {
20 public void onClick(DialogInterface dialog, int which) {
21 int linhasAfetadas = helper.deletar(String.valueOf(id));
22 if (linhasAfetadas > 0) {
23 exibirMensagem( "Contatos deletado com sucesso." );
24 carregar();
25 } else {
26 exibirMensagem( "Falha ao deletar contato." );
27 }
28 }
29 });
30 confirmacao.setNegativeButton( "Não" , null);
31 confirmacao.show();
32 break;
33 }
34 }
35 });
36 dialogo.show();
37 return true;
38 }
39 });
40 }
Código-fonte 25: Diálogo de confirmação ao deletar contato [MainActivity.java]
Pronto, agora o trecho que deleta o contato foi movido para dentro do Listener do
botão Sim. No botão Não passamos null no Listener, pois caso seja a opção escolhida
apenas fazemos nada. Você pode se quiser criar um Listener e mostrar uma mensagem
do tipo, Cancelado pelo usuário, para isso usando o método exibirMensagem.
37. 3.1. MOSTRANDO DIÁLOGOS 27
3.1.3 Entrada de diferentes tipos de dados
O Android foi desenvolvido com muitos recursos pré-prontos para facilitar o desenvolvi-
mento de aplicações. Um recurso bastante útil é a distinção dos dados que irão ser inseridos
nos TextView’s. Com isso o teclado virtual do cliente se adapta ao tipo de dado que será
inserido. No nosso caso faremos distinção do campo telefone, onde apenas números e
hífens (-) podem ser inseridos, e o campo e-mail onde a presença do arroba (@) e pontos
(.) são elementos essenciais.
Vejamos alguns valores aceitos pelo inputType:
Para textos:
text
textCapCharacters
textMultiLine
textUri
textEmailAddress
textPersonName
textPassword
textVisiblePassword
Para números:
number
numberSigned
numberDecimal
phone
datetime
date
time
Precisaremos alterar apenas o salvar.xml localizado em res/layout. Localize o
atributo inputType dos campos telefone e e-mail e altere os valores da seguinte maneira:
38. 28 CAPÍTULO 3. LIVRO DE RECEITAS
1 <!-- ... -->
2 <TableRow android:id= "@+id/tableRow2"
3 android:layout_width= "wrap_content"
4 android:layout_height= "wrap_content" >
5 <TextView android:id= "@+id/textView2"
6 android:layout_width= "wrap_content"
7 android:layout_height= "wrap_content"
8 android:text= "Telefone:" ></TextView>
9 <EditText android:layout_width= "wrap_content"
10 android:layout_height= "wrap_content"
11 android:id= "@+id/et_telefone"
12 android:inputType= "phone" ></EditText>
13 </TableRow>
14 <TableRow android:id= "@+id/tableRow3"
15 android:layout_width= "wrap_content"
16 android:layout_height= "wrap_content" >
17 <TextView android:id= "@+id/textView3"
18 android:layout_width= "wrap_content"
19 android:layout_height= "wrap_content"
20 android:text= "E-mail:" ></TextView>
21 <EditText android:layout_width= "wrap_content"
22 android:layout_height= "wrap_content"
23 android:id= "@+id/et_email"
24 android:inputType= "textEmailAddress" ></EditText>
25 </TableRow>
26 <!-- ... -->
Código-fonte 26: Distinção de dados [res/layout/salvar.xml]
3.1.4 Validação de dados
Mesmo configurando um inputType para seu TextView pode não ser o bastante para
que os dados inseridos estejam corretos. Para isso usaremos a classe Patterns do pacote
android.util. Nela podemos encontrar alguns objetos bastante úteis na hora de validar
dados. Entre eles estão os objetos Patterns.EMAIL ADDRESS e Patterns.PHONE. Com
¯
eles podemos validar de forma simples os dados inseridos em nosso formulário.
Em nosso SalvarActivity adicionaremos um método validar passando como pa-
râmetro um ContentValues. Copie o método exibirMensagem da classe MainActivity
para mostrar uma mensagem caso alguma validação seja falsa.
OBS: Para um melhor reuso crie uma classe abstrata que implementa o método exibirMensagem
e que extenda de Activity e faça com que seus Activity’s herdem dela. É uma boa prá-
tica.
Vamos ao trecho de código:
39. 3.1. MOSTRANDO DIÁLOGOS 29
1 /* ... */
2 private void ir() {
3 btSalvar.setOnClickListener(new OnClickListener() {
4
5 public void onClick(View view) {
6 ContentValues values = new ContentValues();
7 values.put( "nome" , etNome.getText().toString());
8 values.put( "telefone" , etTefone.getText().toString());
9 values.put( "email" , etEmail.getText().toString());
10 if (validar(values)) {
11 if (contatoId == null) {
12 helper.criar(values);
13 } else {
14 helper.atualizar(contatoId, values);
15 }
16 finish();
17 }
18 }
19 });
20 }
21
22 private boolean validar(ContentValues values) {
23 if (!Patterns.PHONE.matcher(values.getAsString( "telefone" )).matches()) {
24 exibirMensagem( "Telefone não é válido." );
25 return false;
26 }
27
28 if (!Patterns.EMAIL_ADDRESS.matcher(values.getAsString( "email" )).matches()) {
29 exibirMensagem( "E-mail não é válido." );
30 return false;
31 }
32 return true;
33 }
34
35 private void exibirMensagem(String mensagem) {
36 Toast.makeText(this, mensagem, Toast.LENGTH_LONG).show();
37 }
38 /* ... */
Código-fonte 27: Validação dos dados [SalvarActivity.java]
3.1.5 Fazendo uma ligação
Já que estamos fazendo uma lista de contatos nada melhor que usar o número do telefone
dos contatos inseridos para realizar chamadas. Para isso vamos aprender um pouco sobre
Permissões.
Permissões no Android são definidas no AndroidManifest.xml. Ao instalar seu aplica-
40. 30 CAPÍTULO 3. LIVRO DE RECEITAS
tivo, o usuário saberá quais as permissões que o seu aplicativo necessita para ser executado.
Por padrão, o Android traz uma série de permissões que auxiliam seu aplicativo a se
comunicar com o aparelho. Abaixo alguns exemplos:
Verificação
ACCESS NETWORK STATE
¯ ¯
ACCESS WIFI STATE
¯ ¯
BATTERY STATS
¯
Comunicação
BLUETOOTH
CALL PHONE
¯
INTERNET
SEND SMS
¯
A lista completa pode ser vista em http://developer.android.com/reference/
android/Manifest.permission.html.
Edite o AndroidManifest.xml e adicione a permissao CALL PHONE.
¯
1 <?xml version="1.0" encoding="UTF-8"?>
2 <manifest xmlns:android= "http://schemas.android.com/apk/res/android"
3 package= "contatos.app"
4 android:versionCode= "1"
5 android:versionName= "1.0" >
6 <uses-permission android:name= "android.permission.CALL_PHONE" >
7 </uses-permission>
8 <!-- ... -->
9 </manifest>
Código-fonte 28: Permissão de realizar chamadas [AndroidManifest.xml]
Agora vamos adicionar um item ao diálogo que aparece ao clicar e segurar um item
da ListView. Ele servirá para implementarmos o trecho que realiza a chamada. Vamos a
ele:
41. 3.1. MOSTRANDO DIÁLOGOS 31
1 /* ... */
2 private void configurar() {
3 listView.setOnItemLongClickListener(new OnItemLongClickListener() {
4 public boolean onItemLongClick(AdapterView<?> parent, View view,
5 final int position, final long id) {
6 final String[] itens = { "Editar" , "Deletar" , "Chamar" };
7 /* ... */
8 dialogo.setItems(itens, new OnClickListener() {
9 public void onClick(DialogInterface dialog, int which) {
10 switch (which) {
11 /* ... */
12 case 2: // chamar
13 model.moveToPosition(position);
14 startActivity(new Intent(Intent.ACTION_CALL,
15 Uri.parse( "tel:" + helper.getTelefone(model))
16 )
17 );
18 break;
19 }
20 }
21 });
22 dialogo.show();
23 return true;
24 }
25 });
26 }
Código-fonte 29: Item chamar no diálogo [MainActivity.java]
Nesse trecho de código podemos ver o uso de Intent’s do prórpio Android, nesse
caso o Intent.ACTION CALL (veja linha 14 ). Ele serve para chamar uma Activity
¯
que realize ligações. Atente apenas para um detalhe - esse Intent faz a chamada sem
confirmação. Caso você queira que o usuário possa visualizar o número no discador use o
Intent Intent.ACTION DIAL. Faça esse teste e veja a diferença entre os Intent’s.
¯
Veja mais detalhes em http://developer.android.com/reference/android/content/
Intent.html.
42. 32 CAPÍTULO 3. LIVRO DE RECEITAS
3.1.6 Enviando e-mail
Para envio de e-mail você pode simplesmente usar a aplicação de e-mail padrão do apare-
lho. Seguindo o mesmo princípio do exemplo anterior vamos apenas inserir um trecho de
código no método configurar da classe MainActivity:
1 /* ... */
2 private void configurar() {
3 listView.setOnItemLongClickListener(new OnItemLongClickListener() {
4 public boolean onItemLongClick(AdapterView<?> parent, View view,
5 final int position, final long id) {
6 final String[] itens = { "Editar" , "Deletar" , "Chamar" ,
7 "Enviar e-mail" };
8 /* ... */
9 dialogo.setItems(itens, new OnClickListener() {
10 public void onClick(DialogInterface dialog, int which) {
11 switch (which) {
12 /* ... */
13 case 3: // enviar e-mail
14 model.moveToPosition(position);
15 Intent email = new Intent(Intent.ACTION_SEND);
16 email.setType( "plain/text" );
17 email.putExtra(Intent.EXTRA_EMAIL,
18 new String[]{ helper.getEmail(model) });
19 startActivity(Intent.createChooser(email,
20 "Enviar e-mail..." ));
21 break;
22 }
23 }
24 });
25 dialogo.show();
26 return true;
27 }
28 });
29 }
Código-fonte 30: Item enviar e-mail no diálogo [MainActivity.java]
Ao testar no emulador você receberá a mensagem: No applications can perform
this action. Traduzindo quer dizer que: Nenhuma aplicação pode executar esta ação.
Em outras palavras, nenhum cliente de e-mail foi encontrado.
3.2 Internacionalização (i18n)
3.2.1 Forçando região para teste
Para podermos testar as strings de i18n podemos forçar o Activity a utilizar uma
determinada linguagem. Isso se dá por meio da classe Locale. Façamos um teste com o
43. 3.3. UTILIZANDO AS PREFERÊNCIAS DO ANDROID 33
SalvarActivity inserindo o trecho de código abaixo no método onCreate. Vamos a ele:
1 /* ... */
2 @Override
3 protected void onCreate(Bundle savedInstanceState) {
4 /* ... */
5 forceLocale( "pt" , "BR" );
6 carregar();
7 ir();
8 }
9
10 private void forceLocale(String language, String country) {
11 Locale locale = new Locale(language, country);
12 Locale.setDefault(locale);
13 Configuration configuration = new Configuration();
14 configuration.locale = locale;
15 getBaseContext().getResources()
16 .updateConfiguration(configuration,
17 getBaseContext().getResources().getDisplayMetrics());
18 }
Código-fonte 31: Forçando região [SalvarActivity.java]
Para visualizar a mudança crie strings no seu arquivo strings.xml. Substitua as
strings Nome, Telefone, E-mail e Salvar pelos respectivos valores em inglês Name, Phone,
E-mail e Save. Agora crie outro arquivo strings.xml dentro do diretório /res/values-pt-rBR
e insira as mesmas strings citadas anteriormente, traduzindo cada valor.
Faça testes comentando a chamada para a função forceLocale e veja as mudanças.
3.2.2 Forçando região pelo emulador
A maneira mais rápida e prática de forçar a região é pelo próprio emulador. Vá até a
lista de aplicativos e procure por Custom Locale. Depois pesquise por pt BR e caso não
¯
encontre clique em Add New Locale. Digite pt BR e clique em Add and Select.
¯
3.3 Utilizando as Preferências do Android
O Android já disponibiliza uma maneira de criar preferências de forma fácil. Para demons-
trar implementaremos um exemplo bem amplo, que irá nos ajudar a entender ainda mais
de Android. Para começar adicionaremos um nova coluna a nossa tabela contato cha-
mada grupo. Depois adicionaremos um array de string’s ao nosso arquivo strings.xml
e ainda vamos aprender a utilizar um Spinner, também conhecido como combo box. Por
último, e não menos importante, usaremos as preferências para tornar padrão um valor
de nosso Spinner.
44. 34 CAPÍTULO 3. LIVRO DE RECEITAS
3.3.1 Atualizando colunas de uma tabela
Como visto em 2.1.4, a classe SQLiteOpenHelper obriga-nos a implementar os métodos
onCreate e onUpgrade. Neste ponto será necessário o uso do método onUpgrade. Ele
serve, como o nome sugere, para atualizar a DDL do banco de dados. Isso é útil quando
seu cliente já possui uma versão do seu aplicativo instalada e ele quer apenas atualizar
para uma nova versão. Também será necessário adicionar a coluna grupo nas queries.
Abra a classe ContatoHelper em contatos.app.model e faça as modificações:
1 public class ContatoHelper extends SQLiteOpenHelper {
2 /* ... */
3 private static final int VERSION = 2;
4 private static final String TAG = "ContatoHelper" ;
5
6 @Override
7 public void onCreate(SQLiteDatabase db) {
8 db.execSQL( "CREATE TABLE contato ( _id INTEGER PRIMARY KEY AUTOINCREMENT," +
9 "nome TEXT, telefone TEXT, email TEXT," +
10 // versao 2
11 "grupo INTEGER NOT NULL DEFAULT 0 );" );
12 }
13
14 @Override
15 public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
16 Log.w(TAG, "Atualizando banco de dados da versão "
17 + oldVersion + " para " + newVersion + "." );
18 if (newVersion > oldVersion) {
19 switch (oldVersion) {
20 case 2:
21 try {
22 db.execSQL( "ALTER TABLE contato " +
23 "ADD COLUMN grupo INTEGER NOT NULL DEFAULT 0" );
24 } catch (SQLException e) {
25 Log.e(TAG, "Erro ao executar SQL: " , e);
26 }
27 default:
28 Log.w(TAG, "Versão desconhecida: " + oldVersion +
29 ". Criando novo banco de dados." );
30 db.execSQL( "DROP TABLE IF EXISTS contato" );
31 onCreate(db);
32 }
33 }
34 }
35 }
Código-fonte 32: Nova coluna grupo na base de dados [ContatoHelper.java]
45. 3.3. UTILIZANDO AS PREFERÊNCIAS DO ANDROID 35
Vemos neste exemplo o uso da classe Log do pacote android.util. Ela possui apenas
métodos estáticos, assim não precisamos instanciar, apenas faça a chamada dos métodos.
Temos:
Log.w() para mostrar warning’s, ou seja, avisos.
Log.e() para mensagens de erro.
Log.d() para mensagens debug.
Log.i() para mensagens informativas.
Log.v() para outras mensagens.
1 public class ContatoHelper extends SQLiteOpenHelper {
2 /* ... */
3 public Cursor listar() {
4 return getReadableDatabase()
5 .rawQuery( "SELECT _id, nome, telefone, email, grupo " +
6 "FROM contato ORDER BY nome" , null);
7 }
8
9 public int getGrupo(Cursor c) {
10 return c.getInt(4);
11 }
12
13 public Cursor ler(String id) {
14 String[] params = {id};
15 return getReadableDatabase()
16 .rawQuery( "SELECT _id, nome, telefone, email, grupo " +
17 "FROM contato WHERE _id = ?" , params);
18 }
19 }
Código-fonte 33: Modificação nas queries [ContatoHelper.java]
3.3.2 Array de Strings
No arquivo de string’s do Android é possível criar vários recursos. Dentre eles temos
Cor, Dimensão, Estilo/Tema. Usando a ferramenta ADT, crie um String Array em
strings.xml dentro de res/values e adicione alguns itens para representar os valores da
coluna grupo, e outro String Array para representar os índices:
Dica: você pode tentar implementar o trecho usando uma tabela do banco de dados. A
ideia é a mesma, neste caso não seria necessário o uso de String Array’s.
46. 36 CAPÍTULO 3. LIVRO DE RECEITAS
1 <?xml version="1.0" encoding="utf-8"?>
2 <resources>
3 <!-- ... -->
4 <string-array name= "array_grupos" >
5 <item>amigos</item>
6 <item>trabalho</item>
7 <item>conhecidos</item>
8 <item>família</item>
9 </string-array>
10 <string-array name= "index_array_grupos" >
11 <item>0</item><item>1</item>
12 <item>2</item><item>3</item>
13 </string-array>
14 </resources>
Código-fonte 34: Array de Strings [strings.xml]
3.3.3 Spinner, diálogo de seleção
O Spinner é ideal quando temos que escolher entre valores fixos, sejam eles estáticos
ou dinâmicos. Nosso exemplo irá utilizar valores estáticos para popular o mesmo. Para
isso utilizaremos o array grupos que criamos em res/values/strings.xml. Também
¯
veremos um exemplo de uso da classe android.R como visto em 2.1.2 em que é explicado
a diferença entre as classes de recursos. Mas antes temos que atualizar nosso layout
salvar.xml. Adicione o Spinner logo abaixo do e-mail, como mostra o trecho abaixo:
1 <!-- ... -->
2 <TableRow
3 android:id= "@+id/tableRow4"
4 android:layout_width= "wrap_content"
5 android:layout_height= "wrap_content" >
6
7 <TextView
8 android:id= "@+id/textView4"
9 android:layout_width= "wrap_content"
10 android:layout_height= "wrap_content"
11 android:text= "Grupo:" />
12
13 <Spinner
14 android:id= "@+id/sp_grupo"
15 android:layout_width= "wrap_content"
16 android:layout_height= "wrap_content" />
17 </TableRow>
18 <!-- ... -->
Código-fonte 35: Adicionando elemento Spinner [res/layout/salvar.xml]
47. 3.3. UTILIZANDO AS PREFERÊNCIAS DO ANDROID 37
Agora já podemos carregar e popular o Spinner na classe SalvarActivity.
1 public class SalvarActivity extends Activity {
2 /* ... */
3 private Spinner spGrupo = null;
4
5 private void carregar() {
6 /* ... */
7 spGrupo = (Spinner) findViewById(R.id.sp_grupo);
8 ArrayAdapter<CharSequence> adapter =
9 ArrayAdapter.createFromResource(this,
10 R.array.array_grupos, android.R.layout.simple_spinner_item);
11 adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
12 spGrupo.setAdapter(adapter);
13 /* antes de verificar o parâmetro contatoId */
14 }
15
16 private void carregarContato() {
17 spGrupo.setSelection(helper.getGrupo(c));
18 c.close();
19 }
20
21 private void ir() {
22 btSalvar.setOnClickListener(new View.OnClickListener() {
23 /* ... */
24 contato.setGrupo(spGrupo.getSelectedItemPosition());
25 /* antes de validar e salvar */
26 }
27 }
28 }
Código-fonte 36: Utilização de Spinner [SalvarActivity.java]
Note a utilização da classe android.R nas linhas 10 e 11 . Eles servem para definir
o layout do Spinner. Isso quer dizer que você pode implementar como seu Spinner irá
aparecer na tela da mesma maneira que implementamos a linha da ListView em 2.1.5.
3.3.4 A classe PreferenceActivity
Afinal vamos utilizar as preferências do Android. Neste exemplo a usaremos para decidir
qual grupo do array grupos aparecerá selecionado por padrão. A princípio é um exemplo
¯
bem simples, mas que pode ser ajustado para outras finalidades, o que importa realmente
é a ideia.
Para começar criaremos um layout em res/layout chamado preferencias.xml. No
projeto clique com botão direito do mouse e selecione New → Other..., pesquise por
Android XML File e Next. Em Resource Type escolha Preference e escreva preferencias
em File. Logo abaixo em Root Element escolha a opção PreferenceScreen, então
48. 38 CAPÍTULO 3. LIVRO DE RECEITAS
Finish.
Utilizando a ferramenta ADT adicione um elemento ListPreference a PreferenceScreen.
Defina os parâmetros necessários como mostra o código abaixo:
1 <?xml version="1.0" encoding="utf-8"?>
2 <PreferenceScreen xmlns:android= "http://schemas.android.com/apk/res/android" >
3 <ListPreference
4 android:summary= "Selecione o grupo padrão"
5 android:dialogTitle= "Escolha um Grupo"
6 android:entries= "@array/array_grupos"
7 android:entryValues= "@array/index_array_grupos"
8 android:key= "lista_grupos"
9 android:title= "Grupos" />
10 </PreferenceScreen>
Código-fonte 37: XML descrevendo layout de preferências [res/xml/preferencias.xml]
Crie uma nova classe chamada EditarPreferencias em contatos.app.view her-
dando de PreferenceActivity. Agora de uma maneira bem simples implementaremos
essa classe. Veja:
1 package app.contatos.view;
2
3 import android.os.Bundle;
4 import android.preference.PreferenceActivity;
5 import app.contatos.R;
6
7 public class EditarPreferencias extends PreferenceActivity {
8
9 @Override
10 protected void onCreate(Bundle savedInstanceState) {
11 super.onCreate(savedInstanceState);
12 addPreferencesFromResource(R.xml.preferencias);
13 }
14 }
Código-fonte 38: Activity para mostrar preferências [EditarPreferencias.java]
Para chamar a nova Activity temos ainda que mapeá-la no AndroidManifest e criar
um item no menu.
1 <activity android:name= ".view.EditarPreferencias" ></activity>
Código-fonte 39: Mapeando Activity EditarPreferencias [AndroidManifest.xml]
49. 3.3. UTILIZANDO AS PREFERÊNCIAS DO ANDROID 39
1 <?xml version="1.0" encoding="utf-8"?>
2 <menu xmlns:android= "http://schemas.android.com/apk/res/android" >
3 <!-- ... -->
4 <item
5 android:id= "@+id/menu_pref"
6 android:icon= "@android:drawable/ic_menu_preferences"
7 android:title= "Preferências" >
8 </item>
9 </menu>
Código-fonte 40: Adicionar item Preferências ao menu principal
[res/menu/main menu.xml]
¯
Agora que adicionamos um item ao menu, temos que capturar o evento quando o
usuário o selecionar e direcioná-lo às Preferências. Isso deve ser feito em MainActivity.
1 /* ... */
2 @Override
3 public boolean onOptionsItemSelected(MenuItem item) {
4 if (item.getItemId() == R.id.menu_add) {
5 irPara(SalvarActivity.class);
6 return true;
7 } else if (item.getItemId() == R.id.menu_pref) {
8 irPara(EditarPreferencias.class);
9 return true;
10 }
11 return super.onOptionsItemSelected(item);
12 }
13
14 private void irPara(Class<?> clazz) {
15 irPara(clazz, null);
16 }
17
18 private void irPara(Class<?> clazz, String id) {
19 Intent intent = new Intent(MainActivity.this, clazz);
20 if (id != null) {
21 intent.putExtra(_ID, id);
22 }
23 startActivity(intent);
24 }
Código-fonte 41: Ir para Preferências pelo menu principal [MainActivity.java]
Note que para ter um código mais eficiente e otimizado tivemos que mudar o método
irParaSalvar para irPara passando como parâmetro a classe que desejamos ir. Essa
mudança é boa mais causa um impacto em outros trechos do código. Conserte-os da
50. 40 CAPÍTULO 3. LIVRO DE RECEITAS
seguinte maneira:
1 /* ... */
2 private void configurar() {
3 listView.setOnItemClickListener(new OnItemClickListener() {
4 public void onItemClick(AdapterView<?> parent, View view,
5 int position, long id) {
6 irPara(SalvarActivity.class, String.valueOf(id));
7 }
8 });
9
10 listView.setOnItemLongClickListener(new OnItemLongClickListener() {
11 public boolean onItemLongClick(AdapterView<?> parent, View view,
12 final int position, final long id) {
13 /* ... */
14 public void onClick(DialogInterface dialog, int which) {
15 switch (which) {
16 case 0: // editar
17 irPara(SalvarActivity.class, String.valueOf(id));
18 break;
19 /* ... */
20
21 }
22 }
23 }
24 }
25 }
Código-fonte 42: Mudança em método irParaSalvar [MainActivity.java]
Por fim temos que selecionar o item que o usuário quer que esteja selecionado por
padrão ao inserir um novo contato. Assim, em SalvarActivity adicione o trecho:
1 private void carregar() {
2 /* ... */
3 contatoId = getIntent().getStringExtra(MainActivity._ID);
4 if (contatoId != null) {
5 carregarContato();
6 } else {
7 SharedPreferences preferencias =
8 PreferenceManager.getDefaultSharedPreferences(this);
9 spGrupo.setSelection(
10 Integer.parseInt(preferencias.getString( "lista_grupos" , "0" )));
11 }
12 }
Código-fonte 43: Obtem o valor padrão definido nas Preferências [SalvarActivity.java]
51. 3.4. GRUPO DE CONTATOS USANDO GRID 41
3.4 Grupo de Contatos usando Grid
Uma das coisas mais legais quando falamos de aparelhos móveis é a ideia da visão da lista
de aplicativos usada comumente com o ícone e o texto logo abaixo. Essa ideia pode ser
facilmente implementada em um aplicativo Android usando GridView.
Nessa implementação vamos criar uma tela que mostra os grupos de contatos em forma
de Grid e ao clicar levaremos o usuário a lista de contatos mostrando apenas aqueles
contatos de um determinado grupo.
3.4.1 Layout usando GridView
Para começar criaremos um layout em res/layout chamado grupos item.xml. Ele irá
¯
conter a imagem e o texto que serão exibidos no GridView. Faça como mostra o trecho
abaixo:
1 <?xml version="1.0" encoding="utf-8"?>
2 <LinearLayout xmlns:android= "http://schemas.android.com/apk/res/android"
3 android:layout_width= "fill_parent"
4 android:layout_height= "match_parent"
5 android:gravity= "center"
6 android:orientation= "vertical" >
7
8 <ImageView
9 android:id= "@+id/iv_icone"
10 android:layout_width= "wrap_content"
11 android:layout_height= "96.0dip"
12 android:scaleType= "fitCenter" />
13
14 <TextView
15 android:id= "@+id/tv_texto"
16 android:layout_width= "fill_parent"
17 android:layout_height= "wrap_content"
18 android:layout_marginBottom= "20.0dip"
19 android:layout_marginTop= "2.0dip"
20 android:gravity= "center"
21 android:text= "TextView"
22 android:textAppearance= "?android:textAppearanceMedium" />
23 </LinearLayout>
Código-fonte 44: Item do Layout de Grupos [res/layout/grupos item.xml]
¯
Hora de criar o GridView. Para isso crie um novo layout em res/layout chamado
grupos.xml. Adicione apenas um GridView como mostra o trecho de código abaixo:
52. 42 CAPÍTULO 3. LIVRO DE RECEITAS
1 <?xml version="1.0" encoding="utf-8"?>
2 <LinearLayout xmlns:android= "http://schemas.android.com/apk/res/android"
3 android:layout_width= "match_parent"
4 android:layout_height= "match_parent"
5 android:orientation= "vertical" >
6
7 <GridView
8 android:id= "@+id/gv_grupos"
9 android:layout_width= "match_parent"
10 android:layout_height= "wrap_content"
11 android:numColumns= "3" >
12 <!-- Preview: listitem=@layout/grupos_item -->
13 </GridView>
14
15 </LinearLayout>
Código-fonte 45: Layout de Grupos [res/layout/grupos.xml]
Dica: a ferramenta ADT provê uma forma de pré-visualizar seu layout. Note que na
linha 12 temos um comentário e nele temos a referência ao layout grupos item. Para
¯
isso apenas clique com botão direito do mouse na GridView e na opção Preview Grid
Content → Choose Layout... selecione grupos item.
¯
3.4.2 Activity para visualizar os Grupos
Como é de se imaginar temos que criar uma Activity para visualizar os Grupos.
1 public class GruposActivity extends Activity {
2
3 private GridView grid = null;
4
5 @Override
6 protected void onCreate(Bundle savedInstanceState) {
7 super.onCreate(savedInstanceState);
8
9 setContentView(R.layout.grupos);
10 carregar();
11 }
12
13 private void carregar() {
14 grid = (GridView) findViewById(R.id.gv_grupos);
15 }
16 }
Código-fonte 46: Activity para visualizar Grupos [GruposActivity.java]
53. 3.4. GRUPO DE CONTATOS USANDO GRID 43
Temos que criar duas classes internas para nos ajudar a criar cada item do grupo de
contatos. Para isso usaremos a classe abstrata BaseAdapter.
1 /* ... */
2 static class IconeAdapter extends BaseAdapter {
3
4 private Context context;
5
6 public IconeAdapter(Context context) {
7 super();
8 this.context = context;
9 }
10
11 static class GruposHolder {
12 public ImageView icone;
13 public TextView texto;
14 }
15
16 public int getCount() {
17 return 0;
18 }
19
20 public Object getItem(int position) {
21 return null;
22 }
23
24 public long getItemId(int position) {
25 return 0;
26 }
27
28 public View getView(int position, View convertView, ViewGroup parent) {
29 return null;
30 }
31 }
Código-fonte 47: Adapter responsável por cada item do Grid [GruposActivity.java]
Nesse momento precisamos usar a ferramenta Inkscape e criar alguns ícones. Para os
exemplos a seguir você deve criar um ícone para cada item do grupo, sendo eles:
amigos
trabalho
conhecidos
família