Anda di halaman 1dari 30

Programação em Android

sexta-feira, 12 de outubro de 2012

Como navegar entre telas no Android

Olá a todos.

Até este tópico, aprendemos como instalar o Android, criar um projeto e até mesmo criar
layouts bem completos. Qual o próximo passo? Até agora, em todos os exemplos vistos, foi
utilizada no máximo uma tela por exemplo. O próximo passo a ser dado é aprender a navegar
entre mais de uma tela em uma mesma aplicação.

Em Android, cada tela é uma classe Java que estende da classe Activity. Para navegarmos entre
mais de uma Activity, devemos utilizar a classe Intent. A melhor tradução para esta palavra é
"intenção". Se estamos em uma Activity e queremos ir para outra, temos que chamar uma
Intent (ou seja, temos a "intenção" de mudar de uma tela para outra).

Para entender o conceito de Intent, criaremos 3 exemplos bem simples em que basicamente
trafegaremos entre várias telas de uma mesma aplicação. No 1º exemplo, criaremos uma
transição simples de uma tela para outra. No 2º exemplo, criaremos uma transição de uma
tela para outra em que a tela de origem enviará uma variável para a tela de destino. No 3º
exemplo, criaremos uma transição de uma tela para outra em que a tela de destino retornará
um valor para a tela de origem. Este tópico do blog se dividirá entre esses 3 exemplos.

Transição simples de uma tela de origem para uma tela de destino

Em Android, quando criamos um projeto no Eclipse, é gerado o arquivo AndroidManifest.xml,


que é um arquivo de configuração onde relatamos várias informações, como quais telas
existem na aplicação, qual é a API mínima e a API máxima do Android que a aplicação poderá
rodar, dentre outras. Logo, o primeiro passo a ser dado na criação do nosso exemplo é
informar ao AndroidManifest.xml as telas que usaremos em nossa aplicação. Vamos supor que
teremos 3 telas em nossa aplicação: Tela1Activity.java, Tela2Activity.java e Tela3Activity.java
(é aconselhável, em Android, o nome de uma Activity possuir o posfixo "Activity"). Então,
precisamos declará-las no arquivo AndroidManifest.xml, tal qual mostrado abaixo:
Agora que já temos as Activity's declaradas no AndroidManifest.xml, o próximo passo será
criar o layout de cada uma dessas telas. De início, criaremos algo bem simples, como uma
TextView sendo mostrada no centro da tela. Algo como isso:
Para cada tela, o parâmetro android:text="@string/tela1_title" será adaptado para os devidos
nomes (para a Tela2 por exemplo, o parâmetro será android:text="@string/tela2_title", e com
a Tela3, analogamente).

Em seguida, precisamos criar as Activity's dessas telas (as classes Java estendendo da classe
Activity). Elas basicamente seguirão o modelo mostrado abaixo:
Agora que criamos todas as nossas telas, seus layout's, e as declaramos no
AndroidManifest.xml, poderemos enfim lidar com as Intent's, que nos permitirão navegar
dentre essas 3 telas.

Para navegarmos entre as telas, precisamos criar um dispositivo de entrada ao usuário, para
que ele escolha quando essa transição entre as telas ocorrerá. O melhor dispositivo para esse
caso é criar um Button que, quando clicado, mude a tela corrente da aplicação. Para isso,
criaremos um Button na Tela1Activity.java e outro Button na tela Tela2Activity.java. A idéia é
que a transição ocorra da Tela1 para a Tela2, e da Tela2 para a Tela3.

Modificando o layout da Tela1, teremos o seguinte conteúdo em seu arquivo XML:


E seu layout ficará como mostrado abaixo:
Agora, precisamos mapear o id do Button na nossa Activity (tal qual ensinado no tópico
anterior). Modificando a estrutura do código-fonte da tela Tela1Activity.java, teremos o
seguinte conteúdo:
Agora, nos restar implementar a chamada à Tela2. Para chamarmos outra tela em Android,
precisamos usar uma Intent. A sintaxe de uma chamada à uma classe Intent é mostrada
abaixo:

