Вы находитесь на странице: 1из 78

Explicao

Atualmente, o poder de processamento dos celulares e outros aparelhos mveis salta


vista. Com esse avano, tambm h sensveis melhorias nas telas e na usabilidade desses
dispositivos.

Imagine o quo elegante seria, nesse cenrio, poder mostrar seu portflio de aplicaes
j diretamente na sua mo, sem necessidade de sequer um laptop?

Por essas e outras razes, plataformas mveis como Blackberry, iOS e Android, esto cada
vez mais em evidncia e o mercado para tais dispositivos est em plena ascenso. A exploso
do Android a mais recente dentre essas plataformas, e seu crescimento no tem previso
de declnio.

O Android um sistema operacional que roda sobre o ncleo Linux. Ele foi inicialmente
desenvolvido pela Android Inc., e depois passou para as mos do Google (que a comprou em 2005) e
posteriormente pela Open Handset Alliance. A plataforma permite que os
desenvolvedores escrevam software na linguagem Java controlando o
dispositivo via bibliotecas desenvolvidas pela Google, com o objetivo de ser uma
plataforma flexvel, aberta e de fcil migrao para os fabricantes.

Site para desenvolvedores

O link para documentao, downloads e outros :
http://developer.android.com/

Se est procurando um livro para se aprofundar nos estudos, indicamos o da editora Casa do Cdigo:
http://www.CasaDoCodigo.com.br

No mercado j existem inmeras opes de dispositivos com Android. Desde vrios fabricantes
a vrios modelos. J existem tablets e at uma ideia para Google TV Android:


Samsung Galaxy Tab 10
Samsung Galaxy S, S2 e S3
Google Nexus S, Google Nexus 4, Google Nexus7 e Nexus 10
HTC Legend
Motorola Xoom e Xoom 2
Xperia X10
Motorola Defy


Primeiramente, devemos baixar o Bundle Android para o nosso sistema operacional. Voc pode baixar o
arquivo da seguinte URL:

http://developer.android.com/tools/sdk/eclipse-adt.html

O Bundle vem com o SDK, Eclipse e ADT j configurado e customizado para voc programar no Android.

Aps o download ser necessrio rodar o SDK e fazer o update das verses Android que voc deseja
usar.

Durante o curso

Note que, durante o curso, o Bundle est pronto na Caelum j tem os
diversos "Installed Packages". Isso porque so 1.00Gb de downloads e nosso tempo de
curso precioso!

bom tambm baixar o Google APIs para todos os levels, para poder usar outras APIs opcionais.

Como todo incio de aprendizado, nosso primeiro projeto ser um Hello World. Criar uma
aplicao inicial para Android muito fcil.

Vamos criar um projeto em branco, e preencher nome da aplicao e pacotes de instalao.

No Eclipse, v em New... e escolha Android Application Project:



Na tela de criao, preencha o nome do Application Name, Package Name e as configuraes de verses da
SDK.

Preencha o nome da aplicao como sendo OlaMundo e o package como br.com.caelum.olamundo como
na seguinte figura:



Aperte Next.

Na tela de Configurao do Projeto desmarque a opo Create custom launcher icon.

Aperte Next.

Na tela de criao da Activity, selecione a opo Blank Activity. Como na seguinte figura:



V para a prxima tela.

Nesse tela vai ser configurado como vamos chamar nossa Activity e o seu respectivo layout. Altere
o Layout Name paraprincipal . Como na seguinte figura:



Agora clique em Finish.

Muitos arquivos foram gerados automaticamente quando criamos um projeto do Android.
Para comearmos a entender o que acontece na nossa aplicao, vamos explorar um pouco a
estrutura desse projeto.


A classe OlaMundoActivity


Comece abrindo o arquivo OlaMundoActivity.java (em src, no pacote
br.com.caelum.helloworld). Voc ver algo como:
1
2
3
4
public class OlaMundoActivity extends Activity {

@Override
public void onCreate(Bundle savedInstanceState) {
5
6
7
8
super.onCreate(savedInstanceState);
setContentView(R.layout.principal);
}
}
Note que essa classe uma Activity, pois ela herda dessa classe. Isso quer dizer que ela representa
uma tela da nossa
aplicao e implementa a forma como essa tela reagir interao com o usurio e o contedo mostrado
nela,
entre outros.


Layouts moda do Android


A forma e disposio com que os elementos so apresentados na tela, contudo, responsabilidade dos
Layouts.
Veja o arquivo principal.xml em res/layout/:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="@string/hello_world" />

</RelativeLayout>
Nesse exemplo, estamos declarando um layout linear e avisando que, mesmo quando no houver
contedo o bastante para preencher a tela, a aplicao se esticar e vai ocup-la por completo.
Isso se deve aos parmetros com fill_parent.

J na tag TextView, note que a altura determinada como o apenas necessrio para
mostrar seu contedo, configurada como wrap_content.

Agora, repare na linha em destaque: @string/hello. Ela define o texto que aparecer na
tela quando a aplicao rodar. Perceba que ela apenas uma chave para algum texto. Esse
texto est definido em res/values, dentro do arquivo string.xml.

Essa uma ideia simples que facilita na internacionalizao da sua aplicao. Para traduzi-
la para outras lnguas, basta criar outros arquivos de value com as tradues.


Imagens e afins


Frequentemente, precisamos de imagens para complementar nossa aplicao. Entretanto, quando
pensamos em dispositivos pequenos, necessrio considerar as capacidades de resoluo da
tela.

Assim, um projeto Android guarda imagens nas pastas res/drawable-[lmh]dpi/, onde
ldpi corresponde baixa resoluo, mdpi mdia e hdpi alta resoluo.

Caso no haja um device disponvel para testarmos nosso cdigo possvel utilizarmos
emuladores no ADT. Para isso basta escolhermos as especificaes do device que desejamos.

O emulador bastante til porque nem sempre possumos vrios dispositivos com diferentes
tamanhos de tela e verses do Android disponveis para teste.

Para criar um novo simulador precisamos seguir os seguintes passos:

Clique no menu Window e depois em Android Virtual Device Manager.

Na janela que foi aberta, clique sobre o boto New.

Agora preencha as informaes conforme a figura abaixo.



Pronto!!! Agora, basta rodar sua aplicao no simulador
de Android.

Para isso, v em Run -> Run Configurations... e crie uma nova configurao para
Android, nomeando-a e escolhendo a aplicao OlaMundo.

O plugin far o upload da aplicao para o simulador e o instalar, rodando sua
aplicao logo em seguida.



O simulador demora um tanto para inicializar, j que est realmente dando boot num
Android para o teste. Mas, quando finalmente terminar, voc deve ver uma tela assim:



Para rodar um simulador de Android, preciso configur-lo no Eclipse. Vamos criar um
Virtual Device no Android SDK e usar a verso do OS. Siga as instrues sobre a verso (Target) a ser
utilizada no curso.

Verso do Target

Utilizaremos as verses:

Minimum Required SDK: Api 8: Android 2.2
Target SDK: Api 17: Android 4.2
Compile With: Api 17: Android 4.2
Theme: None



Pronto! Agora voc j consegue simular suas aplicaes no Android virtual e utilizar os
servios j prontos da plataforma. Basta escolher o AVD e clicar em Start....

Agora que j conhecemos o funcionamento bsico de uma aplicao para Android,
preciso criar uma base maior, teremos que ir mais a fundo no SDK.
Veja a estrutura do sistema do Android na figura abaixo:



As aplicaes e os frameworks do Android rodam sobre uma mquina virtual diferente,
chamada Dalvik, que roda um bytecode especfico. No entanto, a linguagem de alto nvel
que utilizamos para programar o Java.

O que acontece a SDK do Android j vem munida de um tradutor do formato bytecode de um
class para o formato dex da virtual machine Dalvik, que,
alm de traduzir, j faz uma srie de otimizaes focadas em reduzir o espao do executvel gerado.

Entendamos, agora, os componentes e seus ciclos de vida para que possamos montar um sistema
robusto, expansvel e com uma performance aceitvel para o usurio.

J comentamos que uma Activity corresponde usualmente a uma tela da sua aplicao, mas,
mais do que isso, o executvel da sua aplicao Android tem que estender a classe
Activity. Essa a maneira do framework saber o que chamar no seu executvel.

O mtodo onCreate chamado quando uma Activity executada e ele faz a chamada no
sistema.

As classes que estendem Activity, de uma forma mais abrangente, interagem tanto com
usurios como com servios ou intenes.


Ciclo de vida de uma Activity


Toda Activity tem o ciclo de vida representado na figura a seguir. Os mtodos chamados
sero os mtodos que sobrescreveremos quando criarmos nossas prprias Activities.



onCreate()
Chamado quando a aplicao criada. onde se criam as Views, faz chamadas de banco de
dados. Quando executado, o sistema recebe um Bundle com o estado da ltima execuo da atividade.

onStart()
Chamado antes da aplicao ficar visvel na tela. Se der tudo certo, vai para
onResume(), seno, para onStop().

