1. O documento fornece instruções passo a passo para criar um projeto Android inicial no Eclipse, definindo sua estrutura de arquivos e configurações.
2. É explicada a estrutura e função de arquivos importantes como main.xml para a interface, strings.xml para constantes de texto, e AndroidManifest.xml para configurações.
3. A classe ProjetoAulaActivity é apontada como responsável por lidar com a lógica por trás da interface definida em main.xml, seguindo o padrão MVC do Android.
2. Treinamento Android
Pág.: 2 de 96
Projeto Introdutório Android
Passo 01
Execute a IDE do Eclipse para início do primeiro projeto Android. Ver Figura 01.
Figura 01
Passo 02
Acessando o menu File | New | Project, ao se abrir a caixa de dialogo New no nó Android escolha Android
Project conforme Figura 02, clicando em Next para prosseguir.
Conforme Figura 03, defina em Project Name um nome para o projeto. Aqui adotaremos ProjetoAula.
Ainda neta interface, Figura 03, desmarque a opção Use default location, clicando em seguida no botão
Browser para escolhe um diretório de seu domínio para armazenar os fontes do projeto.
Figura 02
Figura 03
3. Treinamento Android
Pág.: 3 de 96
Após definir o diretório do projeto, conforme Figura 05 demonstra, clique no botão Next para avançar.
Figura 04
Figura 05
Passo 03
Selecione a versão do Framework Android desejável, aqui, estamos trabalhando com a API Android 4.0.3
(Figura 06) mas naturalmente, se instalado previamente poderíamos adotar uma outra versão.
Conforme demonstrado na caixa de dialogo representada pela Figura 07, no campo Package Name defina
um nome para a NameSpace do projeto. Aqui adotamos Android.Aula por questões didáticas.
Repare ainda que devemos definir um nome para a primeira Activity (página ou tela se preferir) do projeto.
Clique no botão Finish para encerrar. Por hora basta.
Figura 06
Figura 07
4. Treinamento Android
Pág.: 4 de 96
Analisando a Estrutura de Arquivos de um Projeto Android
Primeiro observe a caixa de dialogo Project Explore com a estrutura de diretórios do projeto (Figura 01). Na
sequência, definirmos alguns aspectos importantes sobre alguns arquivos nestes diretórios.
Figura 01
Item 01 - Arquivo main.xml – diretório ProjetoAula | res | layout
Selecionando este arquivo no diretório indicado, temos duas visões do mesmo no projeto no projeto. A
primeira, que pode ser observada na Listagem 01, corresponde a implementação em XML dos controles
existente na página. O comentário de cada instrução está na Tabela 01.
Listagem 01
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="fill_parent"
5.
android:orientation="vertical" >
6.
7.
<TextView
8.
android:layout_width="fill_parent"
9.
android:layout_height="wrap_content"
10.
android:text="@string/hello" />
11.
12.
</LinearLayout>
5. Treinamento Android
Pág.: 5 de 96
Tabela 01
Linha
Comentário
2
Abertura Tag LinearLayout, definindo o tipo de layout da página.
3
Propriedade que define a largura útil da página igual a totalidade da largura da device.
4
Propriedade que define a altura útil da página igual a totalidade da altura da device.
5
Propriedade que define que os componentes dentro da Tag LinearLayout serão acomodados na
vertical. Assim, controles aplicados a esta Tag, serão apresentados na ordem em que são colocados
neste arquivo.
7
Abertura da Tag que representa um controle de texto, semelhante ao controle Label de outras
tenologias.
8
Propriedade que define que o controle utilizará toda a área do Device no tocante a largura.
9
Propriedade que define que a altura do controle vai acompanhar a quantidade de texto atribuído a
ele, havendo quebra de linha quantas vezes for necessário para acomodar tal texto.
10
Define o texto apresentado pela Tag TextView. Ná prática, é atribuído a propriedade texto do
controle, uma referência a uma variável de escopo de projeto constante no arquivo strings.XML que
apresentaremos na sequência.
A segunda visão que temos do arquivo main.xml, é no modo gráfico, conforme Figura 02. Nela podemos
aplicar visualmente controles no bom e velho conceito de “clicar e arrastar”.
Repara na parte inferior da tela as abas Graphical Layout e main.xml, onde alternamos entre o modo gráfico
e texto, e ainda, no lado esquerdo e direito, respectivamente lista de controles e área de design.
Figura 02
6. Treinamento Android
Pág.: 6 de 96
Para efeito de teste, observe a Figura 03 e Listagem 02 após aplicação de um controle Button a página main
no modo gráfico. Procedendo ao contrário, ou seja, digitar o código de qualquer Tag dentro da Tag
LinearLayout (no modo texto), promove também a apresentação do mesmo no modo gráfico.
Promova alguns teste e vamos em frente.
Figura 03
Listagem 02
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="fill_parent"
5.
android:orientation="vertical" >
6.
7.
<TextView
8.
android:layout_width="fill_parent"
9.
android:layout_height="wrap_content"
10.
android:text="@string/hello" />
11.
12.
<Button
13.
android:id="@+id/button1"
14.
android:layout_width="130dp"
15.
android:layout_height="wrap_content"
16.
android:text="Button" />
17.
18.
</LinearLayout>
7. Treinamento Android
Pág.: 7 de 96
Item 02 - Arquivo strings.xml – diretório ProjetoAula | res | values
Neste arquivo do projeto mantemos as constantes do projeto. Na forma de Tag String dentro da Tag
Resource, onde existe um elemento com um nome e um conteúdo, estes valores são utilizados nas Views,
na verdade, atribuído normalmente a propriedade Text de controles. Por padrão, O Android reconhece que
referência a constantes dentro do código XML de uma View sempre estão presente neste arquivo.
O seguinte exemplo define uma constante com nome “msg_bateria_esgotada”, que quando atribuído a
propriedade Text de um controle, exibe o texto “A bateria do aparelho está se esgotando.”
<string name="msg_bateria_esgotada">A bateria do aparelho está se esgotando.</string>
Um exemplo de uso desta constante pode ser observado no trecho de código a seguir, extraído da página
main.xml do nosso projeto de exemplo. Neste código, é atribuído a propriedade Text do controle (Tag)
TextView não nomeado, uma referência ao tipo String (@string) e a qual constante de strings.xml deve ser
recuperado o valor (texto).
android:text="@string/hello"
Neste exemplo, o texto que será exibido pelo controle é “Hello World, ProjetoAulaActivity!”, mas claro,
podemos alterar este valor para a língua portuguesa por questões de comunicação. Confira esta instrução
na linha 10 da Listagem 02, conferindo a definição da constante na linha 04 da Listagem 03 que se segue.
Listagem 03
1.
<?xml version="1.0" encoding="utf-8"?>
2.
<resources>
3.
4.
5.
<string name="hello">Hello World, ProjetoAulaActivity!</string>
<string name="app_name">ProjetoAula</string>
</resources>
Além da visão texto do arquivo strings.xml, podemos, conforme Figura 04, visualizar e manter (adicionar,
alterar e remover) constantes deste arquivo utilizando a interface visual. Confira!
Figura 04
8. Treinamento Android
Pág.: 8 de 96
Item 03 - Diretórios drawable – diretório ProjetoAula | res | drawables-hdpi (ver outros)
Nestes diretório são armazenados as imagens utilizadas na interface das páginas do projeto. Como
exemplo, vamos digitar instrução que se segue na Tag Button nomeado como button1:
android:background="@drawable/ic_launcher"
Confira o código final no arquivo consultando a Listagem 04 (arquivo main.xml) e o efeito imediato na visão
Graphial Layout, demonstrado pela Figura 05.
Listagem 04
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="fill_parent"
5.
6.
android:orientation="vertical" >
7.
<TextView
8.
9.
10.
// Código omitido aqui
<Button
11.
android:id="@+id/button1"
12.
android:layout_width="138dp"
13.
android:layout_height="wrap_content"
14.
15.
android:background="@drawable/ic_launcher" />
16.
</LinearLayout>
Figura 05
9. Treinamento Android
Pág.: 9 de 96
Item 04 - Arquivo ProjetoAulaActivity.java – Diretório ProjetoAula | src | Android.Aula
O arquivo (classe) ProjetoAulaActivity.java é a Controller da View main.xml no melhor do padrão MVC.
Naturalmente, toda lógica associado a View main.xml, para seu funcionamento fica implementado ai em
código Java.
Confira o código na Listagem 05 e os comentários de cada linha na Tabela 02.
Listagem 05
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
package Android.Aula;
import android.app.Activity;
import android.os.Bundle;
public class ProjetoAulaActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}
Tabela 02
Linha
Comentário
1
Referencia a que pacote (namespace) a classe pertence.
3
Import que referencia a classe Activity, que implementa métodos de uma Activity (atividade).
4
Import que referencia a classe Bundle (pacote) que permite referenciar objetos da View main.xml.
6
Define a classe como púlica extendendo-a com Activity.
8
Assinala que o método que segue a instrução será substituirá o método padrão da classe.
9
Assinatura do método onCreate da classe ProjetoAulaActivity.
10
Invoca o método onCreate da superclasse passando o mesmo Bundle como parâmetro.
11
Renderiza a View main.xml, referenciada a partir da classe “R”. Abordaremos a classe “R” na
sequência.
10. Treinamento Android
Pág.: 10 de 96
Item 05 - Classe R – Diretório ProjetoAula | gen | Android.Aula | R.java
É importante notar que a classe R é manipulada pelo plugin ADT. Quando se coloca qualquer arquivo no
diretório res o plugin altera a classe R. java no diretório gen adicionando o ID do recurso à classe. Se você
remover ou alterar qualquer recurso o R.java é automaticamente atualizado.
A lista a seguir representa as constantes
de cada recurso conforme definido. A
Figura 06 exibe esta estrutura, e, a
Listagem 06 apresenta o código que
expressa tais constantes.
R.drawable.nome_imagem
R.layout.nome_layout
R.string.nome_string
R.color.red
R.dimen.espaco
R.array.nome_array
R.style.nome_estilo
Figura 06
Listagem 06
1.
package Android.Aula;
2.
public final class R {
3.
public static final class attr {
4.
}
5.
public static final class drawable {
6.
public static final int ic_launcher=0x7f020000;
7.
}
8.
public static final class id {
9.
public static final int button1=0x7f050000;
10.
}
11.
public static final class layout {
12.
public static final int main=0x7f030000;
13.
}
14.
public static final class string {
15.
public static final int app_name=0x7f040001;
16.
public static final int hello=0x7f040000;
17.
18.
}
}
11. Treinamento Android
Pág.: 11 de 96
Item 06 - Arquivo AndroidManifest.xml – Diretório ProjetoAula
O arquivo AndroidManifest.xml é o arquivo principal do projeto e centraliza as configurações da aplicação.
Ele obrigatoriamente deve ficar na pasta raiz do projeto, contendo todas as configurações necessárias para
executar a aplicação, como o nome do pacote utilizado, o nome das classes de cada activity e várias outras
configurações. Podemos comparar o arquivo AndroidManifest.xml com o arquivo web.xml utilizado nas
aplicações web em java. Em um aplicação web cada classe de servlet deve ser declarada no arquivo
web.xml e, da mesma forma, no Android cata activity deve ser declarada no arquivo AndroidManifest.xml.
É importante que o encode do XML seja UTF-8.
Dentro da tag <manifest> é necessário declarar o pacote principal do projeto, utilizando a tag <package>. É
obrigatório que cada activity do projeto esteja declarada no arquivo AndroidManifest.xml, caso contrario
não é possível utiliza-la. Para declarar a activity é utilizada a tag <activity>, que recebe o nome da classe, e é
sempre relativa ao pacote principal. Por exemplo, em nossa aplicação o nome do pacote é Android.Aula.
Assim, o nome da activity ficou sendo .ProjetoAulaActivity. O ponto indica que a classe
ProjetoAulaActivity.java esta no pacote principal do projeto. Caso activity ficasse em outro pacote, por
exemplo, Android.Aula.Exemplo, o nome da activity deveria ser .pacote.ProjetoAulaActivity.
O projeto pode conter apenas uma, várias ou nenhuma activity, mas o importante é que ser for necessário
exibir um ícone na tela principal do Android, para que a aplicação possa ser iniciada pelo usuário, é
necessário pelo menos uma activity, e esta deve ser configurada como sendo o ponto de partida da
aplicação. Para isso é necessário declarar uma tag <intent-filter> com as ações android.intent.action.MAIN e
a categoria android.intent.category.LAUNCHER dentro da tag <activity>, conforme o seguinte código.
A tag <intent-filter> é necessária para customizar a forma como a activity será iniciada. A ação MAIN
significa que essa activity ProjetoAulaActivity pode ser iniciada isoladamente, como ponto inicial da
aplicação. A categoria LAUNCHER indica que a activity estará disponível para o usuário na tela inicial junto
com as outras aplicações que o usuário tem. Dessa forma, um ícone da aplicação pode ser visualizado na
tela das aplicações instaladas, e ao clicar no ícone a activity configurada como principal é iniciada. Em
aplicações reais geralmente existirá apenas um activity com essa configurações.
Confira na Listagem 07 o conteúdo do arquivo XML AndroidManifest do nosso projeto de exemplo.
Listagem 07
1. <?xml version="1.0" encoding="utf-8"?>
2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
3.
package="Android.Aula"
4.
android:versionCode="1"
5.
android:versionName="1.0" >
6.
<uses-sdk android:minSdkVersion="15" />
7.
<application
8.
android:icon="@drawable/ic_launcher"
9.
android:label="@string/app_name" >
10.
<activity
11.
android:name=".ProjetoAulaActivity"
12.
android:label="@string/app_name" >
13.
<intent-filter>
14.
<action android:name="android.intent.action.MAIN" />
15.
<category android:name="android.intent.category.LAUNCHER" />
16.
</intent-filter>
17.
</activity>
18.
</application>
19. </manifest>
12. Treinamento Android
Pág.: 12 de 96
Android Virtual Device
Um AVD, ou Android™ Virtual Device, é uma emulação de características de smartphones usando aquela
versão do Android™ escolhida (seja a 2.1, 2.2, 4.0.3 ou qualquer outra). Com ele, são carregados a imagem
do sistema e características deste num emulador, onde você poderá ver se corre tudo bem com o seu
projeto.
O conceito de AVD foi criado a partir do SDK 1.5 para auxiliar no desenvolvimento de aplicações Android,
para que o emulador possa simular exatamente uma configuração de um celular real, que podem estar com
diferentes versões do SDK instaladas.
Passo 01
Vamos definir um dispositivo virtual, conhecido como AVD (Android Virtual Device), onde nossas aplicações
daqui para frente serão executadas. Para isso, vá no menu “Windows” / “Android SDK and AVD Manager”,
conforme mostra a Figura 01. Procedendo assim, a interface da Figura 02 será exibida.
Figura 01
Passo 02
Se orientando pela Figura 02, interface Android Virtual Device Manager, clique no botão New para adição
de um AVD.
Figura 02
13. Treinamento Android
Pág.: 13 de 96
Passo 03
Conforme interface da Figura 03 (Edit Android Virtual Device Manager), preencha as propriedades
conforme Tabela 01, clicando no botão Edit AVD em seguida observando o resultado na Figura 04.
Campo
Valor
Name
AVDAula
Sise
128
Built-in
HVGA
Figura 03
Figura 04
14. Treinamento Android
Pág.: 14 de 96
Passo 04
Operando a caixa de dialogo Android Virtual Device Manager, Figura 04, clique no botão Start para iniciar o
emulador. Será exibido a interface Launch Options para qual devemos ajustar conforme Figura 05.
Figura 05
15. Treinamento Android
Pág.: 15 de 96
Passo 05
Ainda com relação a interface da Figura 05, clique no botão Launch para termos a tela do Emulador em
execução.
Conforme observado na tela do Emulador, a saber, Figuras 06, o mesmo está carregando. A Figura 07 exibe
a interface final padrão do um aparelho Android em execução.
Pronto o teste de execução do emulador está encerrado com sucesso. Agora podemos voltar para a
aplicação introdutória e executá-la, clicar no botão Menu e ver o resultado sendo exibido no Emulador
conforme Figura 08.
Figura 06
Figura 07
Figura 08
16. Treinamento Android
Pág.: 16 de 96
Banco de Dados SQLite
SQLite é um banco de dados Open Source, que é incorporado (embarcado) em Android. SQLite suporta
recursos padrão banco de dados relacional como sintaxe SQL, operações e instruções armazenadas. Além
disso, requer pouca memória em tempo de execução (aprox. 250 Kbyte).
SQLite suporta tipo de dados texto (tipos semelhante ao de String da Java), INTEGER(semelhante ao long da
Java) e Real (similar ao dobuble em Java). Todos os outros tipos devem ser convertidos em um desses
campos antes de serem mantidos no banco de dados. O SQLite em si não valida se os tipos enviados para
as colunas são, na verdade, do tipo definido. Por exemplo você pode escrever um número inteiro em uma
coluna tipo String e vice-versa.
SQLite está disponível em todos os dispositivos Android. Usando um banco de dados SQLite no Android não
requer qualquer configuração de banco de dados ou administração.
Você só tem que definir as instruções SQL para criar e atualizar o banco de dados. Depois disso, o banco de
dados é gerenciado automaticamente para você pela plataforma Android.
O acesso a um banco de dados SQLite envolve acessar o sistema de arquivos. Isto pode ser lento. Portanto,
recomenda-se para executar operações de banco de dados de forma assíncrona, por exemplo através da
classe AsyncTask.
Se seu aplicativo cria um banco de dados, este banco de dados é salvo no diretório / DATA / APP_NAME /
bancos de dados / FILENAME.
As partes do diretório acima são construídos com base nas seguintes regras. Dados é o caminho que o
Environment.getDataDirectory() retorna. APP_NAME é o nome do aplicativo. FILENAME é o nome que
você especificar no código do aplicativo para o banco de dados.
Na sequência, a título de cooperar com seu aprendizado sobre este banco de dados, apresentamos uma
colaboração na forma de tutorial para criarmos um banco de dados e a tabela do nosso exemplo de
aplicação com banco de dados embarcado no Android.
Execute o utilitário SQLite Expert Personal conforme Figura 01, e siga os passos na sequência.
Figura 01
17. Treinamento Android
Pág.: 17 de 96
Passo 01
Clique na opção de menu File | New Database, preenchendo os campos da caixa de dialogo Database
Creation Properties com forme apresentado na sequência das Figuras 02, 03, 04 e 05. Encerrando, clique
no botão OK.
Figura 02
Figura 03
Figura 04
Figura 05
Passo 02
Clique com o botão direito do mouse sobre o nó BancoCursoAndroid (Figura 05) escolhendo a opção New
Table do menu de contexto. Conforme Figura 06, digite no campo Table name “Cliente”.
Figura 06
18. Treinamento Android
Pág.: 18 de 96
Passo 03
Adicione colunas a tabela, com a aba Fields selecionada, clicando com o botão direito do mouse e
selecionado a opção Add. Preencha o campo Name como “ID” e selecione no campo Type “BIGINT”
clicando no botão OK para definitivamente criar a coluna. Proceda novamente desta maneira para criar as
outras colunas da tabela, orientando-se pelas Figuras 07, 008, 09, 10 e 11.
Ao final, clique no botão Applay (Figura 12) e teremos a tabela criada.
Figura 07
Figura 08
Figura 09
Figura 010
Figura 11
19. Treinamento Android
Pág.: 19 de 96
Figura 12
Passo 04
Crie também outra tabela, nomeando-a como Visita, tomando por base as informações expostas na aba
Fields da Figura 13. Ao final clique no botão applay e pronto.
Figura 13
Passo 05
Selecionando a aba Design | Index conforme Figura 14, clicando com o botão direito do mouse, selecione a
opção Add do menu de contexto para adicionar índices.
Na sequência representada pelas Figuras 15 e 16, são apresentado os detalhes para criarmos alguns índices.
21. Treinamento Android
Pág.: 21 de 96
Passo 06
Selecione a tabela cliente no nó do Banco de Dados no lado esquerdo da IDE, em seguida, selecione a aba
Data e adicione alguns clientes conforme ilustrado na Figura 17.
Figura 17
22. Treinamento Android
Pág.: 22 de 96
Projeto Android e Banco de Dados SQLite Embarcado
Criando o Projeto Android
Passo 01
Com a IDE do Eclipse em execução, crie um projeto Android acionando a opção de menu File | New | Android Project.
Repare as Figuras 01 e 02 exemplificando este passo.
Figura 02
Figura 01
Passo 02
Continuando, se orientando pela imagem das Figuras 03 e 04, selecione o diretório onde ficará armazenado os fontes
do projeto (Figura 03) e escolha a versão do Android para o projeto em questão (Figura 04).
Figura 03
Figura 04
Passo 03
Clicando no botão Next, Figura 04, teremos a caixa de dialogo final, representada pela Figura 05. Nesta, preencha o
campo Application Name com ExercicioBancoDados, o campo Package Name com android.curso. Também mantenha a
opção Create Activity ativa, definindo o nome da Ativity como MainActivity clicando o Finish para encerrar.
23. Treinamento Android
Pág.: 23 de 96
Figura 05
Passo 04
Iniciaremos agora alguns ajustes no código donte do projeto, iniciando pelo arquivo Strings.xml conforme Listagem 01.
Listagem 01
1.
<?xml version="1.0" encoding="utf-8"?>
2.
<resources>
3.
4.
5.
<string name="hello">Menu de Opções</string>
<string name="app_name">AppBancoDados</string>
</resources>
Passo 05
Alteraremos agora o arquivo main.xml, interface que representa a tela principal do projeto, aplicando nesta alguns
controles conforme exibido na Figura 06. Recorra também a Listagem 02 e Tabela 01 para cumprir esta etapa.
Figura 06
25. Treinamento Android
61.
62.
63.
64.
65.
66.
67.
68.
69.
<Button
android:id="@+id/main_buttonBrowser"
android:layout_width="match_parent"
android:layout_height="70sp"
android:background="@drawable/ic_degradeazulescuro"
android:textColor="#ffffff"
android:drawableRight="@drawable/ic_databaseup"
android:layout_margin="1dip"
android:text="Usar Browser" />
71.
Pág.: 25 de 96
</LinearLayout>
70.
Tabela 01
Linha
Explicação
2
Define o tipo do Layout como LayoutLinear.
3
Define que a largura do Lauout ocupará toda extenção da largura definida pelo Device.
4
Define que a altura do Lauout ocupará toda extenção da altura definida pelo Device.
5
Determina que os controles serão distribuídos na Vertical, uma abaixo do outro na área de Layout.
7
Define um controle TextView
8
Define que o controle ocupará a largura total da área de Layout.
9
Define que o texto será quebrado (em linhas) para acomodar o texto atribuído ao controle.
10
Define a margem que o controle guardará no lado esquerdo com relação a área de Layout ou
controle a seu lado esquerdo.
Obs.: Confira na Tabela 02 os tipos de unidade de medida em Android.
11
Idem item 10, mas para a margem superior (Top).
12
Idem item 10, mas para a margem inferior (Botton).
13
Define cor do texto que o controle exibirá. Este valor equivale a algo como amarelo dourado.
14
Tamanho do fonte de texto.
15
Define estilo (style) bold para o texto.
16
Atribui como valor para a propriedade Text do controle, o valor definido para constante string hello,
na Tag Resources, no arquivo Strings.xml. Confira a alteração que já promovemos no Passo 04,
Listagem 01, refletindo o novo valor da constante hello.
17
Fechamento da Tag Textview.
19
Abre a Tag Button.
20
Define o nome (id) do controle. Repare que o nome definido, é a composição do nome da View
com o nome que se deseja para o controle. Isto é importante, pois todos os controles de todas as
Views do projeto são acessados em código fazendo referência a classe “R” e subclasse “id”,
conforme exemplo que se segue: R.id.main_buttonBrowser
24
Define a imagem que será exibido sobre o controle em seu lado direito.
27
Define a imagem que server de pano de fundo para o controle.
28
Fecha a Tag Button.
26. Treinamento Android
Pág.: 26 de 96
Passo 06
Adicione arquivos de imagem ao diretório res | drawable-hdpi do projeto (Figura 07), para que possam apoós
compilação se tornarem reurso da classe “R” subclasse “drawable”
Figura 07
Tabela 02 - Unidades de Medida
Sigla
Explicação
px
Pixels - corresponde a pixels reais na tela.
in
Polegadas - baseado no tamanho físico da tela.
mm
Milímetros - com base no tamanho físico da tela.
pt
Pontos - 1/72 de polegada com base no tamanho físico da tela.
dp
Density-independent Pixels - uma unidade resumo que é baseada na densidade física da
tela. Estas unidades são relativos a uma tela de dpi 160, de modo uma dp é um pixel numa
tela dpi 160. A proporção de DP-a-pixel irá mudar com a densidade de tela, mas não
necessariamente em proporção directa. Nota: O compilador aceita tanto "dip" e "DP",
embora "DP" é mais consistente com "sp".
sp
Scale-independent Pixels - este é como a unidade de DP, mas também é dimensionado pelo
utilizador de preferência de tamanho da fonte. É recomendável utilizar esta unidade ao
especificar tamanhos de fonte, então eles vão ser ajustado tanto para a tela de densidade e
da preferência do usuário.
27. Treinamento Android
Pág.: 27 de 96
Passo 07
Repare o código da classe MainActivity na Listagem 03 e os comentários da linhas de código na Tabela 03.
Listagem 03 – Arquivo de classe MainActivity.java
1.
package android.curso;
2.
3.
4.
5.
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
6.
7.
8.
9.
10.
11.
12.
13.
public class MainActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}
Tabela 03
Linha
Comentário
1
Define que a classe está presente na namespace do pacote android.curso
3
Import para que a classe presente possa estender a classe Activity, e assim usar seus métodos e estender
outros (@Override).
4
Import da classe View. Classe responsável pela renderização da View main neste exemplo.
8
Indica que o método assinado na linha posterior subscreverá o mesmo método da classe extendida Activity.
9
Método associado ao momento em que uma instância da classe é criada.
10
Invoca o método onCreate da classe Super.
11
Método que recebe como parâmetro o recurso que representa o arquivo xml que servirá de template para
exibição da página.
Execute o projeto, assumindo que já criamos um AVD para tanto. Então, acesse o munu Run | Run executando o teste
reparando a Figura 08 exibindo a interface principal do aplicativo em execução.
Figura 08
28. Treinamento Android
Pág.: 28 de 96
Implantando o Arquivo de Banco de Dados no Servidor SQLite Embarcado
Passo Único
Na IDE do Eclipse, acione o menu Window na opção Show View | Other..., em seguida, com a caixa de dialogo Show
View em exibição (Figura 09) escolha File Explore e clique no botão OK.
A janela File Explore (Figura 10), resultante da ação anterior, prover acesso a estrutura de arquivos do Device (no caso
do Emulador) a partir da pasta data onde podemos encontrar o caminho final para armazenamento do arquivo de
banco de dados. Assim sendo, para finalizar esta etapa, na janela File Explore, vá expandido os nós até chegar no
caminho datadata adicionando uma pasta denominada database.
Por padrão, e isso é realmente um grande facilitador, no que diz respeito a distribuição e localização de banco de
dados em aplicativos Android, arquivos de banco de dados para todas as aplicações residem neste caminho, a saber,
datadatadatabase.
Colocando em prática, se oriente pelas imagens da Figuras 11 e 12, usando um artifício elementar, faça uma cópia (Ctrl
+ C) do arquivo de banco de dados do projeto, transferindo esta cópia que agora está em memória, com outro recurso
elementar, Ctrl V. Pronto observe agora a imagem da Figura 12, caixa de dialogo File Explore, agora contendo uma
cópia do arquivo do banco de dados pronto para acesso pela aplicação.
Figura 09
Figura 10
30. Treinamento Android
Pág.: 30 de 96
Criando as Views do Projeto - Camada View - MVC
Como exemplo do processo para adicionar uma nova View ao projeto, siga os passos abaixo repetindo-o na sequência
das outras Views.
Passo 01
Clique com o botão direito do mouse sobre o nó layout na janela Project Explore (Figura 01), selecionando a opção
New do menu de contexto. Em seguida escolha a opção Other, tendo como resposta a caixa de dialogo representada
pela Figura 02. Escolha a opção Android | Android XML Layout File, passando para próximo passo.
Figura 01
Figura 02
Passo 02
Na caixa de dialogo New Android Layout XML File, Figura 03, define um nome para o arquivo no campo File e clique no
botão Next..
31. Treinamento Android
Pág.: 31 de 96
Figura 03
Passo 03
Não é necessário nesta etapa selecionar alguma configuração em especial, bastando apenas clicar novamente no
botão Next na caixa de dialogo representada aqui pela Figura 04. Por fim, clique no botão Finish para encerrar o
processo.
Figura 04
Prossiga o processo acompanhando na sequência as instruções para todos as outras Views do projeto.
32. Treinamento Android
Pág.: 32 de 96
View listaclientes.xml
Esta View tem como finalidade expor a lista de registros da tabela Cliente, precisamente as colunas ID, NOME e
TELEFONE. Na prática esta View servirá somente de template contendo um controle para cada coluna mencionada.
Naturalmente, os aspectos relativos a configuração visual de cada controle da View, prevalecerão os aplicados aqui,
ficando por conta da rotina que renderizará a View final, atribuir valore as colunas. Considere a imagem da Figura 01,
o código da Listagem 01 e os comentários desta listagem na Tabela 01 para construir e entender a proposta da View.
Figura 01
Listagem 01
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:id="@+id/layout">
<TextView
android:layout_height="30dip"
android:layout_width="40sp"
android:layout_marginLeft="05dip"
android:layout_marginTop="05dip"
android:id="@+id/listaclientes_consultarCliente_id"/>
<TextView
android:layout_height="40dip"
android:layout_width="190sp"
android:layout_marginRight="05dip"
android:layout_marginTop="05dip"
android:id="@+id/listaclientes_consultarCliente_nome"/>
<TextView
android:layout_height="30dip"
android:layout_width="90sp"
android:layout_marginTop="05dip"
android:id="@+id/listaclientes_consultarCliente_telefone"/>
</LinearLayout>
33. Treinamento Android
Pág.: 33 de 96
Tabela 01
Linha
Comentários
1
Define que a estrutura do arquivo é XML com padrão de teto UTF 8.
2
Define que o lay-out adotado para página é LinearLayout. Na sequência estudaremos outros
tipos de layout de página.
3
Define que a área útil lay-out ocupará toda a largura do device onde for executado.
4
Define que a área útil lay-out ocupará toda a altura do device onde for executado.
5
Define que o controles adicionados a página serão organizados na horizontal. Na prática os
controles serão acomodados um abaixo do outro, respeitando possíveis configurações de
distância atribuída, por intermédio de propriedades tipo margem.
6
Define o identificador do arquivo de lay-out indicando que está na pasta layout.
8
Abre a tag para um controle TextView.
9
Define a altura do controle em 30 dip. Ver Tabela 02 com tipos de dimensões.
10
Define a largura do controle em 40 sp.
11
Define a medida da margem esquerda do controle com relação a área do lay-out.
12
Define a medida da margem superior do controle com relação ao objeto acima dele.
13
Define o identificador (nome) do controle. Repare que é salutar definir um nome para o
controle que tenha como prefixo o nome da View. Isso porque, todos os controles de todas
as Views são registrados na classe R, logo, fica mais fácil identificar um controle específico.
15 a 20 e
Define as propriedades para os controles listaclientes_consultarCliente_nome e
listaclientes_consultarCliente_telefone. As definições são as mesmas encontradas entre as
linhas 8 a 13.
22 a 26
28
Tag de encerramento da tag LinerLayout.
Tabela 02 - Tipos de Dimensões em Android
Sigla
Descrição
Px (pixels)
Correspondente ao número de pixels da tela.
in(polegadas)
Baseado no tamanho físico da tela.
mm(milímetros)
Baseado no tamanho físico da tela.
Pt (pontos)
1/72 de uma polegada, baseado no tamanho físico da tela
Dp ou dip
(Density-independent Pixels) Essa unidade é relativa à resolução da tela. Por exemplo, se
a resolução da tela é de 160 dpi, significa que um dp representa 1 pixel em 160 dpi.
sp
(Scale-independent Pixels) Idem ao dp, mas também considera o tamanho da fonte que o
usuário está utilizando. É recomendado que use essa unidade quando especificar o
tamanho de uma fonte, para que esta seja automaticamente ajustada conforme as
34. Treinamento Android
Pág.: 34 de 96
preferências da tela do usuário.
View editarcliente.xml
O lay-out desta View (Figura 01) implementa quatro controles TextView para funcionar como título dos campos e mais
quatro controles EditText que servirão coma caixa de texto para entrada de dados. Também são aplicados a página
três controles Button na parte inferior.
Confira o código necessário na Listagem 01, com os comentários na Tabela 01. Não comentaremos linhas já
comentadas em listagens anteriores, sendo isso uma regra na sequência deste material.
Figura 01
Listagem 01
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="10dip"
android:layout_marginRight="10dip"
android:orientation="vertical" >
<TextView
android:id="@+id/editarcliente_textViewId"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="15dip"
android:text="Código"
android:textSize="15sp"
android:textStyle="bold" />
<EditText
android:id="@+id/editarcliente_editTextId"
android:layout_width="match_parent"
36. Treinamento Android
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
Pág.: 36 de 96
android:layout_width="match_parent"
android:layout_height="32dip"
android:layout_marginBottom="20dip"
android:textSize="13px" />
<TableRow
android:id="@+id/editarcliente_tableRowBotoes"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center" >
<Button
android:id="@+id/editarcliente_buttonAlterar"
android:layout_width="90dip"
android:layout_height="wrap_content"
android:drawableTop="@drawable/ic_bteditar"
android:text="Alterar" />
<Button
android:id="@+id/editarcliente_buttonExcluir"
android:layout_width="90dip"
android:layout_height="wrap_content"
android:drawableTop="@drawable/ic_btexcluir"
android:text="Excluir" />
<Button
android:id="@+id/editarcliente_buttonVoltar"
android:layout_width="90dip"
android:layout_height="wrap_content"
android:drawableTop="@drawable/ic_btvoltar"
android:text="Voltar" />
</TableRow>
</LinearLayout>
Tabela 01
Linha
Comentário
12
Define que o texto atribuído a propriedade text do controle será quebrado em linhas, se necessário,
obedecendo a largura do controle como limite.
14
Define o código que será exibido pelo controle.
15
Define o tamanho da fonte de texto para o controle.
16
Define o peso para a fonte de texto indicado anteriormente.
20
Define o comportamento do controle quanto a expansão ou no do texto do controle. Veja a Tabela
02 com a definição para as possíveis formas.
39
Tag interna a tag TextView que coloca o foco neste controle.
88
Define uma tag TableRow (Linha de Tabela) dentro da página (aqui um LinearLayout), possibilitando
acomodar controles dentro de células nas linhas desta Table.
Considerando que o lay-out da página aqui é linearLayout, logo, acomomdando os controles um
abaixo do outro, usando a Tag Table podemos acomodar controles lado a lado, simplesmente
definindo uma estrutura tabular com linhas e colunas. É o caso, neste layout, dos botões que estão
37. Treinamento Android
Pág.: 37 de 96
colocados na parte inferior do formulário.
92
Define que o controle (aqui a Table) vai gravitar pelo centro da área restante, tendo com base o
topo, o fundo, o lado esquerdo e direito.
98
Define qual imagem irá ser exibida no topo do controle. Esta e outras figuras (arquivos de imagens)
para serem utilizadas em layout, devem ser antes acomodadas no sub-diretório drawable do
diretório res do projeto.
Nota: Repare que o texto atribuído ao controle, neste caso um Button, fica abaixo da imagem.
114
Fecha a Tag TableRow.
116
Fecha a Tag LinearLayout.
Tabela 02
Descrição
fill_parent
Configurando o layout de um widget para fill_parent vai forçá-lo a se expandir para
ocupar tanto espaço quanto está disponível dentro do elemento de layout que ele foi
colocado.
wrap_content
Definir o tamanho de uma View para wrap_content vai forçá-lo a expandir apenas o
suficiente para conter os valores (ou controles filho) que ele contém. Para
controles,como caixas de texto (TextView) ou imagens (ImageView) - isso irá quebrar
o texto ou imagem que está sendo mostrado. Para os elementos de layout que vão
redimensionar o layout para ajustar os controles / layouts adicionados como seus
filhos.
38. Treinamento Android
Pág.: 38 de 96
View buscaclientepornome.xml
Este layout servirá para capturar o parâmetro (parte do nome do cliente) para pesquisa de Clientes pelas iniciais de um
nome.
Para desenhar este formulário, se oriente pela Figura 01, conferindo a configuração de cada controle na Listagem 01.
Figura 01
Listagem 01
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/buscaclientepornome_TextviewParteNome"
android:layout_width="300sp"
android:layout_height="20dip"
android:layout_marginLeft="10dip"
android:layout_marginTop="30dip"
android:layout_marginBottom="10dip"
android:text="Digite parte do nome:" />
<EditText
android:id="@+id/buscaclientepornome_EditTextNome"
android:layout_width="290sp"
android:layout_height="35dip"
android:textSize="15px"
42. Treinamento Android
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
Pág.: 42 de 96
<TableRow
android:id="@+id/incluircliente_tableRowBotoes"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<Button
android:id="@+id/incluircliente_buttonIncluir"
android:layout_width="150dip"
android:layout_height="wrap_content"
android:drawableTop="@drawable/ic_btconfirmar"
android:text="Incluir" />
<Button
android:id="@+id/incluircliente_buttonVoltar"
android:layout_width="150dip"
android:layout_height="wrap_content"
android:drawableTop="@drawable/ic_btvoltar"
android:text="Voltar" />
</TableRow>
</LinearLayout>
Tabela 01
Linha
49
Comentário
Define a aparência do texto do controle com tamanho médio. Consideramos melhor definir as
propriedades size, style entre outras explicitamente.
43. Treinamento Android
Pág.: 43 de 96
View executarbrowser.xml
Este layout servirá para capturar uma URL digitada e executar o browser do dispositivo neste endereço http. Confira a
Listagem 01 com todo o código das tags utilizadas.
Figura 01
Listagem 01
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dip"
android:layout_marginBottom="0dip"
android:layout_marginLeft="02dip"
android:layout_marginRight="02dip"
android:textColor="#FFFF00"
android:textSize="12dip"
android:textStyle="bold"
android:text="Digite um Endereço Web" />
45. Treinamento Android
Pág.: 45 de 96
Criando as Classes da Camada Model - MVC
Criando a Classe Cliente
Para servir de modelo para as classes que lidarão com a entidade Cliente, na sequência, implementamos a Classe
Cliente. Confira todo o código na Listagem 01 e e os comentários na Tabela 01.
Listagem 01
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
package android.curso;
import android.provider.BaseColumns;
public class Cliente {
public long ID;
public String NOME;
public String CIDADE;
public String ESTADO;
public String TELEFONE;
public String NOME_Old;
public String CIDADE_Old;
public String ESTADO_Old;
public String TELEFONE_Old;
public Cliente() {
}
public static final class ClienteColunas implements BaseColumns {
public ClienteColunas() {
}
public static final String ID = "id";
public static final String NOME = "nome";
public static final String CIDADE = "cidade";
public static final String ESTADO = "estado";
public static final String TELEFONE = "telefone";
public static String[] colunas = new String[] {
ClienteColunas.ID,
ClienteColunas.NOME,
ClienteColunas.CIDADE,
ClienteColunas.ESTADO,
ClienteColunas.TELEFONE
};
}
}
46. Treinamento Android
Pág.: 46 de 96
Tabela 01
Linha
5
Comentário
Define a assinatura da classe Cliente
7 a 11
Definem os atributos públicos que representam no Modelo Objeto Relacional as colunas da
tabela Cliente do Banco de Dados. Este atributos serão utilizadas nas instruções Insert,
Update e Delete, além claro de modelar um objeto Cliente.
13 a 16
Atributos extras que armazenarão valores originais de um objeto Cliente, retendo os valores
originais dos atributos de Cliente, para serem usados como argumento de comparação
(cláusula Where) nas instruções Update e Delete em seus respectivos métodos. Esta prática
diz respeito ao conceito de Concorrência Otimista, que trata da questão relativo a
concorrência nos processos de Update e Delete.
18 a 20
Método construtor da classe. Dito método vazio já que não inicializa nenhum objeto.
22
24 a 26
Define uma subclasse denominada ClienteColunas, implementando a interface Basecolumms.
Define o método construtor da subclasse ClienteColunas.
28 32
Define os atributos da classe ClienteColunas com seus valores finais. Tais valores representam
os nomes das colunas da tabela Cliente, utilizados no atributo “colunas” desta classe.
34 a 40
Cria um atributo público do tipo Array de String denominado colunas, na sub classe
ClienteColunas, definindo uma estrutura contendo os nome de colunas da subclasse
ClienteColunas. Isto será útil em várias circunstâncias no desenvolvimento das rotinas que
usam a classe Cliente.
42
Encerra o bloco de código da subclasse ClienteColunas.
44
Encerra o bloco de código da classe Cliente.
47. Treinamento Android
Pág.: 47 de 96
Criando a Classe ClienteModel
Para servir de CRUD para as classes que lidarão com a entidade Cliente, na sequência, implementamos a Classe
ClienteModel contendo os métodos de negócio. Confira todo o código na Listagem 01 e e os comentários na Tabela
01.
Listagem 01
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
package android.curso;
import java.util.ArrayList;
import java.util.List;
import android.content.ContentValues;
import android.content.Context;
import android.curso.Cliente.ClienteColunas;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;
public class ClienteModel {
private static final String NomeBanco = "BancoCursoAndroid";
private static final String NomeTabela = "Cliente";
protected SQLiteDatabase DataBase;
protected ClienteModel() {
}
public ClienteModel(Context context) {
DataBase = context.openOrCreateDatabase(NomeBanco, Context.MODE_PRIVATE, null);
}
public Cliente buscarCliente(long id) {
Cursor cursor = DataBase.query(true, NomeTabela, Cliente.ClienteColunas.colunas,
Cliente.ClienteColunas.ID + " = " + id,
null, null, null, null, null);
if (cursor.moveToFirst()) {
Cliente cliente = new Cliente();
cliente.ID = cursor.getLong(0);
cliente.NOME = cursor.getString(1);
cliente.CIDADE = cursor.getString(2);
cliente.ESTADO = cursor.getString(3);
cliente.TELEFONE = cursor.getString(4);
cliente.NOME_Old = cursor.getString(1);
cliente.CIDADE_Old = cursor.getString(2);
cliente.ESTADO_Old = cursor.getString(3);
cliente.TELEFONE_Old = cursor.getString(4);
return cliente;
}
return null;
}
public List<Cliente> listaClientes() {
Cursor cursor = DataBase.query(
true,
NomeTabela,
null,
null,
null,
null,
null,
48. Treinamento Android
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
Pág.: 48 de 96
null,
null);
List<Cliente> ListaClientes = new ArrayList<Cliente>();
if (cursor.moveToFirst()) {
do {
Cliente Cliente = new Cliente();
ListaClientes.add(Cliente);
Cliente.ID = cursor.getLong(0);
Cliente.NOME = cursor.getString(1);
Cliente.CIDADE = cursor.getString(2);
Cliente.ESTADO = cursor.getString(3);
Cliente.TELEFONE = cursor.getString(4);
} while (cursor.moveToNext());
}
return ListaClientes;
}
public List<Cliente> listaClientesPorNome(String partenome) {
Cursor cursor = DataBase.query(true, NomeTabela,
Cliente.ClienteColunas.colunas,
Cliente.ClienteColunas.NOME + " Like " + "'" + partenome + "%'",
null, null, null, Cliente.ClienteColunas.NOME, null);
List<Cliente> ListaClientes = new ArrayList<Cliente>();
if (cursor.moveToFirst()) {
do {
Cliente Cliente = new Cliente();
ListaClientes.add(Cliente);
Cliente.ID = cursor.getLong(0);
Cliente.NOME = cursor.getString(1);
Cliente.CIDADE = cursor.getString(2);
Cliente.ESTADO = cursor.getString(3);
Cliente.TELEFONE = cursor.getString(4);
} while (cursor.moveToNext());
}
return ListaClientes;
}
public List<Cliente> listaClientesPorNomeSQL(String partenome) {
String ComandoSelect = " Select Cliente.ID, Cliente.NOME, Cliente.CIDADE, " +
"
Cliente.ESTADO, Cliente.TELEFONE " +
" From Cliente Where Cliente.NOME Like ? Order By Cliente.NOME ";
String[] Argumentos = {partenome + "%"};
Cursor cursor = DataBase.rawQuery(ComandoSelect, Argumentos);
List<Cliente> ListaClientes = new ArrayList<Cliente>();
if (cursor.moveToFirst()) {
do {
Cliente Cliente = new Cliente();
ListaClientes.add(Cliente);
Cliente.ID = cursor.getLong(0);
Cliente.NOME = cursor.getString(1);
Cliente.CIDADE = cursor.getString(2);
Cliente.ESTADO = cursor.getString(3);
Cliente.TELEFONE = cursor.getString(4);
} while (cursor.moveToNext());
}
return ListaClientes;
}
private long inserir(ContentValues valores) {
long id = DataBase.insert(NomeTabela, "", valores);
50. Treinamento Android
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
public int excluir(Cliente cliente) {
String where = Cliente.ClienteColunas.ID + " = ?";
String _id = String.valueOf(cliente.ID);
String[] whereArgs = new String[] { _id };
int count = excluir(where, whereArgs);
return count;
}
public int excluirConcorrenciaOtimista(Cliente cliente) {
String where = Cliente.ClienteColunas.ID + " = ? " + " AND " +
Cliente.ClienteColunas.NOME + " = ? " + " AND " +
Cliente.ClienteColunas.CIDADE + " = ? " + " AND " +
Cliente.ClienteColunas.ESTADO + " = ? " + " AND " +
Cliente.ClienteColunas.TELEFONE + " = ? ";
String[] whereArgs = new String[]
{
String.valueOf(cliente.ID),
cliente.NOME_Old,
cliente.CIDADE_Old,
cliente.ESTADO_Old,
cliente.TELEFONE_Old
};
int count = excluir(where, whereArgs);
return count;
}
public void fechar() {
if (DataBase != null) {
DataBase.close();
}
}
}
Pág.: 50 de 96
51. Treinamento Android
Pág.: 51 de 96
Tabela 01
Linha
Comentário
14
Cria variável que define o nome do banco de dados a ser conectado.
15
Define a variável que recebe o nome da tabela a ser manipulada pelos métodos CRUD da
classe.
16
Define um objeto do tipo SQLIteDataBase para acesso ao banco de dados SQLIte.
19 a 21
Método construtor da classe. Inicia o objeto DataBase, criando uma instância para o contexto
passado como parâmetro.
22 a 24
Cria um método construtor vazio.
26
Define o método buscarCliente, que retorna uma instância de Cliente tendo como parâmetro
de entrada o ID do Cliente.
27
Cria um Cursor contendo registros da tabela cliente, retornados pelo método query do objeto
Database (SQLIteDatabase). Abaixo uma lista com o significado de cada um dos nove
parâmetros do método query.
Parâmetro Nome
Significado
1
Distinct
Tipo booleano, define se a consulta usará Distinct ou não na instrução
Select.
2
Table
Tipo String com nome da tabela que será executado a instrução Select.
3
Columms
Array de String (String[]) com os nomes das colunas que retornarão pela
instrução Select. Caso seja null, todas as colunas serão retornadas.
4
Where
Tipo String. Define a sentença de filtro na cláusua Where da instrução
Select. Como exemplo temos “Nome Like ? AND Estado = ?”, onde cada
caracter “?” será substituído por valores passados no parâmetro que se
segue.
5
WhereArgs
Tipo Array de String contendo os argumentos para completar a sentença do
parâmetro 4 (Where), substituindo os argumentos “?” nas sentenças desta
cláusula. Para o exemplo dado no parâmetro anterior, seria por exemplo,
“Mar%” e “MG” respetivamente.
6
GroupBy
Tipo string. Define os campos para efeito Group By da instrução Select.
Caso seja nula não passará a instrução campos para agrupamento.
7
Having
Tipo string. Clásula de restrição aos dados agrupados. Se passado null, não
definirá sentença.
8
OrderBy
Tipo string. Define a uma String com o nome dos campos (separados por
virgula) que definirão a ordem que os registros serão retornados.
9
Limit
Tipo string. Define um número limite de linhas que o Cursor retornará. Se
null, não impõe limite.
30
Move o cursor para a primeira linha, testando o sucesso. Caso o cursou não tenha registro a
condição If é igual a False, logo, não executando as instrução que se seguem.
31
Cria um objeto do tipo Cliente.
32 a 36
Atribui pra cada membro da classe Cliente, o valor correspondente a coluna da linha do
Cursor retornado.
52. Treinamento Android
37 a 40
Pág.: 52 de 96
Atribui valor para os atributos (_Old) da classe cliente.
41
Retorna pelo método o objeto Cliente obtido com os atributos devidamente valorados.
46
Define um método que retorna um List (Collection) de objetos Cliente.
47 a 56
Instruções devidamente explanadas nos comentários do método anterior. Em especial, este
método retorna todos os registros da tabela Cliente.
57
Cria um objeto do tipo List de Cliente.
58
Move o cursor para a primeira linha, testando o sucesso. Caso o cursou não tenha registro a
condição If é igual a False, logo, não executando as instrução que se seguem.
59
Inicia o laço “do while”.
60
Cria um objeto tipo Cliente.
61
Adiciona o objeto Cliente (ainda sem valores atribuídos aos atributos) para o objeto
ListaClientes do tipo List de Cliente.
62 a 66
Atribui valor aos atributos públicos da instância de Cliente recém adicionado ao List.
67
Encerra ou continua a varredura do laço “do while”. Para tanto, utiliza o método MoveNext
do cursor, forçando o avanço para a próxima linha do mesmo. Caso não exista mais linhas o
laço “do while” é encerrado.
68
Encerra o bloco de código da estrutura “If”.
69
Retorna a lista de clientes obtidos do cursor.
70
Encerra o bloco de código do método.
72 a 91
Mesmo que definido para o método explicando nas linhas anteriores, exceto que no método
query, responsável por obter os registro junto ao banco de dados, é aplicado um filtro para
trazer somente os registros cujo o campo Nome sejam iniciados com o valor (String) passado
como parâmetro para o método.
93 a 113
Método igual ao definido entre as linhas 93 e 113, difere semente porque é utilizado o
método “rawquery” no lugar de “query”que utiliza uma instrução SQL explicita para obtenção
dos registros junto a tabela Cliente no banco de dados.
115
Define o método privado inserir que exige um parâmetro de entrada do tipo cliente,
retornando um valor inteiro.
116
Invoca o método insert do objeto DataBase, passando como parâmetros o objeto que contem
o nome da tabela a ser afetada, um valor string vazio (não definindo uma condição para
inserção) e por último o parâmetro de entrada do método corrente contendo os valores de
ContentValues que representa a lista de campos e seus valores a serem atribuídos aos
campos da tabela.
O método insert é uma abstração da classe DataBase, que implementa a instrução Insert em
código SQL junto a base de dados do SQLIte. O mesmo ocorrerá para as instruções Update e
Delete.
117
Retorna pelo método 0 ou 1 conforme definido na explicação para a linha 116.
118
Encerra o bloco de código do método.
53. Treinamento Android
Pág.: 53 de 96
120
Cria o método público inserir, que recebe um objeto Cliente, retornando um valor inteiro.
121
Define um objeto do tipo ContentValues que recebera a lista de valores para os campos da
tabela Cliente a ser inserido pelo método privado insert.
122 a 126
Usa o método put do objeto ContentValues para adicionar valores a lista (nome do campo e
valor para o campo).
127
Invoca o método privado insert, passando como parâmetro o objeto “valores” do tipo
ContentValues. Retorna para o objeto id o valor 0 ou 1 dependendo do sucesso ou não.
128
Retorna pelo método o valor do objeto id.
129
Encerra o bloco de código do método.
131
Define o método privado alterar, tendo como parâmetros de entrada o seguinte:
Parâmetro
Tipo
Definição
valores
ContentValues
Lista de valores na forma de par nome do campo e valor a
ser atribuído ao campo na instrução Update.
where
String
String contendo as sentenças para a cláusula Where da
instrução Update.
whereArgs
String
Valores a serem atribuídos a cada lacuna (?) nas sentenças
da cláusula Where na instrução Updadte.
132
Executa o método Update do objeto SQLIteDatabase que exige os parâmetros tratados no
item anteior. Retorna um valor igual ou maior a um para os registros afetados pelo método
Update, ou zero caso nenhum registro seja afetado.
133
Usa o objeto Log para incluir uma linha de informação no arquivo de log do android.
Obs.: Este recurso é válido, em linhas gerais, para podemos acompanhar o processo na fase
de teste por exmplo.
134
Retorna pelo método a quantidade de registrso afetados pelo método Update.
135
Encerra o bloco de código do método.
137
Define o método público alterar, que implementa um parâmetro de entrada tipo Cliente;
Retorna um valor inteiro equivalente ao total de registros afetados pelo método.
138 a 142
Já explanado em métodos anteriores
143
Converte o valor do atributo ID do objeto Cliente para String e atribui ao objeto _id.
144
Define uma String contendo a condição da cláusula Where para o método Update.
145
Define um objeto do tipo Array de String para receber os valores a serem atribuídos as
lacunas (?) da cláusula Where.
146
Invoca o método privado alterar, passando como parâmetro necessários.
147
Retorna pelo método, o valor retornado pelo método privado alterar, representando a
quantidade de registros afetados pelo método Update.
54. Treinamento Android
148
150 a 171
Pág.: 54 de 96
Encerra o bloco de código do método.
O mesmo que o método anterior (método público alterar), mas adicionando a cláusula Where
do método Update além do valor da chave primária da tabela Cliente (ID = ?), os valores
iniciais obtidos para o registro a ser alterado. Dar-se a esta prática o nome de Concorrência
Otimista, já que conforme sugere o nome, trata da concorrência entre possíveis processos
que estejam tentando alterar o registro ao mesmo tempo. Imaginemos o seguinte cenário
como exemplo, demonstrando o processo na linha do tempo para a concorrência entre dois
processos que tentam alterar um registro.
Linha do Tempo
Processo
Instrução SQL
Efeito
Tempo 1.01
Usuário A
Select * From Tabela
Where ID = 100
Retorna: Col1 = 100, Col2 = Juca e Col3
= 12
Tempo 1.17
Usuário B
Select * From Tabela
Where ID = 100
Retorna: Col1 = 100, Col2 = Juca e Col3
= 12
Tempo 2.04
Usuário B
Update Tabela Set Col2
= Alice, Col3 = 12
Where Col1 = 100 AND
Col2 = Juca AND Col3 =
12
O Update ocorre com sucesso, com o
campo Col1 sendo alterado de Juca para
Alice, pois no memento da execução da
instrução Update os valores dos campos
do registro eram o mesmo quando da
obtenção do registro.
Tempo 2.91
Usuário A
Update Tabela Set Col2
= Alice, Col3 = 123 Where
Col1 = 100 AND Col2 =
Juca AND Col3 = 99
A instrução Update falha, pois, no
tempo 2.91, o registro não era mais
idêntico ao obtido no tempo 1.01 do
processo do Usuário A.
173 a 177
Idêntico ao explicado para o método privado alterar, só que neste caso, utiliza o método
delete do objeto SQLIteDataBase.
179 a 185
Idêntico ao explicado ao código do método público alterar, exceto que o objetivo é a exclusão.
187 a 203
O mesmo comentário válido para o método alterarConcorrenciaOtimista, exceto que para
operação de exclusão.
205
Define o método fechar sem retorno (void).
206
Verifica se o valor do objeto DataBase, instanciado anteriormente é diferente de null. Ou
seja, está conectado.
207
Caso seja diferente de nulo (a condição if), invoca o método close do objeto DataBase, uma
instância de SQLIteDatabase, fechando a conexão estabelecida, logo, liberando recursos.
208
Encerra o bloco de instruções da condição if.
209
Encerro o bloco de código do método.
211
Encerro o bloco de código da classe.
55. Treinamento Android
Pág.: 55 de 96
Implementando a classe ClienteListAdapter
Complementando as funcionalidades relativo a classe Cliente que implementa a estrutura do melo Cliente, e a classe
ClienteModel, que implementa os métodos de negócio e os métodos CRUD para a tabela Cliente, criaremos agora uma
classe especial que se junta a classe Cliente e ClienteModel completando as funcionalidades inerente a camada Model
(no tocante ao padrão MVC) do projeto.
A especialidade da classe ClienteListAdapter, é a partir de uma View modelada para expor as colunas e linhas de uma
collection, em nosso caso uma lista de objetos Cliente, renderizar uma espécie de Grid na View em questão. Vamos
agora observar o código da Listagem 01 e os comentários da Tabela 01.
Listagem 01
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
package android.curso;
import java.util.List;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.TextView;
public class ClienteListAdapter extends BaseAdapter {
private Context contexto;
private List<Cliente> lista;
public ClienteListAdapter(Context ctx, List<Cliente> list) {
this.contexto = ctx;
this.lista = list;
}
public int getCount() {
return lista.size();
}
public Object getItem(int posicao) {
return lista.get(posicao);
}
public long getItemId(int posicao) {
return posicao;
}
public View getView(int posicao, View conversaoView, ViewGroup parenteView) {
Cliente cliente = lista.get(posicao);
LayoutInflater inflater = (LayoutInflater)
contexto.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(android.curso.R.layout.listaclientes, null);
view.setScrollContainer(true);
TextView id = (TextView) view.findViewById(android.curso.R.id.listaclientes_consultarCliente_id);
id.setText(String.valueOf(cliente.ID));
TextView nome = (TextView)
view.findViewById(android.curso.R.id.listaclientes_consultarCliente_nome);
nome.setText(cliente.NOME);
TextView telefone = (TextView)
view.findViewById(android.curso.R.id.listaclientes_consultarCliente_telefone);
telefone.setText(cliente.TELEFONE);
return view;
}
}
56. Treinamento Android
Pág.: 56 de 96
Tabela 01
Linha
Comentário
11
Implementa a classe que herda da classe BaseAdapter, que implementa os métodos úteis para
gerar um adaptador de lista.
12
Define um objeto privado tipo Context.
13
Define um objeto privado tipo List, neste caso do modelo Cliente.
14 a 17
Método construtor da classe. Quando invocado, exige um parâmetro de contexto e um com um
objeto tipo List da classe Cliente com uma coleção de objetos Cliente para gerar a lista.
Repare que os parâmetros passados pelo método são atribuídos aos membros privado da
classe.
19 a 21
Implementa o método que retorna a quantidade de elementos presente na lista de Clientes.
23 a 25
Retorna um objeto obtido na lista de objetos Cliente, baseado na posição (índice) passado por
parâmetro para o método.
31
Define o método público que retorna uma View que renderiza a coleção passada por parâmetro
ao método construtor da classe, neste caso a classe é ClienteListAdapter que herda a classe
BaseAdapter. Para esta renderização, é utilizado controles da View listaclientes.xml.
Nota Importante: Este método nunca é chamado em código explícito, ele é executado
automaticamente quando é criado uma instância da classe ListAdapter (aqui ClienteListAdapter)
realizando a sincronização dos controles da View indicada com as colunas da List passada como
parâmetro ao método construtor da classe. Este método é executado para cada item
(linha/registro) da lista.
32
Carrega um objeto Cliente, obtendo-o da lista. Neste caso, o parâmetro posicao recebe um
valor que vai de 0 a um número que representa a quantidade de linhas da lista meno 1. Na
prática, como o método é chamada para cada registro da lista, posicao recebe o valor índice
deste elemento na lista.
33
Cria um objeto tipo LayoutInflater. Este objeto toma como entrada um arquivo XML (neste
caso listacliente.xml) e constrói os objetos de Visualização a partir dele.
35
Cria um novo objeto View a partir do método inflate do objeto inflater criado na linha 33. Está
será a View que será renderizada no lugar do layout listacliente.xml, que serviu aqui apenas
como template da View definitiva.
37
Cria na View o objeto TextView para representar o campo ID da lista de clientes.
38
Atribui o valor do campo ID da lista para o controle Id do tipo TextView recém-criado.
39 a 41
Idem linhas 37 e 38, mas para o campo Nome da lista Cliente.
42 a 44
Idem linhas 37 e 38, mas para o campo Telefone da lista Cliente.
45
Retorna a View com uma linha de registro criada.
46
Encerra o bloco de código do método.
47
Encerra o bloco de código da classe.
57. Treinamento Android
Pág.: 57 de 96
Criando as Classes Activity - Camada Controller - MVC
Implementando Lógica a classe MainActivity
Comentaremos aqui a lógica implementada aos controles Button, que por intermédio de evento Click associado a cada
um implementam chamadas a outras Ativity. Esta Activity mapeia os controles da View main, acessada aqui pelo
método setContentView, tendo como parâmetro Rlayout.main.
Confira na Tabela 01 o comentária para as linhas de código relevantes da Listagem 01.
Listagem 01 – Arquivo de classe MainActivity.java - Completo
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
package android.curso;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class MainActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
final Intent intentBuscaClientePorNomeActivity = new Intent(this, BuscaClientePorNomeActivity.class);
final Intent intentIncluirClienteActivity = new Intent(this, IncluirClienteActivity.class);
final Intent intentSiteGoogleActivity = new Intent(this, ExecutarBrowserActivity.class);
Button buttonConsultarCliente = (Button) findViewById(R.id.main_buttonConsultarCliente);
buttonConsultarCliente.setOnClickListener(new View.OnClickListener(){
public void onClick(View view) {
startActivity(intentBuscaClientePorNomeActivity);
}
});
Button buttonIncluirCliente = (Button) findViewById(R.id.main_buttonIncluirCliente);
buttonIncluirCliente.setOnClickListener(new View.OnClickListener(){
public void onClick(View view) {
startActivity(intentIncluirClienteActivity);
}
});
Button buttonBrowser = (Button) findViewById(R.id.main_buttonBrowser);
buttonBrowser.setOnClickListener(new View.OnClickListener(){
public void onClick(View view) {
startActivity(intentSiteGoogleActivity); }
});
}
}
58. Treinamento Android
Pág.: 58 de 96
Tabela 01
Linha
Comentário
16
Cria um objeto tipo intent (como uma intenção para use subsequente) que representa a
classe BuscaClientePorNomeActivity. Repare que o método construtor utilizado aqui solicita
um primeiro parâmetro como sendo o owner (proprietário) do objeto, aqui passado a própria
classe Activity Main representada pela referência this. O segundo parâmetro é o método
class da própria classe BuscaClientePorNomeActivity.
17
O mesmo que o comentário da linha 16, mas para a classe IncluirClienteActivity.
18
O mesmo que o comentário da linha 16, mas para a classe ExecutarBrowserActivity.
20
Atribui um objeto do tipo Button, nomeado buttonConsultarcliente, tendo como referência o
objeto retornado pelo método findViewById. Repare que o parâmetro passado para o
método findViewById é uma referência ao nome do Button main_buttonConsultarCliente do
método id da classe R, ou seja R.id. main_buttonConsultarCliente e nada mais.
Vale ressaltar a conversão (Cast) por intermédio de (Button) compatibilizando o tipo
retornado pelo método findViewById com o tipo atribuído ao objeto buttonConsultarcliente.
Repare que a referência a um objeto de uma View, é feito eclusivamente pelo recurso que o
representa na classe R.
21
Associa o evento OnClick de Listener ao objeto buttonConsultarCliente recem criado.
22
Implementa o método associado ao evento OnClick para o controle Button em questão.
23
Usa o método startActivity da classe Activity parar executar a intent passada como
parâmetro. Neste caso a execução da intent intentBuscaClientePorNomeActivity que representa
a classe BuscaClientePorNomeActivity.
24
Encerra o bloco de código do método onClick.
25
Encerra o bloco de código que adiciona o evento OnClick de Listener ao objeto Button
27 a 32
O mesmo que explicado para as linhas 21 a 25, mas para o Button main_buttonIncluirCliente.
34 a 38
O mesmo que explicado para as linhas 21 a 25, mas para o Button main_buttonBrowser.
buttonConsultarCliente.
39
Encerra o bloco de código do método onCreate.
41
Encerra o bloco de código da classe.
59. Treinamento Android
Pág.: 59 de 96
Implementando Lógica a Classe BuscaClientePorNomeActivity
Esta classe implementa a lógica para a View BuscaClientePorNome, funcionando como Page Controller da mesma. A
ideia básica é pegar o que foi digitado no controle TextView e passar como parâmetro para a classe
ListaClientesActivity que será executada na sequência exibindo os registros (tabela Cliente) obtidos junto ao banco de
dados.
Confira na Tabela 01 os comentários para as linhas de código relevantes da Listagem 01.
Listagem 01
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
package android.curso;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
public class BuscaClientePorNomeActivity extends Activity {
private Intent intent;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.buscaclientepornome);
intent = new Intent(this, ListaClientesActivity.class);
Button ButtonPesquisar =
(Button) findViewById(R.id.buscaclientepornome_ButtonPesquisar);
ButtonPesquisar.setOnClickListener(new View.OnClickListener(){
public void onClick(View view) {
EditText EditTextNome =
(EditText) findViewById(R.id.buscaclientepornome_EditTextNome);
String textodigitado = EditTextNome.getText().toString();
Bundle parametros = new Bundle();
parametros.putString("ParteNome", textodigitado);
intent.putExtra("Par teNome", textodigitado);
startActivity(intent);
}
});
Button ButtonVoltar =
(Button) findViewById(R.id.buscaclientepornome_ButtonCancelar);
ButtonVoltar.setOnClickListener(new View.OnClickListener(){
public void onClick(View view) {
finish();
}
});
}
}
60. Treinamento Android
Pág.: 60 de 96
Tabela 01
Linha
16
Comentário
Cria um objeto Intent para a classe ListaClientesActivity.
19 a 20
Cria um objeto Button com base no controle ButtonPesquisar da View buscaclientepornome.
21
Inscreve o controle Button no Listener da View. Caso ocorro o evento Click sobre o controle o
procedimento associado a este evento é executado.
22
Define o método para o evento onclick do controle.
23 a 24
Cria um objeto TextView para representar o controle buscaclientepornome_EditTextNome da
View buscarclientenome.xml, a partir do identificador (id) da classe R.
25
Recupera o texto digitado no controle EditTextNome para um objeto tipo String.
26
Cria um objeto Bundle para armazenar valores de parâmetros a serem passados para a próxima
Intent a ser executada. Assim a próxima Itente pode lançar mão desses valores para processar
algo. Neste caso, usar como parâmetro na execução do método de pesquisa que preencherá a
lista de clients.
27
Usa o método putExtra para adicionar um parâmetro a ser recuperado pela Intent após ser
executada, tendo como nome ParteNome e valor igual ao atribuído ao objeto textodigitado.
28
Executa a Intent, neste caso, ListaClientesActivity.
29
Encerra o bloco de código do método onClick.
30
Encerra o bloco de código do método setOnClickListener.
33 a 36
Define o procedimento para o evento click do objeto buscaclientepornome_ButtonCancelar.
37
Executa o método finish da Activity, retornando o processo para a Activity que partiu a ordem
de execução da mesma.
38
Encerra o bloco de código do método onClick.
39
Encerra o bloco de código do método setOnClickListener.
40
Encerra o bloco de código do método onCrate da classe.
41
Encerra o bloco de código da classe.
61. Treinamento Android
Pág.: 61 de 96
Implementando Lógica a classe ListaClientesActivity
Processa a exibição da lista de clentes, utilizando para tanto a classe ClienteListAdapter que constroi uma lista de
clientes renderizando o resultado em uma View passada como parâmetro. Neste caso a View listaclientes.xml.
Confira observando o código da Listagem 01 e Tabela 01 com os respectivos comentários.
Listagem 01 – Arquivo de classe ListaClientesActivity.java – Completo
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
package android.curso;
import java.util.List;
import android.app.ListActivity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ListView;
public class ListaClientesActivity extends ListActivity {
private List<Cliente> clientes;
public static ClienteModel modelocliente;
protected static final int EDITAR = 1;
protected static final int VOLTAR = 2;
private int registroSelecionado = 0;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
atualizarLista();
}
protected void atualizarLista() {
Bundle parametros = getIntent().getExtras();
String partenome = parametros.getString("ParteNome");
modelocliente = new ClienteModel(this);
clientes = modelocliente.listaClientesPorNome(partenome);
setListAdapter(new ClienteListAdapter(this, clientes));
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
menu.add(0, EDITAR, 0, "Editar Cliente").setIcon(R.drawable.ic_bteditar);
menu.add(0, VOLTAR, 0, "Voltar").setIcon(R.drawable.ic_btvoltar);
return true;
}
@Override
public boolean onMenuItemSelected(int featureId, MenuItem item) {
switch (item.getItemId()) {
case EDITAR:
Cliente cliente = clientes.get(registroSelecionado);
Intent itEditarCliente = new Intent(this, EditarClienteActivity.class);
itEditarCliente.putExtra("idCliente", cliente.ID);
startActivityForResult(itEditarCliente, EDITAR);
break;
case VOLTAR:
finish();
break;
62. Treinamento Android
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83. }
Pág.: 62 de 96
}
return true;
}
@Override
protected void onListItemClick(ListView l, View v, int posicao, long id) {
super.onListItemClick(l, v, posicao, id);
if (posicao != 0) {
registroSelecionado = posicao;
Cliente cliente = clientes.get(registroSelecionado);
Intent itEditarCliente = new Intent(this, EditarClienteActivity.class);
itEditarCliente.putExtra("idCliente", cliente.ID);
startActivityForResult(itEditarCliente, EDITAR);
}
}
@Override
protected void onActivityResult(int codigo, int codigoRetorno, Intent it) {
super.onActivityResult(codigo, codigoRetorno, it);
if (codigoRetorno == RESULT_OK) {
atualizarLista();
}
}
@Override
protected void onDestroy() {
super.onDestroy();
modelocliente.fechar();
}
Tabela 01
Linha
Comentário
12
Define a assinatura da classe, estendendo (herança) para o tipo ListActivity, um tipo especial de Activity
que implementa métodos específicos para renderização de uma lista de valores em forma tabular, usando
os controles da View definida na classe Adapter chamada pelo método setListAdapter da classe ListActivity.
13
Cria um objeto tipo Array de objetos Cliente.
14
Cria uma instância da classe ClienteModel que implementa os métodos de negócio sobre cliente.
15 a 16
Cria dois objetos tipo int com valores 1 e 2, respectivamente Editar e Voltar para servir de flag para
execução do processo da Activity.
22
No evento onCreate da classe invoca o método atualizarLista que procede a busca de registros a ser
renderizado.
25
Define o método atualizaLista sem parâmetros e sem retorno.
26
Define um objeto tipo Bundle para conter a lista de parâmetros obtido pelo método getExtras, da Intent
corrente. Lembrar que na Intent que chamou a atual, foi passado esses parâmetros pelo método putExtras
desta mesma Intent.
27
Atribui o valor do parâmetro ParteNome contido no objeto Bundle parametros.
28
Cria uma instância da classe ModeloCliente para o objeto modelocliente definido anteriormente.
63. Treinamento Android
Pág.: 63 de 96
29
Atribui ao objeto clientes, tipo List de Cliente, definido anteriormente, a lista de clientes retornada pelo
método listaClientesPorNome da classe ClienteModel, passando como parâmetro o objeto partenome com
o valor de parâmetro recuperado pelo método getExtras da Activity corrente..
30
Invoca o método setListAdapter da Activity corrente, que é do tipo LitActivity, passando como parâmetro
uma instância da classe ClienteListAdapter, com os parâmetros this (própria classe) e a lista de clientes
representada aqui pelo objeto clientes.
O método setLisAdapter pertence a classe estendida ListActivity, e processa a renderização dos registros
passado por parâmetro a classe ClienteListAdapter, que conhece qual View utilizar para tanto.
31
Encerra o bloco de código da classe.
33 a 39
Cria um objeto menu, com dois itens de menu, que só será exibido quando acionado o botão Menu do
dispositivo. Ele não é necessário em nosso exercíco, servindo apenas de exemplo de como criar um objeto
desta natureza.
42 a 55
Implementa o procedimento para o evento onMenuItemSelected, acionado toda vez que uma opção de
menu for selecionada.
58 a 59
Define o procedimento para o evento onListItemClick que ocorre quando um item da lista é selecionado.
60
Inicia o bloco de instrução if, caso o valor do parâmetro posicao for difrente de zero. Será diferente de zero
caso uma ação de seleção por parte do usuário ocorra sobre a lista de valores.
61
Atribui ao objeto registroselecionado o índice da linha selecionada na lista.
62
Usando o método get do objeto List de cliente, atribui ao objeto Cliente o Cliente da lista baseado no índice
passado por parâmetro.
63
Cria um objeto Intent a partir da classe EditarClienteActivity que será ativada no processo que se segue.
64
Atribui a lista de parâmetros (método putExtra) o parâmetro nomeado como idCliente o valor do atributo
id do objeto Cliente selecionado.
65
Invoca o método starActivityForResult, passando como parâmetro a Intent recém-criada e o objeto EDITAR
como flag.
Este método permite executar uma Intent, mas ao finalizar o processo da mesma, retornando a Intent que
chamou tal processo executar algo. Neste caso, como veremos na sequência, no método onActivityResult.
66
Encerra o bloco de código do método.
67
Encerra o bloco de código da classe.
69 a 75
Implementa (reescreve o método na classe pai) onActivityResult, que ocorre quando o processamento
retorna da Intent executada a partir desta, verificando o valor do parâmetro codigoRetorno, passado pela
Intent que este em execução. Caso o valor seja igual a constante tipo int RESULT_OK atualiza a lista
chamando o método atualizarLista da classe corrente.
78 a 81
Implementa (reescreve o método na classe pai) onDestroy, destruindo o objeto em memória com a lista de
Cliente.
83
Encerra o bloco de código da classe.
64. Treinamento Android
Pág.: 64 de 96
Implementando Lógica a classe EditarClienteActivity
Permite a edição de um objeto Cliente, procedendo as operações de Alteração e Exclusão. Para tanto faz uso dos
métodos de negócio da classe ClienteModel e Cliente.
Confira observando o código da Listagem 01 e Tabela 01 com os respectivos comentários.
Listagem 01 – Arquivo de classe EditarClienteActivity.java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
package android.curso;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
public class EditarClienteActivity extends Activity {
private ClienteModel modelocliente;
private Cliente cliente;
private EditText campoId;
private EditText campoNome;
private EditText campoCidade;
private EditText campoEstado;
private EditText campoTelefone;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.editarcliente);
campoId = (EditText) findViewById(R.id.editarcliente_editTextId);
campoNome = (EditText) findViewById(R.id.editarcliente_editTextNome);
campoCidade = (EditText) findViewById(R.id.editarcliente_editTextCidade);
campoEstado = (EditText) findViewById(R.id.editarcliente_editTextEstado);
campoTelefone = (EditText) findViewById(R.id.editarcliente_editTextTelefone);
cliente = new Cliente();
modelocliente = new ClienteModel(this);
Bundle parametros = getIntent().getExtras();
long id = parametros.getLong("idCliente");
cliente = modelocliente.buscarCliente(id);
campoId.setText(String.valueOf(id));
campoNome.setText(cliente.NOME);
campoCidade.setText(cliente.CIDADE);
campoEstado.setText(cliente.ESTADO);
campoTelefone.setText(cliente.TELEFONE);
Button ButtonAlterar = (Button) findViewById(R.id.editarcliente_buttonAlterar);
ButtonAlterar.setOnClickListener(new View.OnClickListener(){
public void onClick(View view) {
cliente.ID = Long.parseLong(campoId.getText().toString());
cliente.NOME = campoNome.getText().toString();
cliente.CIDADE = campoCidade.getText().toString();
cliente.ESTADO = campoEstado.getText().toString();
cliente.TELEFONE = campoTelefone.getText().toString();
modelocliente.alterar(cliente);
setResult(RESULT_OK);
finish();
}
});