O construtor da classe Intent é: Intent intent = new Intent(packageContext, cls). O argumento


"packageContext" é o contexto da Activity atual. O argumento "cls" é a classe da Activity para
a qual a Activity atual deseja ir. Na imagem acima, os valores desses argumentos são,
respectivamente, "Tela1Activity.this" e "Tela2Activity.class". Ou seja, temos a "intenção" de
migrar da Tela1 para a Tela2.

O código-fonte completo da Tela1Activity.java é mostrado abaixo:


Agora, basta adaptarmos esse código-fonte para a Tela2Activity.java, para termos
implementada a transição entre a Tela2 e a Tela3. E pronto! Teremos implementada uma
aplicação com diversas telas, e com a transição entre elas.

Seguindo este tópico, iremos ver como implementar uma transição entre duas telas em que a
tela de origem enviará dados para a tela de destino.

Transição de uma tela de origem para uma tela de destino com envio de informações entre
elas

Na transição acima, utilizamos o método startActivity() para realizar a transição entre telas.
Porém, foi uma transição simples, sem envio de informações. Desta vez, enviaremos
informações de uma tela para a outra. Para realizar este tipo de tarefa, ainda utilizaremos o
método startActivity(). Porém, modificaremos um pouco sua estrutura, tal qual mostrado
abaixo:

A imagem acima é o conteúdo atualizado do evento onClick(). O que mudou aqui é que
incluímos um Bundle na Intent que chama a próxima tela. Em Android, Bundle é a classe que
armazena o que será enviado de uma tela para outra. Esta classe possui vários métodos. Na
imagem acima, podemos notar o método putString(). Este método recebe a "chave" da string
que passaremos para a próxima tela e o seu valor. A chave é um valor (sempre em String) que
utilizaremos para obter, na tela de destino, os dados passados de uma tela para a outra.

Agora que transmitimos dados da tela de origem para a tela de destino, precisamos captar
esses dados na tela de destino (neste caso, na Tela2Activity.java). Isto é feito através do
método getIntent().getExtras(), que retorna um Bundle. Abaixo é mostrado o código-fonte de
um método customizado que realiza essa leitura.
Algumas observações precisam ser feitas a respeito da imagem acima:

Temos que verificar se os extras são nulos ou não. Isso é vital, pois podemos chamar uma tela
a partir de diferentes telas. Por exemplo, tanto a Tela1 como a Tela2 podem chamar a Tela3. E
se a Tela1 enviar dados para a Tela3, os extras da imagem acima não serão nulos. Mas se a
Tela2 não enviar dados para a Tela3, os extras da imagem acima serão nulos.

mTextView é um atributo da Tela2Activity.java, que nada mais é do que a TextView desta tela.
Como estamos recebendo dados da tela anterior, para verificarmos se estes dados chegaram
da Tela1 para a Tela2, atualizaremos esta TextView.

O código-fonte completo desta tela é mostrado abaixo:


E pronto! Já sabemos como transmitir dados de uma tela para outra. Seguindo este tópico,
iremos ver como implementar uma transição entre duas telas em que a tela de destino
retornará um valor para a tela de origem.

Transição de uma tela de origem para uma tela de destino, com envio de uma informações da
tela de destino para a tela de origem

Nas transições acima, utilizamos o método startActivity(). Desta vez, utilizaremos outro
método: startActivityForResult(). Com este método, a Activity de destino consegue retornar
informações à Activity de origem. Isso é bem útil em alguns casos.
Por exemplo, suponha que temos uma Tela1, que pode chamar tanto uma Tela2 como uma
Tela3 Neste caso, se a Tela1 for uma tela de cadastro de clientes, a Tela2 for uma tela de
deleção de clientes, e a TelaC for uma tela de matrícula de clientes, ao abrirmos as telas 2 ou 3
e realizarmos alguma operação, seremos redirecionados à Tela1. Mas nesta tela, precisamos
saber se a deleção/matrícula foi feita com sucesso ou não. Neste caso, precisamos enviar
alguma informação de retorno à Tela1, a partir do término de execução das telas 2 e 3. Isso é
feito com o método startActivityForResult().