onResume()
Chamado aps o onStart() se a sua aplicao for para primeiro plano. Neste ponto, voc
est interagindo com o usurio. aqui que sua aplicao pode iniciar ou retornar as aes
necessrias para atualizar as interfaces como usurio.

onPause()
Acontece quando o Android chama uma atividade diferente. Voc perde os direitos da tela,
ento o momento de parar animaes e todo o suprfluo que consuma recursos do sistema e
bateria.

onStop()
Chamado quando outra atividade obteve o primeiro plano, ou quando sua atividade est sendo
eliminada.

onDestroy()
ltima oportunidade da sua aplicao fazer alguma coisa antes de ser eliminada. Lembre-se
que este mtodo pode ser chamado quando o Android precisa de recursos, ou porque o usurio
optou por finalizar a aplicao.

onDestroy() na verso 1.5

Por alguma razo, o mtodo onDestroy() no era chamado na verso 1.5 do SDK.

Se voc estiver desenvolvendo para essa verso em particular, tome cuidado com esse
detalhe!

No final do OlaMundo, vimos algumas pastas internas /res, como layout,
values e drawable, e, alm delas, h algumas outras que aparecem em aplicaes mais
complexas e ricas. Vamos, agora, mais a fundo nesses importante arquivos:


res/layout/


Esse o local para armazenar suas telas, escritas em XML. Veja, por exemplo, o arquivo
main.xml em OlaMundo/res/layout/.
1
2
3
4
5
6
7
8
9
10
11
12
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
</LinearLayout>
Nesse exemplo, estamos declarando um layout linear e avisando que, mesmo que no houver
contedo o bastante para preencher a tela, a aplicao se esticar para ocupar toda a tela.
Isso se deve aos parmetros com fill_parent.

J na tag TextView, note que a altura determinada como o apenas necessrio para
mostrar seu contedo, configurada como wrap_content.


res/values/


Repare na linha em destaque no layout acima: @string/hello. Ela define o texto que
aparecer na tela quando a aplicao rodar. Perceba que ela apenas uma chave para algum
texto. Esse texto est definido em res/values, dentro do arquivo string.xml.
1
2
3
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="hello">Hello World!</string>
4
5
<string name="app_name">Curso</string>
</resources>
Essa uma ideia simples que facilita na internacionalizao da sua aplicao. Para traduzi -la
para outras lnguas, basta criar outros arquivos de value com as tradues. Alm disso,
isolar as Strings do sistema, tambm potencializa a clareza de alguns pontos do
cdigo como por exemplos, chamadas ao banco de dados do Android.


res/raw/


Esse o local para armazenar arquivos de mdia que futuramente sero utilizados no sistema, como mp3,
vdeos e outros.


res/XML/


Nessa pasta armazenaremos arquivos XML. Se ela no existir, s cri-la na pasta /res


res/drawable


Local para armazenar imagens, sejam *.gif, *.jpg ou *.png.

Vale relembrar que as imagens da sua aplicao so guardadas em trs resolues, cada uma com sua
pasta no sistema:


res/drawable-ldpi/: low, dispositivos de baixa resoluo (quase
inexistentes);
res/drawable-mdpi/: medium, dispositivos de mdia resoluo (raros);
res/drawable-hdpi/: high, dispositivos com alta resoluo (maioria).
Existe tambm uma classe central e automaticamente gerada que responsvel pelo mapeamento
dos elementos da view com o model e o controller. Veja que tudo o que criado
ou declarado na pasta res ganha uma representao em Java, que utilizaremos bastante
para pegar valores e referenciar itens.

Note, no entanto, que essa classe no deve ser alterada a mo. Ela apenas um recurso que
o Android disponibiliza para facilitar a referncia a objetos visuais, imagens, strings, etc.
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
public final class R {
public static final class attr {
}
public static final class drawable {
public static final int caelum=0x7f020000;
public static final int icon=0x7f020001;
}
public static final class id {
public static final int FrameLayout01=0x7f060000;
public static final int botao=0x7f060002;
public static final int dest=0x7f060003;
public static final int linearl=0x7f060001;
public static final int send=0x7f060005;
public static final int texto=0x7f060004;
}
public static final class layout {
public static final int helloworld=0x7f030000;
public static final int layout1=0x7f030001;
public static final int main=0x7f030002;
public static final int player=0x7f030003;
public static final int smsexample=0x7f030004;
public static final int widgets=0x7f030005;
}
public static final class raw {
public static final int musica=0x7f040000;
public static final int video=0x7f040001;
}
public static final class string {
public static final int app_name=0x7f050001;
public static final int hello=0x7f050000;
28
29
30
31
32
}
}
Note que, dessa forma, das nossas classes java, para acessar qualquer
recurso declarado na pasta res/, fazemos uma referncia aos atributos
pblicos dessa estranha classe R. Por exemplo:

Acesso a imagens:


R.drawable.icon
R.drawable.caelum
Acesso a itens da tela declarados nos XMLs de layout:


R.id.botao
R.id.texto
Acesso a arquivos:


R.raw.musica
R.raw.video
Acesso a strings:


R.string.app_name
R.string.hello
Veremos com frequncia cdigos que pegam esses componentes, strings, imagens atravs do
mtodo findViewById, para depois utiliz-los, definir listeners, etc:
1
Button botaoDeOk = (Button) findViewById(R.id.botao);
Essa classe R gerada pelo plugin do Eclipse e no deve ter seus valores alterados por ns. Ela ser
utilizada como referncia
para acessar os diversos componentes da nossa interface. como uma grande coleo de identificadores,
que a plataforma saber
utilizar para localizar seus valores e propriedades de maneira otimizada.

O R.java gerado de acordo com os diversos arquivos utilizados para configurao da sua aplicao. Se
houver algum erro nesses
diversos arquivos, capaz de que o plugin no consiga reger-lo, dessa forma propagando um erro em
quase todos os seus arquivos fonte,
dada a ausncia da classe R. Devemos ento ficar atento e buscar o erro que est impedido sua gerao,
e tomar cuidado para no
importar a classe android.R, que no a da sua aplicao, e sim uma de uso interno ao Android.

Como voc j sabe, todas as telas do Android so feitas num arquivo XML, que ficam
dentro de res/layout. L configuramos os detalhes de cada componente, que so itens grficos.

Dentro do XML, cada componente declarado poder ser manipulado em cdigo Java. Todos
esses componentes so filhos de android.view.View. Esses Views sero futuramente
agrupados dentro de ViewGroup. No coincidentemente, ViewGroup filha de View,
formando o composite pattern que aparece tambm no Swing, onde Container filha
de Component.

Uma ViewGroup pode conter Views e inclusive ViewGroups conforme imagem a seguir:



Algumas pessoas vo chamar esses components de widget, porm
h um outro conceito no android, que uma pequena aplicao que pode rodar dentro da
home do dispositivo mvel, tambm chamado de widget.

Durante o curso vamos apresentar alguns dos componentes mais usados em aplicaes Android.
No momento vamos apresentar algumas importantes propriedades que podem ser configuradas nesses
componentes. Precisamos tambm aprender a vincular comportamento aos componentes da tela, para
que possamos interagir com o usurio da aplicao.

No momento vamos focar nos componentes mais bsicos:

Serve para escrevermos um texto na tela do Android, como um label.
1
2
3
4
5
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Caelum explica..."
/>
Cada componente possui diversas propriedades. Alis, layout_width e layout_height so
obrigatrios para todos eles. Voc poderia utilizar uma medida especfica, como em pixels, mas
no recomendado. As opes relativas so mais frequentes, como o wrap_content e match_parent
(a partir da verso 2.2, match_parent) aqui utilizados, e veremos mais adiante o significado das
principais opes.



Serve como campo de edio para o usurio do sistema.
1
2
3
4
5
<EditText
android:id="@+id/cidade"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
Para ler o valor do campo, deve-se invocar getText e depois toString:
1
2
EditText cidade = (EditText) findViewById(R.id.cidade);
Log.i("Meu Texto: ", cidade.getText().toString()) ;
Log.i a forma de utilizarmos o DDMS, o sistema de gerenciamento da mquina Dalvik.
Esse log ser guardado em uma localizao especfica do seu dispositivo, e pode ser facilmente
visto atravs do emulador.



Este widget um boto como na web ou em sistemas desktop.
1
2
3
4
5
6
<Button
android:id="@+id/botaoConfirmar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Boto"
/>
Para usarmos na lgica, devemos buscar o boto e adicionar o listener desejado. Esse
listener ser disparado quando houver um clique no boto. Para fazer isso, precisamos de uma
classe que implemente a interface interna View.OnClickListener:
1
2
3
4
5
6
class BotaoDeConfirmarListener implements View.OnClickListener {
public void onClick(View view) {
// pega os dados da Activity e
// grava os dados na base SQL
}
}
Dentro de nossa activity, podemos registrar uma instncia desse listener para o boto:
1
2
3
Button cadastrar = (Button) findViewById(R.id.botaoConfirmar);

cadastrar.setOnClickListener(new BotaoDeConfirmarListener()));
Mas como a instncia de BotaoDeConfirmarListener pode pegar os dados dos campos
que esto na activity? Uma hiptese seria ter diversos getters, e passar this como
argumento para o construtor.