Abaixo será mostrado um exemplo mais básico desta funcionalidade. A idéia básica é que uma
Activity seja chamada na Tela1, e que a Activity filha chamada retorne uma informação à
Tela1. A Tela1 poderá chamar tanto a Tela2 como a Tela3. Esta informação será captada pela
Tela1 através do evento: protected void onActivityResult(int codigo, int resultado, Intent
intent). Vamos ao nosso exemplo.

Abaixo é mostrado os layout XML das nossas telas.


E o código-fonte da Tela1Activity.java:
E agora, o código-fonte da Tela2Activity.java. A Tela3 será análoga à esta tela.
Agora, vamos executar este exemplo, para fixar bem tudo que foi falado acima. Clicando no
botão "Ir para Tela 2", eis o que acontece:
Agora estamos na Tela2. Clicando no botão "Voltar à tela anterior", eis o que acontece:

Basicamente, o que aconteceu foi que a Tela1 recebeu retornou de sua Activity filha. Desta
forma, conseguimos identificar qual das telas foi chamada pela Tela1.

E pronto! Já sabemos como transmitir dados de uma tela para outra de todas as maneiras
possíveis. Mas antes de fecharmos este tópico, iremos falar de uma propriedade de layout
muito útil em Android.
Quando um botão é clicado, o ideal seria o usuário ter um feedback do que aconteceu. Ou
seja, quando o botão for clicado, ficar de uma cor. Quando for solto, ficar de outra. Desta
forma, o usuário saberá se o evento de clique do botão foi acionado ou não. Vamos
implementar isso em nosso exemplo.

Inicialmente, iremos implementar o arquivo XML que "anima" o botão. Vamos chamá-lo de
"comportamento_botao.xml". Seu código-fonte será o seguinte:

Ou seja, quando o botão for clicado, um drawable será chamado. Quando ele não for clicado,
outro drawable será chamado. Agora, precisamos entender o conteúdo dos eventos citados no
arquivo acima (comportamento_pressionado.xml e comportamento_normal.xml). Abaixo é
mostrado o código-fonte dos respectivos arquivos citados ao lado:
Esses arquivos possui alguns parâmetros:

gradient → Este parâmetro escolhe a cor que o botão terá. Ele pode ter 3 cores diferentes,
germinadas. No caso do nosso exemplo, teremos um gradiente de cores idênticas (as mesmas
para cada opção de gradiente) em cada drawable.

corners → Este parâmetro cria contornos suaves no botão. No nosso caso, teremos os cantos
do botão levemente arredondados em um tamanho de 3dp.
stroke → Parâmetro que traça uma borda em nosso botão. Aqui, teremos uma borda preta de
1px de tamanho.

OBS.: Existem outros parâmetros além dos 3 acima. Mas eles não serão vistos neste momento.

Agora, precisamos ativar essa animação nos botões de nosso exemplo. Para fazer isto, basta
incluir o parâmetro android:background="@drawable/comportamento_botao" em cada um
dos botões de nosso aplicativo. Fazendo isso, teremos botões muito mais elegantes, e bem
intuitivos ao usuário.

-----

E aqui terminamos mais um tópico do blog.

Caso alguém tenha uma dúvida, crítica ou sugestão, sinta-se à vontade.

Postado porRodrigo Cericattoàs12:23

Enviar por e-mailBlogThis!Compartilhar no TwitterCompartilhar no FacebookCompartilhar no


Orkut

29 comentários:

MARLLON5 de dezembro de 2012 07:12

Amigo, muito boa sua iniciativa de ensinar a galera as transições. Eu gostaria de saber como
poderia fazer uma transição dessas, mas com imagens, como se fossem esses jogos para
android com as imagens dos criadores do jogo que fazem a transição sem precisar tocar na tela
até chegar no menu principal. vlw.

ResponderExcluir

Respostas

Rodrigo Cericatto5 de março de 2013 08:59


Olá.
Desculpe-me pela demora. Acho que o Gmail não me avisou sobre sua postagem. Só hoje a vi.
Para fazer essa transição, você pode usar o componente ImageButton. Você está familiarizado
com este componente?

Excluir

Responder

Dalvane Janquiel Wehrmeier10 de março de 2013 11:37

Olá Rodrigo, vendo seu tópico e foi ótimo agora que estou iniciando na programação de
aplicativos para Android. Só gostaria de sanar uma duvida, se ao invés de criar novas paginas
eu quise-se apenas a transição delas, no momento em que eu clica-se no botão a pagina antiga
se fecha-se. É possível?
Obrigado e ótimo trabalho!

ResponderExcluir

Rodrigo Cericatto10 de março de 2013 12:50

Dalvane, obrigado pelos elogios!


Sobre sua dúvida, se a página (tela) já existir, basta que você utilize o método
"startActivity(Intent intent);" dentro do evento "onClick()" do botão, e também que você
utilize o método "finish()" dentro do evento "onDestroy()" da Activity que foi fechada.
Isso garantirá o funcionamento que você deseja.
Abraço!

ResponderExcluir

Alexandre LeanderChip9 de abril de 2013 07:21

E pra retornar a Activity anterior? Tipo Fui da tela1 pra tela2 e agora quero retornar a tela1?
aqui ele pega o evento de onClick e só vai pra próxima, ja experimentei cria um parametro
onClick com o nome voltar mas mesmo assim ele pega o onClick que passa pra prómia tela...

ResponderExcluir

Rodrigo Cericatto9 de abril de 2013 13:27

Olá Alexandre.
Neste caso você precisa criar um evento de clique na Tela2, e dentro dele declarar o método
"finish()", tal qual expliquei ao Dalvane. Assim ele "matará" a Activity2 e retornará à última
Activity acessada, que neste caso é a Activity1.
Caso você não consiga, me diga.

ResponderExcluir

Leonardo Macedo Esteves21 de maio de 2013 20:49

Oi Rodrigo , fiz exatamento como vc indicou mas quando vou passar da primeira para a
segunda tela aparece um erro dizendo "Infelzimente o programa parou."
tem ideia do que pode estar acontecendo?

ResponderExcluir

Rodrigo Cericatto21 de maio de 2013 22:32

Você poderia me mandar o código fonte via e-mail?

ResponderExcluir

Mariana Andrade27 de maio de 2013 14:41

rodrigo,
estou com o mesmo erro já tentei varias formas de fazer
tento colocar o map V2 também da erro e diz que o programa parou
não sei se você ouviu falar diz que nao tem o openGL 2.0
estou tentando montar um app mais estou apanhando muito
e dormindo pouco rsrsr te add no facebook
espero que possa me ajudar
estou entrando agora nesse mundo e tenho que
parabenizar pessoas como você que esta disposto a ajudar

ResponderExcluir

Rodrigo Cericatto27 de maio de 2013 20:28

Opa Mariana.
Me diga, como é esse programa que você está criando? Poderia me dar maiores detalhes para
eu ajudá-la?

ResponderExcluir

Mariana Andrade27 de maio de 2013 23:08


Bom dia Rodrigo,
primeiro seria as telas rsrsrs
eu nao consigo interligar elas.

seria assim...

tela 1 liga com tela 2 e 3


tela 2 liga com 1 e 3
tela 3 liga com 4 e 5 e 6 e 7 e 8 e 9
tela 4 liga com 3
tela 5 liga com 3
tela 6 liga com 3
tela 7 liga com 3
tela 8 liga com 3
tela 9 liga com 1