Ou ento j definir o construtor e passar apenas os itens necessrios para que o listener
funcione.

Apesar das duas possibilidades, a forma mais comum utilizar classes annimas:
1
2
3
4
5
6
7
8
9
Button cadastrar = (Button) findViewById(R.id.botaoConfirmar);

cadastrar.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
// pega os dados da Activity
// (agora que temos acesso a todos componentes, fica mais simples)
// grava os dados na base SQL
}
});
O cdigo fica mais curto, mas pode atrapalhar a legibilidade e tornar a classe muito grande
e com responsabilidades demais. Caso conhea pouco de classes annimas, recomendamos o
post no blog da Caelum a respeito delas:
http://blog.caelum.com.br/classes-aninhadas-o-que-sao-e-quando-usar/



Se quiser um alerta que precise de uma confirmao do usurio, utilize um AlertDialog.
1
2
3
4
5
6
AlertDialog.Builder builder = new AlertDialog.Builder(Aplicacao.this);
builder.setMessage(mensagem);
builder.setNeutralButton("OK", null);
AlertDialog dialog = builder.create();
dialog.setTitle(titulo);
dialog.show();
Utilizado frequentemente para confirmar operaes. O alerta pode ser muito customizado, e em vez
de apresentar um texto, pode at mesmo apresentar uma view customizada dentro de seu espao.



Componentes possuem atributos especficos a seu comportamento, mas muitos deles possuem atributos
que so comuns e que
aparecem com frequncia. J vimos alguns deles, outros so:


android:id: Especifica a identificao no programa
android:layout_width: Especifica a largura
android:layout_height: Especifica a altura
android:text: Essa propriedade serve para mostrar o texto que passado como parmetro.
android:textColor: Essa propriedade serve para definir uma cor para o texto exibido.
android:background: Essa propriedade serve para definir uma cor de fundo.
android:textStyle: Essa propriedade serve para definir um estilo a fonte (negrito e/ou itlico).
android:textSize: Essa propriedade serve para definir o tamanho da fonte. O tamanho da fonte pode ser especificado
em vrias notaes : px (pixels),sp(scaled-pixels) , mm(milmetros), in (inches) e etc.
android:typeface: Essa propriedade serve para definir uma fonte ao texto (Arial , Times NewRoman, Courier New e
etc).
android:capitalize: Essa propriedade serve para definir o tipo capitalizao das palavras. Por padro, o valor e
"none"(nenhum).
android:password: Com essa propriedade voc habilita a digitao de senhas.
android:visibility: Define se o componente deve ser visvel desde a primeira apario dessa tela.
android:inputType: Define o teclado para a insero de dados. Entrou no lugar de algumas propriedades que foram
depreciadas
Nome dos componentes

Cada objeto utilizado nos xmls tem a forma @+<tipo>/<nome>. Quando o id de um componente
visual (View), utilizamos @+<id>/<nome>.

Quando voc identifica o id de um widget, ele compilado e aparece na classe R.java.
Por exemplo, se o id for @+telaDeCadastro/botaoConfirmacao, na identificao da sua lgica,
apareceria R.telaDeCadastro.botaoConfirmacao.

Outra abordagem criao de listeners configurar no xml da view um mtodo para ser invocado
na Activity relacionada a ela.
Fazemos isso colocando o nome do mtodo a ser executado no atributo onClick da tag Button:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<LinearLayout...>

<EditText ...>

<Button
android:text="Copiar texto"
android:id="@+id/botao"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="imprime"
</Button>

<TextView ...>
</LinearLayout>
Agora basta implementarmos na Acivity um mtodo chamado imprime que recebe uma View
1
2
3
4
public class OlaMundoActivity extends Activity {
//... outros mtodos

public void imprime(View view) {
5
6
7
Log.i("Informao:", "Botao clicado!");
}
}
Quando definimos um arquivo de layout, jogamos dentro dele todos os componentes que gostaramos de
ter
na tela. Uma questo que fica : como esses componentes estaro dispostos? Apesar deles possurem
diretivas
em relao a sua altura e largura, quem vem primeiro? Quem estar prximo do outro? Como definir com
mais
exatido esse posicionamento?

Assim como o Swing possui seus LayoutManagers, o Android possui classes filhas de ViewGroup, sendo
que alguns deles agem como os layout managers. Eles definiro como seu layout ser aplicado aos
diversos
componentes (Views) contidos nele. comum misturar diferentes layouts em uma mesma tela para obter
um resultado
mais agradvel visualmente.

Por default, e um dos mais usados, temos o LinearLayout, que utilizamos at esse momento.

Este layout utilizado para alinhar horizontalmente ou verticalmente o contedo da tela do Android.
1
2
3
4
5
6
7
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
:
</LinearLayout>
No modo horizontal podemos ter um resultado estranho:


1
2
3
4
5
6
7
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
:
</LinearLayout>


Utilizado para dividir a tela em clulas.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<TableLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">

<TableRow>
:
</TableRow>
<TableRow>
:
</TableRow>
<TableRow>
:
</TableRow>
</TableLayout>


Utilizado para definir exatamente as posies na tela. Esse layout foi depreciado, a Google recomenda
que no usemos em produo.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?xml version="1.0" encoding="utf-8"?>
<AbsoluteLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:text="Texto Centralizado"
android:textColor="#FFFF00"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_x="100px"
android:layout_y="20px"
/>
<TextView
android:text="Texto Esquerdo"
android:textColor="#FF0000"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_y="40px"
android:layout_x="15px"
/>
</AbsoluteLayout>


O RelativeLayout tem sido cada vez mais usado para a organizao das telas
do dispositivo por permitir que os componentes sejam alocados na tela com
relao outros componentes ou prpria tela. Com este layout podemos usar
algumas tags para fazer este alinhamento. Segue uma pequena lista:


android:layout_alignTop="@+id/item" - Alinha o topo do componente em relao a outro
android:layout_alignLeft="@+id/item" - Alinha a esquerda do componente em relao a outro
android:layout_toLeftOf="@+id/item" - Alinhado esquerda do componente
android:layout_toRightOf="@+id/item" - Alinhado direita do componente
android:layout_below="@+id/item" - Alinha abaixo de outro componente
android:layout_centerHorizontal="true" - Alinhado no centro horizontal
android:layout_centerVertical="true" - Alinhado no centro vertical
android:layout_alignParentTop="true" - Alinhado em cima da tela
android:layout_alignParentBottom="true" - Alinhado em baixo da tela
android:layout_alignParentLeft="true" - Alinhado esquerda
android:layout_alignParentRight="true" - Alinhado direita
Mas lembre-se que o Graphical Layout vai te ajudar a fazer esta organizao.
A dica de ouro, colocar id's adequados aos seus componentes.

comum misturarmos diferentes layouts para fazer telas um pouco mais complexas,
um nico layout nem sempre o suficiente. Alm do que vimos, ainda temos:


FrameLayout - Praticamente sem layout. As Views ficam umas em
cima das outras. As vezes o que precisamos para a nossa tela, como
quando vamos montar um video com legendas.
TableLayout - Ele monta uma tabela na tela com diversas linhas
(TableRow). Nestas linhas, as colunas so a quantidade de views nelas
colocadas
GridView - Serve para voc mostrar diversas views numa mesma tela
TabLayout - Como o nome diz, possibilita a colocao de abas na nossa
aplicao


Um importante recurso de Layout no Android o atributo layout_gravity. Atravs dele
podemos influenciar no posicionamento de nossas Views.

Se criarmos um texto dentro de um FrameLayout ele ficar no topo da tela, na esquerda
por padro.
1
2
3
4
5
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">

6
7
8
9
10
11
12
13
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Testando Layouts"
android:textSize="30sp"
/>

</FrameLayout>


Vamos agora customizar o posicionamento do TextView. Se quisermos
que ele seja um ttulo e aparea centralizado no topo da tela podemos
utilizar o layout_gravity com o valor center_horizontal. Conforme
cdigo abaixo:
1
2
3
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
4
5
6
7
8
9
10
11
12
13
14
android:layout_height="fill_parent">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Testando Layouts"
android:textSize="30sp"
android:layout_gravity="center_horizontal"
/>

</FrameLayout>
O resultado est representado na imagem abaixo:



Podemos tambm determinar que nosso TextView deve aparecer no
centro vertical, usando o valor center_vertical para nosso
layout_gravity.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Testando Layouts"
android:textSize="30sp"
android:layout_gravity="center_vertical"
/>

</FrameLayout>
O resultado:



Repare que o TextView encontra-se no centro vertical, mas voltou
a estar alinhado esquerda. Se quisermos que ele esteja centralizado
tanto vertical quanto horizontalmente podemos utilizar mais de um valor
para o layout_gravity usando o caractere | ("pipe") para concatenar
os valores. Isso no necessrio para o caso do centro da tela j que
existe o valor center. No exemplo abaixo demonstramos como
colocar um TextView centralizado na tela e outro no canto inferior
direito utilizando o layout_gravity.
1
2
3
4
5
6
7
8
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
9
10
11
12
13
14
15
16
17
18
19
20
21
22
android:text="Testando Layouts"
android:textSize="30sp"
android:layout_gravity="center"
/>

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Direita inferior"
android:textSize="30sp"
android:layout_gravity="bottom|right"
/>