é um programa bem interessante, e se der certo você poderia trabalhar comigo


isso seria apenas o começo, mas podemos começar por ai rsrsrs

Desde já agradeço

ResponderExcluir

Rodrigo Cericatto28 de maio de 2013 23:15

Olá Mariana.
Vamos por partes.
Você não consegue criar um botão na Tela1 que conecte-o à Tela2 e à Tela3?
Mesmo seguindo meu tutorial, na parte referente à imagem abaixo?
http://3.bp.blogspot.com/-N4Qv0vYpyJI/UHhsEzlQ7gI/AAAAAAAAAfs/l-
SyA_zesAQ/s1600/05.png

ResponderExcluir

Mariana Andrade29 de maio de 2013 03:07

Olá Rodrigo,
então eu consigo conectar a primeira tela com até
duas telas ou seja tela 1 com tela 2 e 3
, mas nao consigo fazer voltar diz que o programa parou
e fecha ai nao consigo mais fazer exemplo da tela 2 para 3 ou simplesmente retornar a tela 1,
nao sei o que faço errado. estou tentando parar um activity e iniciar outro um por cada tela,
mas ainda nao estou conseguindo.
mas enfim é isso eu nao consigo resumindo tudo rsrs
se vc tiver um código semelhante com o que eu preciso e puder me mandar rsrsr

ResponderExcluir

Mariana Andrade29 de maio de 2013 03:10

public class MainActivity extends Activity {

Button btnovatela, btirtela2;

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

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


btnovatela.setOnClickListener(new View.OnClickListener() {

@Override
public void onClick(View v) {
chamanovatela();

}
});
btirtela2 = (Button) findViewById(R.id.btirtela2);
btirtela2.setOnClickListener(new View.OnClickListener() {

@Override
public void onClick(View v) {
chamatela2();

}
});
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;

}
public void chamanovatela(){
setContentView(R.layout.novatela);

}
public void chamatela2(){
setContentView(R.layout.tela2);
}
}

quando vou fazer a terceira parte igual a essas da erro

ResponderExcluir

Mariana Andrade29 de maio de 2013 14:48

Rodrigo,
Conseguiii

Segui seu exemplo e funcionou perfeitamente


muito obrigado mesmo
logo segue mais duvidas rsrsrsr

muito obrigado mesmo

ResponderExcluir

Rodrigo Cericatto29 de maio de 2013 17:12

Que erro que estava acontecendo?


Precisando é só perguntar!

ResponderExcluir

Mariana Andrade29 de maio de 2013 17:35

Boa noite Rodrigo,


tudo bem ?

eu consegui fazer a navegacao entre telas, mais consigo apenas um comando por tela,
você sabe me dizer qual comando uso para mais de um?

exemplo eu fiz 3 telas e fiz a 1 ir para 2 e a 2 ir para a 3 e a 3 ir para 1.


mas preciso fazer a 1 ir para 2 e para 3 e quando faco o mesmo comando na tela ele nao vai,