</FrameLayout>


Quando criamos um elemento de nossa View podemos tambm estar preocupados em como
posicionar seu interior. Suponha agora que desejamos colocar um texto na cor preta
em um fundo branco. Esse elemento da nossa tela dever estar dentro de um FrameLayout
que por sua vez ter um fundo preto. Podemos customizar um TextView para que ele tenha
essa aparncia:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">

<TextView
android:layout_width="250dp"
android:layout_height="250dp"
android:text="Com fundo"
android:textSize="30sp"
android:textColor="#000000"
android:background="#FFFFFF"
android:layout_gravity="center"
/>

</FrameLayout>
O cdigo anterior vai gerar uma tela conforme a imagem a seguir:



Nosso TextView de fundo branco est centralizado na tela, porm
no interior do TextView o texto encontra-se posicionado na parte
superior esquerda. Para centralizarmos o texto no interior do TextView
podemos usar o atributo gravity juntamente com o layout_gravity
previamente utilizado.
1
2
3
4
5
6
7
8
9
10
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">

<TextView
android:layout_width="250dp"
android:layout_height="250dp"
android:text="Com fundo"
android:textSize="30sp"
android:textColor="#000000"
11
12
13
14
15
16
17
android:background="#FFFFFF"
android:layout_gravity="center"
android:gravity="center"
/>

</FrameLayout>


Quando o assunto layout, outro artifcio do desenvolvedor Android o uso do
layout_weight.

Quando existe um espao sobrando na tela, atravs da propriedade layout_weight
podemos orientar o Android a dividir esse espao aplicando um peso maior ou menor
para os elementos da View. Para ilustrar no cdigo abaixo vamos colocar trs Button's
ocupando toda a largura da tela, porm a altura queremos dividir de tal maneira que o segundo
boto tenha o dobro da altura do primeiro e o terceiro boto, por sua vez tenha o triplo da
altura do primeiro. Queremos tambm que o conjunto dos trs os botes ocupem toda a nossa tela.

Nosso objetivo encontra-se ilustrado na imagem abaixo:



Para atingir nosso objetivo vamos utilizar o layout_weight para dar peso diviso do
espao na tela. Nosso primeiro boto ter peso 1, o segundo ter peso 2 e o terceiro ter peso 3,
conforme o cdigo abaixo:
1
2
3
4
5
6
7
8
9
10
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >

<Button
android:text="Primeiro"
android:layout_weight="1"
android:layout_height="0dp"
android:layout_width="fill_parent"
/>
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

<Button
android:text="Segundo"
android:layout_weight="2"
android:layout_height="0dp"
android:layout_width="fill_parent"
/>

<Button
android:text="Terceiro"
android:layout_weight="3"
android:layout_height="0dp"
android:layout_width="fill_parent"
/>

</LinearLayout>
Lint uma ferramenta que verifica pequenos erros na construo de layouts como:


id duplicado
layout duplicados
layout no usado
texto no externalizado no arquivo strings.xml
tamanhos no externalizados no arquivo de dimens.xml
outros erros
apis de verses superiores usadas em verses inferiores
uma boa ferramenta para verificar se a construo de seu layout est seguindo
as regras do Android.

O Lint est disponvel somente em verses do plugin ADT superiores a verso 14.

Para rodar o Lint, basta clicar no menu Window -> Run Android Lint.
Explicao
Para estudar os conceitos do curso e aplic-los na prtica, desenvolveremos
incrementalmente um projeto para cadastrar alunos de uma instituio de ensino.

Precisamos de uma aplicao capaz de registrar alunos com suas notas com funcionalidades
especficas como fazer ligaes, navegao web, envio de dados para a web e
envio/recebimento de SMS. Alm disso, encontraremos os alunos num mapa e numa galeria.

Para comear, faremos:


Incio do sistema de cadastro de alunos
Integrar alguns componentes de tela e navegao
Vamos comear criando a funcionalidade de listar os alunos em uma tela. Vamos criar o
novo projeto e pedir para ao wizard criar a tela inicial de nossa aplicao, controlada
pela ListaAlunosActivity e associada ao layout listagem_alunos.xml.

Vamos comear editando o layout criado para colocar um componente usado para apresentar listas
na tela do Android, um ViewGroup chamado ListView:
1
2
3
4
5
6
7
8
9
10
11
12
<?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">

<ListView
android:id="@+id/lista_alunos"
android:layout_width="match_parent"
android:layout_height="match_parent">
</ListView>
</LinearLayout>
Agora precisamos manipular o ListView e colocar uma lista de nomes para serem apresentados
na tela. Na ListaAlunosActivity podemos buscar o ListView criado e criar um Array de
nomes:
1
2
3
4
5
6
7
8
9
10
11
12
public class ListaAlunosActivity extends Activity {
private ListView listaAlunos;

public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.listagem_alunos);

String[] alunos = {"Anderson", "Filipe", "Guilherme"};

listaAlunos = (ListView) findViewById(R.id.lista_alunos);
}
}
Agora precisamos fazer o ListView apresentar os nomes do Array.
O problema que o Array contm Strings e a tela do Android s aceita objetos
do tipo View, precisamos fazer o trabalho de converter um objeto comum do Java
em uma View. Soma-se a essa tarefa mais uma dificuldade: Como definir a aparncia da linha
do ListView?

Abaixo podemos observar dois exemplos de uso de ListView, um deles mais simples outro mais
complexo:



Para conseguirmos atingir nosso objetivo e criar uma tela com um ListView populado
vamos utilizar um Adapter, uma classe do Android especializada em adaptar para
a tela um objeto do Java atravs da criao de uma objeto do tipo View. Um dos
adapters disponveis o ArrayAdapter que capaz de converter listas ou arrays em views.
Em seu construtor o ArrayAdapter nos pede 3 argumentos:


um Context j que ser necessrio impactar na tela
o id do layout da linha
a lista ou array de objetos que queremos no ListView
1
2
3
4
5
6
7
String[] alunos = {"Anderson", "Filipe", "Guilherme"};

int layout = android.R.layout.simple_list_item_1;

ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
layout, alunos);

listaAlunos = (ListView) findViewById(R.id.lista_alunos);
8
Agora basta associarmos nosso Adapter ao
Para que o ListView possa buscar seus elementos atravs do adapter vamos
associ-los usando o mtodo setAdapter:
1
2
3
4
5
6
//...
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
layout, alunos);

listaAlunos = (ListView) findViewById(R.id.lista_alunos);
listaAlunos.setAdapter(adapter);
Para que seja possvel a criao de um sistema com esta capacidade, ser necessria a
criao de um projeto Android no Eclipse, utilizando o plugin que instalamos.

Pequenos avisos podem ser mostrador atravs da classe Toast (Torradeira), que faz exatamente o que o
nome diz... ele
faz "brotar" um aviso na tela por um certo tempo. A durao pode ser Toast.LENGTH_LONG =
1 eToast.LENGTH_SHORT = 0.
1
Toast.makeText(context, "Meu texto de aviso", Toast.LENGTH_SHORT).show();
Quando um Toast criado, uma mensagem fica pronta para ser mostrada na tela, na forma de um
balozinho de texto informativo. Ele s mostrado, contudo, quando chamamos o mtodo show().

Diferente de um alerta comum, voc pode continuar a utilizar sua aplicao normalmente enquanto o
Toast exibido.

Podemos integr-lo nossa aplicao para que, quando o usurio clicar no aluno listado, mostremos
a posio daquele aluno na lista.

Para vincularmos um Toast ao clique em uma View qualquer precisamos vincular a lista a um
OnClickListener como no cdigo abaixo:
1
2
3
4
5
public class MinhaActivity extends Activity {

public void onCreate(Bundle savedInstanceState) {
// chamada a super, setContentView e outros..

6
7
8
9
10
11
12
13
14
15
16
17
ListView minhaLista = (ListView) findViewById( //algum id de um ListView

listaAlunos.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> adapter, View view,
int posicao, long id) {

Toast.makeText(MinhaActivity.this, "Meu texto de aviso",
Toast.LENGTH_SHORT).show();
}
});
}
}
Repare que na chamada ao Toast estamos passando o Context que no caso a instncia
da MinhaActivity fazendo MinhaActivity.this. Isso porqu this seria a instncia
da classe annima que uma classe sem nome que implementa a interface OnItemClickListener.
A classe annima no extende Activity que o nico Context que conhecemos at
o momento, portanto essa instncia da classe annima no pode ser usada como um Context.
Explicao
Vamos criar uma nova tela para que possamos cadastrar novos alunos.

Para atingir esse objetivo vamos precisar criar uma nova Activity.
Vamos cham-la de FormularioActivity e vincul-la a um novo layout
que chamaremos de formulario.xml.
1
2
3
4
5
6
7
8
public class FormularioActivity extends Activity{

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.formulario);
}
}
Podemos realizar essa tarefa sem muita dificuldade com um atalho do ADT:

Aperte CTRL + N e digite Android Activity. Agora clique em Next e na prxima tela escolha a opo Blank
Activity.
Preencha o campo Activity Name com o nome FormularioActivity.
Escolha como nome do layout para essa Activity o nome formulario.xml.



Agora precisamos alterar o layout formulario.xml at atingirmos o seguinte resultado:



Para isso precisamos criar vrios componentes orientados verticalmente. Por esse motivo a tag raiz
de nosso layout dever ser um LinearLayout com a orientao vertical:
1
2
3
4
5
6
7
8
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >

<!-- outros elementos em breve aqui! -->

</LinearLayout>
Dentro do LinearLayout o primeiro elemento que desejamos colocar
uma imagem para que mais tarde possamos ter a foto do aluno cadastrado.

Para isso vamos criar um ImageView. Ele deve estar centralizado
horizontalmente na tela portanto vamos configurar o atributo layout_gravity
de nosso ImageView:
1
2
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
3
4
5
6
7
8
9
10
11
12
13
14
15
android:layout_height="wrap_content"
android:orientation="vertical" >

<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="@drawable/ic_launcher" />

<!-- outros elementos em breve aqui! -->

</LinearLayout>
Devemos criar varias entradas de dados, ou seja EditText's
e cada um deles deve ter um texto indicativo de qual informao
desejamos que seja preenchida. Ou seja para cada EditText
vamos criar um TextView logo acima.

No ltimo elemento da tela ser um Button com o texto Gravar.
Ento nosso layout ficar dessa maneira:
1
2
3
4
5
6
7
8
9
10
11
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >

<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:src="@drawable/ic_launcher" />

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Nome:" />

<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content" />

<!-- outros campos -->

<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Gravar" />

</LinearLayout>
Logo acima do boto gravar precisaremos pedir que o
usurio escolha a nota to aluno. No lugar de pedir
para que ele digite em um EditText vamos fazer a
seleo em um SeekBar com um valor mximo de 10.
1
2
3
4
5
6
7
8
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >

<!-- outras tags criadas previamente -->

<TextView
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Nota:" />

<SeekBar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:max="10" />

<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Gravar" />

</LinearLayout>
O problema que podemos enfrentar a variedade de dispositivos
Android disponveis no mercado. Para os dispositivos de tela
pequena no ser possvel visualizar todos os componentes que
colocamos no layout e nossa tela no foi configurada para permitir
scroll.

Vamos melhorar a compatibilidade de nossa App fazendo com que
o LinearLayout fique dentro de uma ScrollView que ser a nova
tag raiz do layout formulario.xml:
1
2
3
4
5
6
7
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent" >

<LinearLayout
android:layout_width="match_parent"
8
9
10
11
12
13
14
android:layout_height="wrap_content"
android:orientation="vertical" >

<!-- outras tags criadas previamente -->

</LinearLayout>
</ScrollView>
Repare que a tag raiz sempre deve conter o namespace (xmlns) do Android,
para definir quais tags podemos usar!

Para que seja possvel buscar esses elementos no cdigo devemos
criar id's para cada um dos campos de entrada de dados
(os EditText's e o SeekBar).

Agora possumos duas telas, precisamos encontrar alguma forma de fazer o usurio navegar
entre elas.

Na maioria das vezes precisamos de diversas telas numa mesma aplicao e de menus de acesso a
funes
especficas.

Felizmente, toda Activity do Android j vem preparada para lidar com menus.
Para cri-lo, basta sobrescrever o mtodo onCreateOptionsMenu(Menu menu) da Activity.
Faremos isso na nossa ListaAlunosActivity.

Quando criamos um item no menu de uma aplicao, quem se encarrega de encaix-lo
na posio correta da tela o prprio sistema, voc no precisa se preocupar.
Para isso, dentro do onCreateOptionsMenu(Menu menu), faramos:
1
2
3
4
5
menu.add("Novo");
menu.add("Mapa");
menu.add("Sincronizar");
menu.add("Baixar Provas");
menu.add("Preferncias");
Para que o menu de opes aparea precisamos apenas clicar no boto Menu de nosso
aparelho:



Como comportamento padro, o sistema colocar como nome do boto,
o parmetro passado no mtodo add, mas, se preferir, pode-se trocar por um cone.
Basta chamar no item de menu recm-criado, que devolvido pelo mtodo add, o mtodo setIcon,
passando um R.drawable.nomeDaImagem.
1
2
MenuItem mapa = menu.add(0, 3, 0, "Mapa");
mapa.setIcon(R.drawable.mapa);
O mtodo onCreateOptionsMenu(Menu menu) deve retornar true (ou o resultado do super)
para indicar que o menu deve aparecer na tela.

Apesar da possibilidade da criao programtica do menu, como ele um elemento de tela
damos a preferncia de criar seus itens atravs de um xml.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="@+id/menu_novo"
android:icon="@drawable/ic_novo"
android:title="Novo"/>
<item
android:id="@+id/menu_mapa"
android:icon="@drawable/ic_mapa"
android:title="Mapa"/>
<item
android:id="@+id/menu_enviar_alunos"
android:icon="@drawable/ic_enviar"
android:title="Sincronizar"/>
<item
android:id="@+id/menu_receber_provas"
android:icon="@drawable/ic_receber"
android:title="Baixar Provas"/>
<item
android:id="@+id/menu_preferencias"
android:icon="@drawable/ic_preferencias"
android:title="Preferncias"/>
</menu>
Repare inclusive que j estamos escolhendo arquivos dentro da pasta drawable para
cones de nossos itens de menu.

Agora precisamos fazer o Android criar elementos na tela - Views - para cada item
do menu descrito no xml.

O Android precisa ter a capacidade de ler os xmls que criamos e criar objetos
do tipo View a partir das tags, essa a especialidade dos Inflaters.

No caso especfico de um xml de menu podemos utilizar um Inflater especializado em
interpretar esse tipo de arquivo, trata-se do MenuInflater.

No mtodo onCreateOptionsMenu podemos fazer uma chamada a getMenuInflater(), um mtodo
da classe Activity que nos d acesso a um MenuInflater.

Repare que o mtodo onCreateOptionsMenu j nos fornece um objeto do tipo Menu,
basta utilizarmos o inflater para ler nosso xml e criar a partir
deles os itens que sero colocados no menu. Para isso podemos utilizar o mtodo mais
importante de um Inflater: o inflate.
1
2
3
4
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.meu_arquivo_de_menu, menu);
}
A abordagem de utilizar botes fsicos no aparelho foi um diferencial competitivo dos aparelhos
Android em relao ao iPhone. Enquanto o produto da Apple baseava toda sua usabilidade
em Gestures (inclusive o boto voltar, que ocupa espao na tela) os aparelhos Android podiam
combinar cliques na tela com botes no aparelho, possibilitando a fabricao de aparelhos com telas
bem menores e utilizando telas com sensibilidade inferior, se necessrio.

Hoje a qualidade dos aparelhos Android evoluiu e o mercado consumidor optou por utili zar principalmente
aparelhos com telas maiores, fazendo com que a usabilidade nos aparelhos Android mudassem. Hoje a
tendncia
minimizar a utilizao de botes fsicos no aparelho (boa parte dos devices mais novos j no possuem
botes como o Search e a tendncia minimizar ainda mais).

Para a maior parte dos dispositivos quando uma tela possui um OptionsMenu no existe nenhum
indicativo visual na tela dessa presena, fazendo com que a usabilidade da app seja prejudicada.

Em nossa aplicao vamos seguir a tendncia do Android e colocar o Menu em um elemento visual
na tela atravs do uso de um componente que surgiu na verso 3.0 do Android: a Action Bar.

Para configurarmos os itens de menu para aparecerem na Action Bar simplesmente configuramos
o atributo showAsAction da tag item:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="@+id/menu_novo"
android:showAsAction="always"
android:icon="@drawable/ic_novo"
android:title="Novo"/>

<item
android:id="@+id/menu_mapa"
android:showAsAction="always"
android:icon="@drawable/ic_mapa"
android:title="Mapa"/>

<!-- outros itens -->
</menu>


Para evitar que o nome de nossa aplicao desaparea nos devices de tela pequena e para tornar
a tela mais agradvel, vamos deixar visveis no menu principal apenas as opes mais teis. Para
atingir esse objetivo vamos criar um submenu de opes:
1
2
3
<menu xmlns:android="http://schemas.android.com/apk/res/android" >

<item
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
android:id="@+id/menu_novo"
android:icon="@drawable/ic_novo"
android:showAsAction="always"
android:title="Novo"/>
<item
android:id="@+id/menu_mapa"
android:icon="@drawable/ic_mapa"
android:showAsAction="always"
android:title="Mapa"/>
<item
android:icon="@drawable/ic_opcoes"
android:showAsAction="always"
android:title="Mais opes">
<menu>
<item
android:id="@+id/menu_enviar_alunos"
android:icon="@drawable/ic_enviar"
android:showAsAction="always"
android:title="Sincronizar"/>
<item
android:id="@+id/menu_receber_provas"
android:icon="@drawable/ic_receber"
android:showAsAction="always"
android:title="Baixar Provas"/>
<item
android:id="@+id/menu_preferencias"
android:icon="@drawable/ic_preferencias"
android:showAsAction="always"
android:title="Preferncias"/>
</menu>
</item>
</menu>
34
35