public void chamanovatela(){


setContentView(R.layout.novatela);

com esse comando vai mais ai ele nao obedece mais o os demais,

você sabe algum que eu possa por em conjunto?


para acionar um segundo botao na mesma tela?

ResponderExcluir

Rodrigo Cericatto30 de maio de 2013 12:19

Você quer que o aplicativo vá da Tela1 para a Tela2 e a Tela3, ao mesmo tempo? Ou que da
Tela1 tenhamos opções para ir tanto para a Tela2 quanto para a Tela3?

ResponderExcluir

Mariana Andrade31 de maio de 2013 08:21

Este comentário foi removido por um administrador do blog.

ResponderExcluir

Gabriel29 de junho de 2013 12:41

Oi, Rodrigo. Muito bom tutorial. Parabéns.

E no caso, por exemplo, de querer retornar uma String de uma Acivity filha? No seu exemplo, a
tela1 apenas informa (através de Toast) qual tela foi chamada. Tem como manusear os
Bundles/Intents para que eles retornem uma String?

No meu caso, chamo um FileChooser por uma Activity e preciso que o FileChooser retorne o
caminho encontrado para a Activity. Consigo pegar o caminho e imprimi-lo (através de Toast)
no FileChooser, mas não consigo pegar esse caminho de volta (uma String) na atividade que
chama o FileChooser? Fui claro?

Obrigado novamente!

ResponderExcluir
Rodrigo Cericatto29 de junho de 2013 12:54

Gabriel, basta passar um Bundle na chamada referenciada em "Transição de uma tela de


origem para uma tela de destino, com envio de uma informações da tela de destino para a tela
de origem".

ResponderExcluir

Gabriel29 de junho de 2013 13:09

Desculpa, não entendi. Você quer dizer em startActivityforResult? Porque esse método só
aceita Intent como parâmetro.

Estou fazendo (o FileChooser é chamado pelo menu):

case R.id.importar:
Intent intent1 = new Intent(MainActivity.this, FileChooser.class);
Bundle extras = new Bundle();
extras.putString("path", "vazio");
intent1.putExtras(extras);
startActivityForResult(intent1, code);
return true;

Isso para a chamada.

E depois segue:

public void onActivityResult(int requestCode, int resultCode, Intent data) {


Log.i("MainActivity", "Entrou na funcao " + "codigo: " + requestCode + "code: " + code);
if (requestCode == code) {
Bundle extras = new Bundle();
extras = data.getExtras();
Log.i("MainAct", "Retornou");
Toast.makeText(this, "Caminho: " + extras.getString("path"), Toast.LENGTH_LONG).show();
}

Mas esse Toast não é mostrado.

ResponderExcluir

Rodrigo Cericatto29 de junho de 2013 13:32


Aqui:
http://2.bp.blogspot.com/-j0mY5QynnRI/UHhtQOIoP_I/AAAAAAAAAhE/0z_WNEDaH-
0/s1600/16.png

Na função "setaResultadoActivity".

ResponderExcluir

*Rafa*12 de setembro de 2013 10:44

Oi Rodrigo, estou começando com Android agora e achei muito interessante seu texto, mas
fiquei com uma dúvida, no exemplo que você deu só passa uma variável para a segunda tela.
Como faço para passar várias variáveis? no meu caso tenho uma tela onde o usuário digita
alguns números e quando ele clica no botão tabela, abre outra tela que faz uma tabela com os
dados digitados. Como faço para passar mais de um valor para outra tela?

ResponderExcluir

Rodrigo Cericatto12 de setembro de 2013 19:52

Basta colocar mais de uma linha, tal quais a dos tipos abaixo:
"extras.putString(, )"
ou
"extras.putBoolean(, )"

ResponderExcluir

Unknown23 de setembro de 2013 08:08

Mano, sabes como fazer para a próxima tela, entrar com uma animação, tipo surgindo da
esquerda, ou da direita?

ResponderExcluir

Rodrigo Cericatto23 de setembro de 2013 09:28

Sei sim. Este será o tema do próximo post que farei aqui o Blog.

ResponderExcluir

Rodrigo27 de setembro de 2013 19:43


Muito bom seu post, parabéns por compartilhar esse conteúdo.
Apenas um problema que está ocorrendo com o meu app, quando eu saio do menu (tela1) e
vou para tela2, eu consigo criar um botão de voltar e funciona tranquilo, mas quando eu uso o
botão de voltar do aparelho a aplicação fecha no lugar de voltar ao menu. Qual seria a
solução? desde já agradeço.

ResponderExcluir

Rodrigo Cericatto29 de setembro de 2013 15:37

Olá Rodrigo.
Estranho este comportamento. A lógica parece estar certa. Para eu opinar melhor, só vendo o
código-fonte da sua aplicação.

Anda mungkin juga menyukai