Nem s de Toast's e menus viver a nossa aplicao: precisamos chamar outras Activity's para trabalhar
com outras telas do nosso sistema. Dessa forma, ser possvel navegar pelas telas da nossa
aplicao atravs dos menus e botes.

O processo simples: criaremos uma outra Activity, que controlar as aes da nova tela,
e um novo Android XML para montar a diagramao da tela.

Em seguida, bastar fazer com que o clique em determinado menu chame o mtodo
startActivity(...), passando para ele um Intent: uma inteno de ir para outra
Activity. O Intent, por sua vez, precisar receber o objeto de contexto atual
(usualmente o this) e a classe que controla a tela para onde queremos ir.
1
2
Intent intent = new Intent(ContextoAtual.this, NovaActivity.class);
startActivity(intent);
Veremos em captulos posteriores que podemos abrir outras funcionalidades atravs dos Intents,
e no apenas outras activities. Aqui, pedimos explicitamente que a atividade NovaActivity
seja iniciada.

Na nova activity, dentro do onCreate utilizamos o mtodo setContentView para renderizar
a nova tela, puxando as informaes do XML:
1
setContentView(R.layout.novaActivity);
J outra Activity, deve ser chamada com o mtodo startActivity, com a Activity e a desejada.
Explicao
De nada adianta fazermos um formulrio para adicionar novos alunos se no temos como
guard-los. necessrio persisti-los de alguma forma.

Apesar da grande e crescente capacidade dos aparelhos mveis, em particular
aqueles que usam Android, ainda no vivel guardar um banco de dados completo nesses
dispositivos. Ento, usaremos o SQLite e alguns arquivos do sistema (SharedPreferences)
para persistir os dados no Android.

Seguindo a ideia do padro MVC, que pode ser visto mais a fundo no curso FJ21,
dividiremos a nossa aplicao em trs camadas. Uma camada que j temos trabalhado bastante
a de visualizao. Alm dela, j criamos alguns listeners que foram usados justamente
para controlar a integrao entre as nossas Views e as outras classes, essa camada
conhecida como Controller. Para completar o padro vamos implementar nossa camada
de modelo.

A camada de Modelo, a qual comearemos a trabalhar agora, onde basicamente ficaro as
lgicas da aplicao. Por exemplo, implementaremos nosso acesso ao Banco de Dados e
criaremos algumas classes que representam os conceitos importantes da aplicao.

Agora que temos uma tela com um formulrio vamos criar a funcionalidade de extrair os
dados preenchidos.

Na FormularioActivity podemos buscar os componentes de tela e ento extrair os
dados preenchidos:
1
2
3
4
5
6
7
EditText editText = (EditText) findViewById(R.id.nome);
EditText editSite = (EditText) findViewById(R.id.site);
// ...

String nome = campoNome.getText().toString();
String site = campoSite.getText().toString();
//...
Em nosso sistema as informaes nome, site, telefone, nota e endereco constituem os dados de
um aluno.
Em um sistema Orientado a Objetos criamos classes de modelo para tudo o que for importante. No nosso
caso, gostaramos de guardar os dados de um aluno. Para isso, criaremos uma classe
que representa a entidade Aluno com alguns atributos para guardar as informaes que so relevantes.
1
2
3
4
5
6
7
8
9
10
11
12
public class Aluno {

private Long id;
private String nome;
private String telefone;
private String endereco;
private String site;
private String foto;
private double nota;

//getters e setters
}
Assim podemos lidar com todas as informaes de um aluno em um lugar isolado. Se tivermos algum
comportamento especfico de um aluno podemos criar mtodos com regras de negcio nessa entidade.

Agora somos capazes de extrair os dados da tela de formulario e colocar em um objeto do tipo Aluno.
Na classe FormularioActivity que controla a tela de formulario podemos fazer:
1
2
3
4
5
6
7
8
9
EditText editText = (EditText) findViewById(R.id.nome);
EditText editSite = (EditText) findViewById(R.id.site);
// ...

Aluno aluno = new Aluno();

aluno.setNome(campoNome.getText().toString());
aluno.setSite(campoSite.getText().toString());
//...
Como podemos ter muita funcionalidade em uma tela a tendncia acabarmos um uma Activity com
muitas linhas de cdigo. Sempre que possvel uma boa prtica isolar pequenas responsabilidades
em outras classes para que a Activity faa seu trabalho interagindo com outros pequenos
especialistas. Essa abordagem facilita o reuso de cdigo (sem necessariamente fazer-se uso de herana)
e tambm a manuteno.

Vamos criar uma nova classe responsvel por extrair os dados do formulario para a FormularioActivity.
Vamos cham-la de FormularioHelper, ela receber no construtor
a instncia do FormularioActivity e cuidar da parte de extrair um aluno a partir dos dados dos
campos:
1
2
3
4
5
6
7
8
9
10
11
12
13
public class FormularioHelper {
private EditText nome;
private EditText telefone;
//... outros campos
private Aluno aluno;

public FormularioHelper(FormularioActivity activity) {
nome = (EditText) activity.findViewById(R.id.nome);
telefone = (EditText) activity.findViewById(R.id.telefone);
//... find no restante dos campos
aluno = new Aluno();
}

public Aluno pegaAlunoDoFormulario() {
14
15
16
17
18
19
20
21
22
aluno.setNome(nome.getEditableText().toString());
aluno.setEndereco(endereco.getEditableText().toString());

//... pega outros dados

return aluno;
}
}
Agora somos capazes de fazer com que o clique no botao de salvar crie um
um objeto do tipo Aluno a partir dos dados preenchidos no formulrio:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
protected void onCreate(Bundle savedInstanceState) {
//...

helper = new FormularioHelper(this);

Button botao = (Button) findViewById(R.id.botao);

botao.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Aluno aluno = helper.pegaAlunoDoFormulario();

Toast.makeText(Formulario.this, "Objeto aluno criado: "+aluno.getNome(),
Toast.LENGTH_SHORT).show();
}
});
}
Agora que fomos capazes de criar um objeto do tipo Aluno como vamos armazenar essa informao de
forma que quando sairmos da aplicao e voltarmos sejamos capazes de restaur-la?

Para nossa sorte os aparelhos Android vm com um banco de dados relacional instalado, o SQLite.

Mas, como vamos traduzir os dados do mundo relacional com o mundo Orientado a Objetos? Para isso,
utilizaremos
um padro de projeto (Design Pattern) conhecido como Data Access Object (DAO).

Para trabalhar com ele, basta seguir a abordagem padro: criar uma classe chamada AlunoDAO.
A diferena ser que ela deve estender de SQLiteOpenHelper e ter um construtor que recebe um objeto
do
tipo Context, o qual traz informaes sobre a aplicao.

Precisamos receber esse objeto porque, para construir corretamente o DAO, necessrio chamar
o construtor da classe me, passando o contexto e algumas configuraes do seu banco em particular.

Logo de cara teremos dois mtodos:


onCreate: executado na criao do banco;
onUpgrade: executado na alterao da estrutura do banco.
O onCreate vai ser invocado sempre que a tabela no existir, por exemplo no primeiro
acesso aplicao. J o mtodo onUpgrade mais especifico. Sempre que quisermos atualizar
a estrutura da nossa tabela, este mtodo sera chamado para executar o SQL necessrio
para realizar a atualizao. No nosso caso sempre apagaremos a tabela e criaremos
uma nova.

Para podermos invocar mtodos para executar operaes no banco como insert, update ou delete
usaremos objeto do tipo SQLiteDatabase, recebido atravs do mtodo getWritableDatabase que
herdamos de
SQLiteOpenHelper, e tambm recebemos no onCreate.

H tambm o mtodo getReadableDatabase, que tambm devolve uma referncia
para SQLiteDatabase,
gastando menos recursos porm possibilitando apenas leitura.

Para criarmos o banco, precisaremos executar uma query SQL indicando as colunas da nossa tabela
e seus respectivos tipos. Queremos armazenar cada atributo da classe Aluno nessa tabela,
ento teremos uma query assim:


"CREATE TABLE " + TABELA +
"(id INTEGER PRIMARY KEY," +
" nome TEXT UNIQUE NOT NULL," +
" telefone TEXT," +
" endereco TEXT," +
" site TEXT," +
" nota REAL," +
" foto TEXT" +
");"


Essa query deve ser executada na criao do banco de dados, portanto, no mtodo
onCreate e ela preparar nossa infraestrutura para guardar alunos. O
SQLiteDatabase tem o mtodo execSQL para isso.

Agora que temos a infraestrutura criada, basta adicionarmos mtodos no nosso DAO para
as aes que queremos executar.

Se voc j trabalha com Java, vai se lembrar bastante do estilo da API do JDBC, isto ,
teremos que converter manualmente um objeto na estrutura da tabela - sem a maior parte das
facilidades de uma ferramenta ORM.

Contudo, no ser necessrio escrever a query, j que ela vem encapsulada pelos
mtodos do SQLiteDatabase, provido pelo Android. Apenas preencheremos os parmetros.

Um objeto SQLiteDatabase j tem pronto o mtodo insert, que recebe o nome da tabela,
um parmetro que no nos importante no momento e o objeto a ser inserido.

Para inserir um novo registro neste banco, no precisamos de cdigo SQL, basta usar o
mtodo insert e o SQL correto j ser gerado, desde que tenhamos preenchido corretamente
os valores a serem adicionados. Faremos o seguinte:
1
getWritableDatabase().insert(TABELA, null, valores);
No mtodo insert, o primeiro parmetro uma String indicando a tabela onde os valores
devero ser inseridos. O segundo parmetro indica o valor padro das colunas caso o valor para ela
no seja definido.

Para preencher os valores corretamente, basta usar um objeto do tipo ContentValues,
que bem similar a um Map. Nele guardamos o contedo da linha
do registro a ser adicionada e vamos preench-lo usando o mtodo put("nomeDaColuna", valor).
Veja um exemplo abaixo:
1
ContentValues values = new ContentValues();
2
3
values.put("nome", aluno.getNome());
values.put("nota", aluno.getNota());
Para fazer a transformao de uma entidade para ContentValues, podemos criar um mtodo auxiliar
no prprio DAO. H aqui uma questo de gosto. Alguns vo preferir colocar na prpria classe
Aluno um mtodo toContentValues, porm quebra a um pouco da responsabilidade da entidade.

Com nosso DAO criado podemos fazer com que o clique no boto salva persista no SQLite o
objeto Aluno criado:
1
2
3
4
5
6
7
8
9
10
botao.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Aluno aluno = helper.pegaAlunoDoFormulario();

AlunoDAO dao = new AlunoDAO(this);
dao.insere(aluno);
dao.close();
}
});
Repare que invocamos o mtodo close herdado da classe SQLiteOpenHelper.
Quando nosso DAO instanciado ele acessa o banco, quando no precisamos mais
utiliz-lo devemos fechar a conexo!

O que fazer agora que o usurio de nossa aplicao conseguiu salvar o novo Aluno?
Provavelmente ele vai querer voltar para a tela de listagem para certificar-se
que o aluno foi realmente inserido. Para isso ele clicar no boto voltar do aparelho.
Vamos melhorar a usabilidade da aplicao e fazer isso para o usurio: se quisermos
programaticamente fazer o papel do boto de voltar podemos invocar o mtodo finish
de nossa Activity:
1
2
3
4
5
botao.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Aluno aluno = helper.pegaAlunoDoFormulario();

6
7
8
9
10
11
12
AlunoDAO dao = new AlunoDAO(this);
dao.insere(aluno);
dao.close();

finish();
}
});
Agora que fomos capazes de inserir alunos no SQLite vamos alterar a ListaAlunosActivity
para que os elementos da lista no sejam as constantes de um Array de Strings criados por ns.

Vamos adicionar ao nosso DAO um mtodo que vai retornar a lista de alunos
cadastrados no nosso sistema.

Buscar todos os alunos , contudo, ligeiramente mais complicado: teremos que lidar
com o cursor do banco de dados. Similarmente ao insert, contamos com outro mtodo
que nos permite mais liberdade na busca a ser realizada. Esse o mtodo query, que
recebe a tabela e um conjunto de colunas a serem recuperadas.
1
2
3
4
5
6
String[] colunas = {"nome", "telefone"};

Cursor cursor = getWritableDatabase().
query(TABELA, colunas, null, null, null, null, null);

cursor.moveToFirst();
Como comum buscarmos por todas as colunas, podemos definir uma array de string como
constante, contendo todas as colunas da nossa tabela.

Para saber mais...

Os outros muitos parmetros que deixamos nulos, nos permitem tambm fazer select,
groupBy, having e orderBy. Explore a API para aprender mais sobre essas
opes.

Do resultado dessa busca, receberemos um cursor e, com ele em mos, basta iterar sobre
suas diversas linhas, preenchendo objetos Aluno para cada registro do banco:
1
2
3
Aluno aluno = new Aluno();
aluno.setNome(cursor.getString(1));
aluno.setTelefone(cursor.getString(2));
Como desejamos obter uma lista de alunos precisaremos repetir o procedimento de extrair
os dados do Cursor enquanto existir um prximo registro. Podemos atingir esse objetivo
criando um lao e usando o cursor para verificar se existe um prximo registro salvo,
fazendo cursor.moveToNext() e adicionando cada aluno em uma lista criada.
1
2
3
4
5
6
7
8
9
List<Aluno> alunos = new ArrayList<Aluno>();

while(cursor.moveToNext()) {
Aluno aluno = new Aluno();
aluno.setNome(cursor.getString(1));
//...

alunos.add(aluno);
}
Note que poderamos, talvez, devolver o prprio cursor, mas no faremos isso porque essa
prtica vai contra o padro dos DAOs - a funo de um DAO abstrair, para quem o utiliza,
a interao com o banco de dados e suas classes especficas.

Muitos dos mtodos que estamos trabalhando aqui podem lanar android.database.SQLException,
que uma exceo de runtime, logo no somos obrigados a fazer o bloco de try/catch nem de
declarar seu throws. Em especial, ao se trabalhar com recursos que podem ficar abertos,
como o Cursor, boa prtica deixar seu fechamento dentro de um bloco finally, garantindo
seu fechamento.

Agora desejamos deletar um aluno de nossa listagem, podemos criar um mtodo em nosso DAO
que deleta um aluno passado como argumento:
1
2
3
4
public void deletar(Aluno aluno) {
String[] args = { aluno.getId().toString() };
getWritableDatabase().delete(TABELA, "id=?", args);
}
Quando vamos invocar esse mtodo?

Vamos pensar na usabilidade de nossa aplicao.
Quando clicamos no item da lista de alunos somos redirecionados para a o formulrio de cadastro para
fazer a alterao do aluno clicado.

Normalmente em sistemas operacionais o clique simples em um item na tela significa a seleo do item.
Quando desejamos outras opes de aes em um item normalmente o que fazemos clicar nele com o
boto
direito e esperamos que um menu de opes aparea para que possamos escolher qual ao desejamos.

No Android no temos boto direito mas esse papel nos devices realizado pelo clique longo. Podemos
fazer
com que o clique longo em um item cause a abertura de um menu de opes semelhante ao dos demais
sistemas
operacionais. O detalhe que as opes disponveis podem variar em funo do item clicado, devido a
esse fato esse tipo de menu no Android chamado do Menu de Contexto ou Context Menu.

No Android possumos o Menu de contexto. Ele nos d conforto ao tratar um item especfico,
abrindo um menu exclusivo para tal.

Para avisarmos ao Android que uma view possui um menu de contexto associado precisamos registr-la
utilizando o mtodo registerForContextMenu(aReferenciaParaAView) da classe Activity.

Em nossa aplicao queremos que o clique longo na ListView que contm a listagem culmine com a
abertura
do menu de contexto. Vamos ento registrar nossa listagem:
1
2
3
4
5
6
7
8
9
10
11
public class ListaAlunos extends Activity {

private ListView lista;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.listagem_alunos);

lista = (ListView) findViewById(R.id.lista);
//...

12
13
14
registerForContextMenu(lista);
}
Mas quais sero os itens que aparecero no menu de contexto quando clicarmos na listagem?

Quando fazemos um clique longo em uma View registrada para Menu de Contexto,
o Android invoca o mtodo onCreateContextMenu da Activity que estiver rodando.
Para customizar o contedo do menu de contexto utilizaremos esse mtodo de maneira
muito parecida com a criao dos itens do Options Menu:
1
2
3
4
5
6
7
8
9
10
public void onCreateContextMenu(ContextMenu menu, View view,
ContextMenuInfo menuInfo) {

menu.add("Ligar");
menu.add("Enviar SMS");
menu.add("Achar no Mapa");
menu.add("Navegar no site");
menu.add("Deletar");
menu.add("Enviar E-mail");
}
Em uma mesma tela vrias Views podem ser registradas para Menus de Contexto. Nesse caso
talvez precisssemos criar menus diferenciados para cada uma delas. Pensando exatamente nesse
problema
que o mtodo onCreateContextMenu recebe uma View passada como argumento. Podemos
verificar qual View foi criada e programaticamente criar menus diferentes em funo da View clicada.

O comportamento de clique no item do menu de contexto pode ser criado no ato de criao desse item.
Quando adicionamos programaticamente um item no menu de contexto criado um MenuItem ao qual
podemos
associar um Listener:
1
2
3
4
//...
menu.add("Navegar no site");

MenuItem deletar = menu.add("Deletar");
5
6
7
8
9
10
11
deletar.setOnMenuItemClickListener(new OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
//... comportamento do clique em deletar
return false;
}
});
Podemos tambm optar pela criao dos itens do menu atravs de xml.
Poderamos fazer a mesma abordagem que vimos com o MenuInflater, declarando um XML com
suas opes, batizando cada uma com um id em particular:
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"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="@+id/ligar"
android:title="Ligar"/>
<item
android:id="@+id/sms"
android:title="Enviar SMS"/>
<item
android:id="@+id/mapa"
android:title="Achar no Mapa"/>
<item
android:id="@+id/site"
android:title="Navegar no Site"/>
<item
android:id="@+id/deletar"
android:title="Deletar"/>
<item
android:id="@+id/email"
android:title="Enviar E-mail"/>
</menu>
21
No onCreateContextMenu basta fazer tambm
getMenuInflater().inflate(R.menu.menu_contexto, menu).

Para lidarmos com o clique no item do menu de contexto podemos sobrescrever o mtodo
onContextItemSelected e, baseado no id que demos para o item do menu podemos ter
um comportamento diferenciado.
1
2
3
4
5
6
7
8
9
10
@Override
public boolean onContextItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.deletar:
//??? qual aluno ???
break;
}

return super.onContextItemSelected(item);
}
O problema no caso da deleo que no sabemos qual item da lista foi clicado quando
o menu de contexto aparece.


Removendo o aluno selecionado utilizando o Context Menu


J possumos o mtodo deleta em nosso AlunoDAO e j criamos um menu de contexto para o clique
no item da ListView que contm os alunos cadastrados. Agora basta descobrirmos o aluno que foi
selecionado para deleo.

Sabemos que o usurio far um clique longo no item da ListView para disparar a criao do Menu de
Contexto
podemos alterar a implementao do OnItemLongClickListener para guardarmos o aluno selecionado
em um atributo
de nossa ListaAlunosActivity. No mtodo onCreate da ListaAlunosActivity:
1
2
listaAlunos.setOnItemLongClickListener(new OnItemLongClickListener() {
@Override
3
4
5
6
7
8
9
10
public boolean onItemLongClick(AdapterView<?> adapter, View view,
int posicao, long id) {

// guarda aluno escolhido em atributo
alunoSelecionado = (Aluno) adapter.getItemAtPosition(posicao);
return false;
}
});
Note que importante recarregar a lista, para que o elemento deletado no aparea
na tela.
Explicao
J possumos a capacidade de listar e inserir alunos em nossa aplicao.

Vamos agora prepar-la para alterar o dados do aluno e apagar um aluno!

Agora desejamos deletar um aluno de nossa listagem, podemos criar um mtodo em nosso DAO
que deleta um aluno passado como argumento:
1
2
3
4
public void deletar(Aluno aluno) {
String[] args = { aluno.getId().toString() };
getWritableDatabase().delete(TABELA, "id=?", args);
}
Quando vamos invocar esse mtodo?

Vamos pensar na usabilidade de nossa aplicao.
Quando clicamos no item da lista de alunos somos redirecionados para a o formulrio de cadastro para
fazer a alterao do aluno clicado.

Normalmente em sistemas operacionais o clique simples em um item na tela significa a seleo do item.
Quando desejamos outras opes de aes em um item normalmente o que fazemos clicar nele com o
boto
direito e esperamos que um menu de opes aparea para que possamos escolher qual ao desejamos.

No Android no temos boto direito mas esse papel nos devices realizado pelo clique longo. Podemos
fazer
com que o clique longo em um item cause a abertura de um menu de opes semelhante ao dos demais
sistemas
operacionais. O detalhe que as opes disponveis podem variar em funo do item clicado, devido a
esse fato esse tipo de menu no Android chamado do Menu de Contexto ou Context Menu.

No Android possumos o Menu de contexto. Ele nos d conforto ao tratar um item especfico,
abrindo um menu exclusivo para tal.

Para avisarmos ao Android que uma view possui um menu de contexto associado precisamos registr-la
utilizando o mtodo registerForContextMenu(aReferenciaParaAView) da classe Activity.

Em nossa aplicao queremos que o clique longo na ListView que contm a listagem culmine com a
abertura
do menu de contexto. Vamos ento registrar nossa listagem:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class ListaAlunos extends Activity {

private ListView lista;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.listagem_alunos);

lista = (ListView) findViewById(R.id.lista);
//...

registerForContextMenu(lista);
}
Mas quais sero os itens que aparecero no menu de contexto quando clicarmos na listagem?

Quando fazemos um clique longo em uma View registrada para Menu de Contexto,
o Android invoca o mtodo onCreateContextMenu da Activity que estiver rodando.
Para customizar o contedo do menu de contexto utilizaremos esse mtodo de maneira
muito parecida com a criao dos itens do Options Menu:
1 public void onCreateContextMenu(ContextMenu menu, View view,
2
3
4
5
6
7
8
9
10
ContextMenuInfo menuInfo) {

menu.add("Ligar");
menu.add("Enviar SMS");
menu.add("Achar no Mapa");
menu.add("Navegar no site");
menu.add("Deletar");
menu.add("Enviar E-mail");
}
Em uma mesma tela vrias Views podem ser registradas para Menus de Contexto. Nesse caso
talvez precisssemos criar menus diferenciados para cada uma delas. Pensando exatamente nesse
problema
que o mtodo onCreateContextMenu recebe uma View passada como argumento. Podemos
verificar qual View foi criada e programaticamente criar menus diferentes em funo da View clicada.

O comportamento de clique no item do menu de contexto pode ser criado no ato de criao desse item.
Quando adicionamos programaticamente um item no menu de contexto criado um MenuItem ao qual
podemos
associar um Listener:
1
2
3
4
5
6
7
8
9
10
11
//...
menu.add("Navegar no site");

MenuItem deletar = menu.add("Deletar");
deletar.setOnMenuItemClickListener(new OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
//... comportamento do clique em deletar
return false;
}
});
Podemos tambm optar pela criao dos itens do menu atravs de xml.
Poderamos fazer a mesma abordagem que vimos com o MenuInflater, declarando um XML com
suas opes, batizando cada uma com um id em particular:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="@+id/ligar"
android:title="Ligar"/>
<item
android:id="@+id/sms"
android:title="Enviar SMS"/>
<item
android:id="@+id/mapa"
android:title="Achar no Mapa"/>
<item
android:id="@+id/site"
android:title="Navegar no Site"/>
<item
android:id="@+id/deletar"
android:title="Deletar"/>
<item
android:id="@+id/email"
android:title="Enviar E-mail"/>
</menu>
No onCreateContextMenu basta fazer tambm
getMenuInflater().inflate(R.menu.menu_contexto, menu).

Para lidarmos com o clique no item do menu de contexto podemos sobrescrever o mtodo
onContextItemSelected e, baseado no id que demos para o item do menu podemos ter
um comportamento diferenciado.
1
2
3
4
@Override
public boolean onContextItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.deletar:
5
6
7
8
9
10
//??? qual aluno ???
break;
}

return super.onContextItemSelected(item);
}
O problema no caso da deleo que no sabemos qual item da lista foi clicado quando
o menu de contexto aparece.


Removendo o aluno selecionado utilizando o Context Menu


J possumos o mtodo deleta em nosso AlunoDAO e j criamos um menu de contexto para o clique
no item da ListView que contm os alunos cadastrados. Agora basta descobrirmos o aluno que foi
selecionado para deleo.

Sabemos que o usurio far um clique longo no item da ListView para disparar a criao do Menu de
Contexto
podemos alterar a implementao do OnItemLongClickListener para guardarmos o aluno selecionado
em um atributo
de nossa ListaAlunosActivity. No mtodo onCreate da ListaAlunosActivity:
1
2
3
4
5
6
7
8
9
10
listaAlunos.setOnItemLongClickListener(new OnItemLongClickListener() {
@Override
public boolean onItemLongClick(AdapterView<?> adapter, View view,
int posicao, long id) {

// guarda aluno escolhido em atributo
alunoSelecionado = (Aluno) adapter.getItemAtPosition(posicao);
return false;
}
});
Note que importante recarregar a lista, para que o elemento deletado no aparea
na tela.

Seguindo a mesma filosofia j estudada, a busca por id ser uma query passando
a String id=? como argumento, e o prximo parmetro uma array de string que
contm um nico element, o id que procuramos:
1
2
String[] args = {id.toString()};
Cursor c = getWritableDatabase().query(TABELA, COLS, "id=?",args , null, null, null);
Agora basta mover o cursor para o primeiro resultado e popular um novo aluno
com seus dados:
1
2
3
4
5
6
7
8
9
10
11
12
c.moveToFirst();

Aluno aluno = new Aluno();
aluno.setId(c.getLong(0));
aluno.setNome(c.getString(1));
aluno.setTelefone(c.getString(2));
aluno.setEndereco(c.getString(3));
aluno.setSite(c.getString(4));
aluno.setNota(c.getDouble(5));
aluno.setFoto(c.getString(6));

c.close();
Esse cdigo pode ficar dentro do nosso DAO, em um mtodo como getAlunoPorId(Long id).
Como comum popularmos uma entidade atravs dos dados adquiridos no cursor, pode ser
interessante isolar esse cdigo em um mtodo auxiliar, assim como possvel fazer
para gerar um ContentValues a partir de um Aluno e evitar repetio.

Вам также может понравиться