Baixe o app para aproveitar ainda mais
Prévia do material em texto
Curso Técnico em Desenvolvimento de Sistemas Educação a Distância 2018 2018 Programação para Dispositivos Móveis Gilson de Oliveira EXPEDIENTE Professor Autor Gilson de Oliveira Design Educacional Deyvid Souza Nascimento Renata Marques de Otero Revisão de Língua Portuguesa Letícia Garcia Diagramação Jailson Miranda Coordenação Anderson Elias Coordenação Executiva George Bento Catunda Terezinha Mônica Sinício Beltrão Coordenação Geral Paulo Fernando de Vasconcelos Dutra Conteúdo produzido para os Cursos Técnicos da Secretaria Executiva de Educação Profissional de Pernambuco, em convênio com o Ministério da Educação (Rede e-Tec Brasil). Janeiro, 2017 Dados Internacionais de Catalogação na Publicação (CIP) de acordo com ISDB O48p Oliveira, Gilson de. Programação para Dispositivos Móveis: Curso Técnico em Desenvolvimento de Sistemas: Educação a distância / Gilson de Oliveira. – Recife: Secretaria Executiva de Educação Profissional de Pernambuco, 2018. 91 p.: il. Inclui referências bibliográficas. Material produzido em dezembro de 2016 através de convênio com o Ministério da Educação (Rede e-Tec Brasil) e a Secretaria de Educação de Pernambuco. 1. Engenharia de Software. 2. Dispositivos Móveis. I. Oliveira, Gilson de. II. Título. CDU – 02:141:005.6 Elaborado por Hugo Carlos Cavalcanti | CRB-4 2129 Índice para catálogo sistemático: 1. Engenharia de software Sumário Introdução .............................................................................................................................................. 6 1.Competência 01 | Apresentando a Classe Activity, Ciclo de Vida e Tipos de Activity ........................ 8 1.1 Activity........................................................................................................................................................ 8 1.2 Ciclo de vida de uma Activity ..................................................................................................................... 9 1.3 Navegação entre activities ....................................................................................................................... 14 1.3.1 Navegação simples de uma activity para outra .................................................................................... 14 1.3.2 Navegação entre telas com passagem de parâmetros ......................................................................... 16 1.4 ListActivity – uma activity diferente ......................................................................................................... 18 2.Competência 02 | Intent ................................................................................................................... 22 2.1 Abrindo o browser e acessando um site específico ................................................................................. 22 2.2 Fazendo uma ligação para um número de telefone ................................................................................ 25 2.3 Solicitando ao google maps que exiba um local específico do mapa ...................................................... 28 2.4 Acessando contatos da agenda ................................................................................................................ 29 2.5 Retornando resultados de uma activity para outra através do método startActivityForResult ............. 30 2.6 Intent – Resumo ....................................................................................................................................... 33 3.Competência 03 | Conceitos de Interface Gráfica ............................................................................ 34 3.1 A classe View ............................................................................................................................................ 34 3.2 ViewGroup e gerenciadores de layout ..................................................................................................... 34 3.3 FrameLayout ............................................................................................................................................ 35 3.4 O famoso LinearLayout ............................................................................................................................ 39 3.5 RelativeLayout .......................................................................................................................................... 41 3.6 AbsoluteLayout (deprecated ou depreciado) .......................................................................................... 45 3.7 Resumo ..................................................................................................................................................... 47 4.Competência 04 | Conhecendo os Conceitos de Interface Gráfica .................................................. 49 4.1 Especificando texto, cores e imagens da aplicação ................................................................................. 49 4.2 Arquivo com as mensagens da aplicação ................................................................................................. 50 4.3 Arquivo com as cores da aplicação .......................................................................................................... 51 4.4 Criando estilos .......................................................................................................................................... 52 4.5 Usando temas do Android ....................................................................................................................... 53 4.6 Definindo as dimensões dos componentes de layout ............................................................................. 55 4.7 Resumo ..................................................................................................................................................... 56 5.Competência 05 | A Classe View Elementos Básicos ........................................................................ 58 5.1 TextView ................................................................................................................................................... 59 5.2 EditText .................................................................................................................................................... 61 5.3 Button e ImageButton .............................................................................................................................. 62 5.4 CheckBox .................................................................................................................................................. 65 5.5 RadioButton ............................................................................................................................................. 66 5.6 Spinner ..................................................................................................................................................... 68 5.7 ProgressDialog.......................................................................................................................................... 71 5.8 Toast ......................................................................................................................................................... 72 5.9Resumo ..................................................................................................................................................... 73 6.Competência 06 | Banco de Dados, SharedPreferences e APIs Importantes .................................. 74 6.1 Banco de dados ........................................................................................................................................ 74 6.2 SQLite ....................................................................................................................................................... 74 6.3 Preferências do usuário ........................................................................................................................... 75 6.4 API de Mapas ........................................................................................................................................... 77 6.5 GPS ........................................................................................................................................................... 77 6.6 Resumo ..................................................................................................................................................... 78 7.Competência 07 | Publicando Aplicação na Google Play ................................................................. 79 7.1 Versionamento da sua app ...................................................................................................................... 79 7.2 Compatibilidade para instalação da aplicação ......................................................................................... 81 7.3 Assinando a aplicação com um certificado digital ................................................................................... 82 7.4 Assinando a aplicação para publicá-la no Google Play ............................................................................ 85 7.5 Publicando a sua aplicação na Google Play ............................................................................................. 86 Conclusão ............................................................................................................................................. 89 Referências ........................................................................................................................................... 90 Minicurrículo do Professor ................................................................................................................... 91 Gilson de Oliveira ................................................................................................................................. 91 6 Introdução Neste caderno vamos aprender mais sobre o sistema operacional Android, suas principais classes, características e comportamentos. A plataforma Android foi escolhida neste curso por ser bastante difundida, madura, robusta e acessível, tanto para desenvolver quanto para um usuário que deseja adquirir um equipamento que pode ser um tablet ou smartphone. Para iniciar o desenvolvimento, não existem muitas restrições, não é preciso de um equipamento específico, licença ou certificado de desenvolvimento, basta ter um computador (atendendo os requisitos mínimos de processamento especificados pela ferramenta de desenvolvimento que você deseja utilizar), fazer o download gratuito de uma IDE (Integrated Development Environment, que significa ambiente de desenvolvimento integrado e se refere a ferramentas de desenvolvimento como Eclipse ou Android Studio, por exemplo) e instalar o SDK (Software Development Kit) Android. Dentre as três principais plataformas de desenvolvimento móvel, o Android é uma das mais acessíveis no que diz respeito à aquisição de um exemplar. Existem smartphones de todos os preços, os mais baratos custam em torno de 250,00 reais e os mais caros podem custar até milhares de reais, por exemplo, os modelos top de linha da Samsung podem custar cerca de R$ 6.000. Tendo um aparelho é possível você instalar e testar o seu aplicativo no próprio dispositivo e observar o seu comportamento e layout, isso é bastante interessante, mas caso você não possua um smartphone, você pode fazer uso do emulador que simula a utilização de um dispositivo no seu próprio computador. O Android é o sistema operacional (SO) mais utilizado no mundo. Em 2014, a GOOGLE anunciou que existem mais de 1 bilhão de usuários Android ativos. Apesar de ter sido criado pela GOOGLE, o Android é regido por uma licença de código aberto, ou seja, é permitido que você baixe o código do sistema operacional Android e o modifique da maneira que você desejar. Essa prática de modificar o SO Android é bastante comum e utilizada pela maioria das empresas. Dessa forma, há uma combinação do código aberto disponibilizado com o código privado desenvolvido pela empresa. Essas modificações no SO feitas pela empresa vão desde melhorias na interface, com aumento de nitidez das imagens, brilho, performance, até a incorporação de aplicativos nativos da empresa. Falando em desenvolvimento de aplicativos para a plataforma Android de forma autônoma, o GOOGLE possui a GOOGLE PLAY, que é a loja da empresa para a disponibilização e venda de aplicativos para a plataforma Android. Caso você crie o seu próprio aplicativo, pode 7 vendê-lo na loja da GOOGLE ou mesmo disponibilizá-lo de forma gratuita e tentar ganhar dinheiro através de anúncios e propagandas que a GOOGLE embute no seu aplicativo, caso você permita. Existem vários casos de sucesso de pessoas jovens que criaram aplicativos, colocaram na loja e ficaram ricas. O criador do Ant Smasher já teve o seu jogo baixado por mais de 30 milhões de pessoas. O aplicativo é gratuito, mas rende mais de 3 milhões de dólares por ano apenas com anúncios. O criador de Flappy Bird, um jogo bem simples, chegou a, no início de 2014, 50 mil dólares por dia. Por que você não pode ser uma dessas pessoas? Aprender uma linguagem de programação exige dedicação, persistência e curiosidade. Dedicação e persistência para estudar o material disponibilizado e fazer os exercícios propostos, curiosidade para ir atrás de novas informações, notícias, outros materiais e novos exercícios. Quando terminar de estudar o material do curso, busque novos materiais, tutoriais e outros exemplos em livros e na internet. O ser humano aprende por repetição, quanto mais você praticar, mais você vai assimilar o conteúdo. A cada exemplo, tente entendê-lo e tente você mesmo fazer e não fique apenas como espectador, dessa forma você criará suas próprias soluções. Nos próximos capítulos vamos falar de algumas das classes mais importantes utilizadas para o desenvolvimento em Android. Com relação à ferramenta de desenvolvimento (também chamada tecnicamente de IDE - Integrated Development Environment) você pode tanto usar o Eclipse (ADT – Android Development Tools) ou o Android Studio (mais recomendo). Comercialmente, o Android Studio vem sendo cada vez mais usado, principalmente para novos projetos. Para fazer o download do Android Studio, basta acessar o site https://developer.android.com/studio/index.html?hl=pt-br e fazer o download da versão mais recente. Caso você ainda não tenha o SDK Android, deve baixar o Android Studio com o SDK. Caso já tenha, basta baixar apenas o Android Studio. E então, vamos começar a nos divertir? Competência 01 8 1.Competência 01 | Apresentando a Classe Activity, Ciclo de Vida e Tipos de Activity Vamos aprender neste capítulo o conceito de activity, como funciona o seu ciclode vida, como mudar de uma activity para outra. Aprenderemos também como trafegar informações entre as telas da sua aplicação e falaremos da ListActivity, que é um tipo específico de activity. Vamos começar! 1.1 Activity Uma Activity é uma classe que herda de Android.app.Activity ou alguma subclasse desta. Em geral, toda tela de uma aplicação em Android está associada a uma Activity e esta é responsável por tratar todos os seus eventos como cliques de botão, seleção de checkbox, cliques no menu e mudanças de tela, por exemplo. Toda Activity implementa obrigatoriamente o método onCreate(bundle), responsável por inicializar os elementos necessários para que a tela seja exibida para o usuário. Para isso, o método setContentView(view) é chamado especificando-se a view que contém os elementos da tela. Além disso, toda Activity deve ser declarada no arquivo AndroidManifest.xml da seguinte forma: <activity Android:name:”.MinhaActivity” /> Esse “.” antes do nome da sua Activity indica que ela está no mesmo pacote do projeto, caso ela estivesse em um pacote diferente, o nome do pacote deveria ser especificado. Lembre-se de escrever o nome da Activity corretamente, pois o compilador é case sensitive, ou seja, ele diferencia as letras maiúsculas das minúsculas, dessa forma para ele “MinhaActivity” é diferente de “minhaActivity”. Para ter certeza de que o nome e o pacote foram especificados corretamente, segure a tecla control do seu teclado e passe o mouse em cima do nome da sua Activity, se o texto ficar “clicável” indica que você pode chegar até a sua Activity apenas clicando, pois ela foi encontrada no caminho especificado. Bom, dito isso, lembre-se de que quando você desejar criar uma nova tela na sua aplicação Android você precisará criar também uma nova Activity e esta necessariamente deverá ser declarada no AndroidManifest.xml. Ela vai controlar os eventos e elementos da tela, que é Competência 01 9 especificada no método setContentView(view), que já vimos anteriormente, este método recebe como parâmetro uma referência para um arquivo XML que contém os elementos da sua interface. 1.2 Ciclo de vida de uma Activity É bastante importante você entender o ciclo de vida de uma Activity para saber em qual estado ela se encontra e para você poder controlar o comportamento da sua aplicação. Tenha em mente o seguinte: quem cuida da execução do fluxo do ciclo de vida é o sistema operacional Android, mas você pode customizar os estados (executando, temporariamente interrompida em segundo plano e completamente destruída), por exemplo. Vamos ver um exemplo prático da utilização e da importância do conhecimento e do uso desses estados. Imagine que você tenha desenvolvido um jogo espetacular para Android e enquanto o usuário está jogando ele recebe uma ligação, o que vai acontecer com o jogo? Bom, o sistema operacional vai interromper o jogo e colocá-lo em segundo plano para que o usuário possa atender a ligação. Ao encerrar a ligação a grande pergunta que resta é: o que irá acontecer com o jogo? O jogo vai estar pausado? O jogo foi salvo? Bom, isso vai depender do que foi especificado por você, desenvolvedor. O Android fornece toda a infraestrutura necessária para isso, basta você entender o ciclo de vida da Activity. Competência 01 10 A figura abaixo (figura 1) ilustra o fluxo do ciclo de vida de uma Activity e seus possíveis estados. Figura 1 - Ciclo de vida de uma activity Fonte: O próprio autor. Descrição: A figura mostra todas as fases do ciclo de vida de uma aplicação Android. Quando uma activity é iniciada o seu ciclo de vida tem início e o método onCreate é executado, em seguida é executado o onStart e o onResume. Caso outra activity seja iniciada, a atual é pausada, então, é executado o método onPause. Se a activity anterior voltar a executar, ela chamará novamente o onResume, caso contrário, é chamado o método onStop e em seguida pode ser chamado o onDestroy, que encerra a activity ou pode ser chamado o onRestart , se a activity voltar a executar ou caso ela tenha ido para segundo plano no onStop e for encerrada pelo SO. No caso dela voltar a ser exibida, o método onCreate é chamado novamente. Preste bastante atenção, pois agora iremos explicar cada um dos métodos que se encontram no ciclo de vida de uma activity. É importante que você leia a descrição do método e vá acompanhando o fluxo na figura 1. Competência 01 11 onCreate(bundle) É um método obrigatório, por isso deve estar presente em toda activity e é executado apenas uma vez. Ele é responsável por criar a activity e chamar o método setContentView(view) que faz a associação entre a activity e um arquivo de interface específico (XML) que contém os elementos da tela que serão exibidos para o usuário. Logo após a execução do onCreate(bundle) é chamado o método onStart(). onStart() Esse método é chamado após a activity ser criada, bem como a sua view, ou seja, após o método onCreate(bundle). Sua view está prestes a ficar visível. Como mostrado no fluxo acima, esse método também é chamado sempre após o onRestart(). onRestart() Esse método é chamado caso sua activity tenha sido parada temporariamente e esteja sendo iniciada novamente, então o Android chama o onRestart() que logo em seguida chama o onStart(). onResume() Esse método é chamado quando a activity já está executando e está pronta pra interagir com o usuário. onPause() Caso o celular entre em modo de espera, hiberne, receba uma ligação ou a aplicação seja colocada em background o método onPause() é chamado. Dessa forma, o desenvolvedor pode salvar algum estado ou informação que está sendo usada pela aplicação. onStop() É chamado quando a activity está sendo encerrada e já não está mais visível para o usuário. Isso pode ocorrer quando a aplicação muda de uma activity pra outra, num comportamento de transição de telas. onDestroy() Encerra a execução de uma activity. O sistema operacional libera os recursos alocados pela activity como valores de atributos e demais recursos. Tabela 1 - Ciclo de vida de uma aplicação Android Fonte: o autor Descrição: Tabela informando os métodos do ciclo de vida de uma Activity, bem como a sua descrição de quando ocorre. A seguir mostrarei um exemplo do código de uma activity que implementa os métodos: onCreate(bundle), onStart(), onRestart() e onResume() do ciclo de vida que mencionamos anteriormente. Recomendo seguir o exemplo e implementar todos os métodos. Dessa forma, você pode fazer seus próprios testes: colocar a aplicação em background, ligar para o seu celular, encerrar a aplicação e ir vendo os métodos que são chamados através das mensagens de log que serão exibidas na janela do LogCat. Para isso, você pode criar um projeto Android simples e executá-lo usando o emulador do Android ou o seu próprio celular. Competência 01 12 public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.i(getLocalClassName(), "onCreate()"); TextView olaMundo = new TextView(this); olaMundo.setText("Olá mundo! :)"); setContentView(olaMundo); } @Override protected void onStart(){ super.onStart(); Log.i(getLocalClassName(), "onStart()"); } @Override protected void onRestart(){ super.onRestart(); Log.i(getLocalClassName(), "onRestart()"); } @Override protected void onResume(){ super.onResume();Log.i(getLocalClassName(), "onResume()"); } } Competência 01 13 Quando eu executo a aplicação, meu LogCat mostra o seguinte: Figura 2 - Impressão de logs no LogCat Fonte: O autor. Descrição: Está sendo mostrado um printscreen das informações exibidas no LogCat mostrando quais métodos foram chamados a partir da exibição de uma Activity. No caso, está sendo exibido um print escrito onCreate(), onStart() e onResume(). Note que é exibido o nome da activity (getLocalClassName()) e a mensagem que foi especificada no segundo parâmetro, no caso o nome do método que está sendo chamado. O trecho mais importante é o final, no caso: …MainActivity: onCreate() …MainActivity: onStart() ...MainActivity: onResume() Quando se coloca em background, apertando o botão da casinha (home) do Android e depois a se coloca em evidência novamente, é mostrado o seguinte: ...MainActivity: onRestart() ...MainActivity: onStart() ...onResume() Note que o onCreate(bundle), como havíamos falado anteriormente, é chamado apenas uma vez. No meu exemplo não inclui os métodos onPause(), onStop() e onDestroy(), coloque-os no seu exemplo e me diga quais métodos foram chamados quando você clicou no botão home (símbolo da casinha) e quando você encerrou a aplicação. Perceba que você apenas implementou os métodos e não está chamando eles em lugar algum. Quem faz essa chamada é o próprio sistema operacional Android. Entender o ciclo de vida de uma activity é fundamental para você dominar o desenvolvimento de aplicações Android. O conhecimento e domínio desses métodos são bastante importantes principalmente para o desenvolvimento de jogos. Imagine que você está jogando e recebe uma ligação ou a bateria acaba e o jogo não foi salvo e você tem apenas uma vida ou está Competência 01 14 com o progresso bastante avançado, então o ideal seria que o jogo fosse salvo ao ser interrompido ou mesmo pausado para que o usuário não seja prejudicado com interrupções externas e que fogem do controle do usuário, mas não do desenvolvedor. 1.3 Navegação entre activities Até agora vimos alguns conceitos do que é uma activity e para que ela é utilizada bem como o seu ciclo de vida. Agora vamos criar outras activities e aprender como navegar de uma para outra, tendo em mente que cada activity representa uma tela e a maioria dos aplicativos que utilizamos possui um conjunto de telas diferentes, então para cada tela será criada uma nova activity. Para navegar entre activities (mudar de tela) você pode utilizar dois métodos diferentes: ou você utiliza o startActivity(intent) ou o startActivityForResult(intent, codigo). Ambos utilizam uma instância da classe Intent. Intent significa intenção, no nosso caso a nossa intenção é mudar de activity, ou seja, navegar de uma tela para outra. Veremos com detalhes essa classe Intent no nosso material. O método startActivity simplesmente faz a mudança de uma tela para outra sem deixar nenhum vínculo com a tela anterior, já o startActivityForResult passa um código como parâmetro para que a segunda Activity saiba de onde veio a informação e possa retornar para esta uma outra informação. Esse segundo método é usado quando a primeira tela precisa de um parâmetro da segunda. Dessa forma, quando a segunda tela é encerrada, ela passa a informação para a tela que a chamou. 1.3.1 Navegação simples de uma activity para outra O código a seguir mostra como a partir de um clique de botão é possível abrir uma nova tela (o botão ocupa a tela toda, mas não se preocupe com isso agora). Note que para isso você precisa de uma segunda activity. Já que estamos navegando de uma tela para outra serão necessárias duas activities para o exemplo. A primeira activity vamos chamar de MainActivity e a segunda de SegundaTela. Competência 01 15 Exemplo MainActivity public class MainActivity extends Activity implements View.OnClickListener { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Button olaMundo = new Button(this); olaMundo.setText("Olá mundo! :)"); olaMundo.setOnClickListener(this); setContentView(olaMundo); } public void onClick(View v) { Intent tela2 = new Intent(this, SegundaTela.class); startActivity(tela2); } } Exemplo SegundaTela public class SegundaTela extends Activity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); TextView tela2 = new TextView(this); tela2.setText("Bem vindo a SegundaTela."); setContentView(tela2); } } Se você tiver essas duas activities criadas você vai conseguir rodar? Depende... Você se lembrou de declarar essa sua nova activity no AndroidManifest.xml? Lembre-se de que toda nova Competência 01 16 activity(tela) deve ser declarada no AndroidManisfest, caso você não faça isso o seu LogCat vai exibir a seguinte mensagem de erro quando você clicar no botão na tentativa de mudar de tela: FATAL EXCEPTION Unable to find explicit activity class SegundaTela have you declared this activity in your AndroidManifest.xml? Perceba que ele exibe uma mensagem em inglês informando o porquê do erro, traduzindo: “você declarou essa activity no seu AndroidManifest.xml?”. Para que isso não ocorra adicione a seguinte linha no seu AndroidManifest.xml: <activityAndroid:name=".SegundaTela" /> O que acontece com a primeira activity após a mudança para a segunda tela? Veja o que foi impresso no LogCat a partir da implementação e impressão de log nos métodos do ciclo de vida que aprendemos anteriormente. Implemente os métodos do ciclo de vida tanto para a primeira tela quanto para a segunda e entenda o que acontece em ambas. 1.3.2 Navegação entre telas com passagem de parâmetros Agora já sabemos como navegar de uma tela para outra, mas como enviar uma ou mais informações da primeira tela para a segunda? Para isso, usaremos uma classe chamada Bundle que é similar a uma HashTable (estrutura de dados do tipo chave valor). Ela faz uso do método putString(chave, valor) para configurar as informações que serão passadas em formato de texto para a próxima tela. Agora faremos uma pequena modificação no exemplo anterior para ilustrar a passagem de informações entre as telas (o código a seguir faz parte do conteúdo da classe MainActivity). public void onClick(View v) { Intent tela2 = new Intent(this, SegundaTela.class); Bundle informacoes = new Bundle(); informacoes.putString("cargo","Professor"); informacoes.putString("nome","Gilson"); tela2.putExtras(informacoes); startActivity(tela2); } Competência 01 17 No nosso exemplo utilizamos o método putString, mas a classe Bundle possui outras opções caso você queira passar outro tipo primitivo como putBoolean, putChar, punInt, dentre outras. Para obter a lista completa basta consultar o javadoc. Já sabemos como passar as informações, agora precisamos saber como resgatá-las na outra tela. Novamente vamos alterar o código que havíamos criado (o código a seguir faz parte do conteúdo da classe SegundaTela). protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); TextView tela2 = new TextView(this); Intent it = getIntent(); String cargo = "", nome = ""; if(it != null){ Bundle informacoes = it.getExtras(); if(informacoes != null){cargo = informacoes.getString("cargo"); nome = informacoes.getString("nome"); } } tela2.setText("Bem vindo " + cargo + " " + nome); setContentView(tela2); } Note que no onClick do botão da primeira tela (MainActivity) nós passamos o Intent (chamado tela2) com as informações que desejamos transferir. Como o parâmetro do startActivity e no onCreate da segunda tela (SegundaTela), nós resgatamos esse mesmo Intent (tela2) e extraímos as informações que foram passadas através da chave “cargo” e “nome”, basicamente, foi isso que fizemos. Em toda linguagem de programação existem diferentes formas de se fazer a mesma coisa, vai depender do seu conhecimento e da flexibilidade da mesma. Também poderíamos passar as informações da seguinte forma: Competência 01 18 public void onClick(View v) { Intent tela2 = new Intent(this, SegundaTela.class); tela2.putExtra("cargo", "Professor"); tela2.putExtra("nome","Gilson"); startActivity(tela2); } Veja que no exemplo acima nós omitimos a utilização Bundle e colocamos os parâmetros diretamente no Intent. Da mesma maneira, para recuperar essas informações na próxima tela, podemos novamente omitir a utilização da classe Bundle e fazer o seguinte: cargo = it.getStringExtra("cargo"); nome = it.getStringExtra("nome"); 1.4 ListActivity – uma activity diferente A classe Activity é uma classe básica e simples que permite uma alta customização, contudo existem outros tipos de Activities que são um pouco mais complexas, pois já apresentam alguns comportamentos implícitos, como é o caso da classe ListActivity. Como o próprio nome já diz é uma Activity utilizada para exibir uma lista de itens na vertical. Esse tipo de activity já apresenta internamente um componente do tipo ListView, responsável por desenhar uma lista vertical com uma barra de rolagem, se necessário. Além da presença desse componente, o método setContentView(view) é chamado automaticamente pela ListActivity, dessa forma o programador não precisa se preocupar com a view que será mostrada e sim com os elementos que irão preencher a lista. Agora como fazemos para criar essa lista de elementos? Bom, para isso será necessário criar um objeto que implemente a classe ListAdapter que faz a ligação entre o componente (ListView) e os valores que você deseja exibir na sua lista. É importante que você entenda que você poderia criar uma Activity e adicionar um ListView, ou você poderia usar diretamente uma ListActivity. Criando uma ListActivity você não precisa interagir diretamente com o ListView. A ListActivity proporciona ao programador novos métodos com o objetivo de facilitar tanto a criação quanto a manipulação da lista. Ai você pergunta: “Professor, eu preciso conhecer todos os tipos de activity?”, a minha resposta é “Não!”. O meu objetivo é mostrar que existem outros tipos de Activity e com o passar do tempo e à medida em Competência 01 19 que você for adquirindo experiência vai acabar conhecendo outras classes de Activity. O objetivo dessas outras classes é justamente facilitar a manipulação e a utilização dos componentes do Android. Agora, vamos colocar a mão na massa, vamos criar uma classe que estende de ListActivity, preencher um array (conjunto) de objetos e exibir na tela, conforme demonstrado a seguir: public class MainActivity extends ListActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); String[] lista = new String[]{"Item 01", "Item 02"}; ArrayAdapter<String> arrayAdapter = new ArrayAdapter<String> (this, Android.R.layout.simple_list_item_1, lista); setListAdapter(arrayAdapter); } @Override protected void onListItemClick (ListView, View, int position, long id){ super.onListItemClick (listView, view, position, id); String itemSelecionado = this.getListAdapter().getItem(position).toString(); Toast.makeText(this, "Item selecionado -> " + itemSelecionado, Toast.LENGTH_LONG).show(); } } O método onListItemClick é um método da ListActivity utilizado para facilitar a manipulação do ListView. Sempre que o usuário clicar em um elemento da lista esse método é chamado automaticamente permitindo ao programador identificar qual objeto foi selecionado. No exemplo acima, sempre que o usuário clicar em um item da lista nós exibimos um alerta através do Competência 01 20 método show()da classe Toast com a mensagem “Item selecionado -> Item 01”, por exemplo. Caso essa lista funcionasse como um menu, nós poderíamos identificar qual elemento foi clicado e ter uma ação associada a cada item ou poderia ser usada apenas como uma lista de dados informativa. Atenção para o parâmetro Android.R.layout.simple_list_item_1, ele representa um layout de lista padrão predefinido pelo Android. Os layouts predefinidos ajudam bastante quando se quer utilizar um layout simples, contudo para layouts mais complexos e personalizados é necessário que o próprio desenvolvedor crie de acordo com a sua necessidade. No nosso último exemplo nós criamos uma ListActivity com dois itens: “Item 01” e “Item 02”, já que foi dada a ideia de criar um menu com o ListView da ListActivity. Vamos lá!? Já temos uma lista com dois itens e já implementamos o método onListItemClick, a tarefa é a seguinte: se o usuário clicar no “Item 01” nós vamos iniciar nova activity chamada CicloDeVidaActivity que vai conter o nosso primeiro exemplo desse capítulo. Será uma activity simples com todos os métodos do ciclo de vida implementados. Já se o usuário clicar no “Item 02” nós vamos chamar a activity ItemClicadoActivity que recebe a informação do item clicado. Já que não vamos criar nenhum item novo, então eu não preciso mexer no método onCreate, eu só vou mexer no método onListItemClick, porque a única coisa que eu vou fazer é ter uma ação diferente dependendo do item que for clicado, ok? Então, o método seria modificado da seguinte forma: @Override protected void onListItemClick (ListView, View, int position, long id){ switch (position){ case 0: startActivity(new Intent(this, CicloDeVidaActivity.class)); break; case 1: Intent = new Intent(this, ItemClicadoActivity.class); intent.putExtra("itemClicado", this.getListAdapter().getItem(position).toString()); startActivity(intent); break; }} Competência 01 21 Perceba que para identificar qual item foi clicado eu usei o parâmetro “position”, esse parâmetro informa a posição do item clicado. O primeiro item é representado pela posição de índice 0, o segundo item é representado pela posição de índice 1 e assim por diante. No próximo capítulo abordaremos o conceito de Intent e veremos mais exemplos da sua utilização, pois essa talvez seja a classe mais importante do Android. Lembre-se de que ela já foi citada brevemente neste capítulo. Quando precisamos navegar de uma tela para outra, nós criamos um Intent e passamos a tela para qual desejamos navegar como parâmetro e chamamos o método startActivity(Intent). Competência 02 22 2.Competência 02 | Intent Neste capítulo aprenderemos mais sobre a classe Intent, que para muitos é o coração do Android. Intent significa intenção, representa uma ação que a aplicação deseja executar. No capítulo anterior, a intenção que tínhamos era a de mudar de umatela para outra, mas poderíamos ter a intenção de abrir o browser do celular, fazer uma ligação, abrir o GOOGLE PLAY para instalar um aplicativo, enviar uma mensagem para o SO ou mesmo exibir um endereço ou rota no GOOGLE MAPS. Agora, aprenderemos diversas utilidades da classe Intent, por isso fique atento e se tiver mais curiosidade busque mais informações na internet sobre as diversas formas de se utilizar um Intent. Vamos aprender algumas delas. 2.1 Abrindo o browser e acessando um site específico O Android já possui diversas ações padrões que podem ser requisitas pelo desenvolvedor a qualquer momento. Dentre elas está a abertura de uma página web. Então, o programador dirá para o Android: “Você pode abrir essa página para mim?”. E ele, como já possui essa tarefa mapeada pelo sistema operacional dirá: “Sim, você que manda!”. Vamos ver um exemplo a seguir de como através do clique de um botão podemos abrir o buscador do Google: public class MainActivity extends Activity implements View.OnClickListener { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Button abrirBrowser = new Button(this); abrirBrowser.setText("Abrir o google.com"); setContentView(abrirBrowser); abrirBrowser.setOnClickListener(this); } Competência 02 23 @Override public void onClick(View v) { Uri endereco = Uri.parse("http://www.google.com"); Intent it = new Intent(Intent.ACTION_VIEW, endereco); startActivity(it); } } No código acima nós temos uma Activity chamada MainActivity que implementa a interface View.OnClickListener. No método onCreate da Activity nós criamos um botão chamado abrir Browser com o texto “Abrir o google.com” e, ao clicá-lo, nós chamamos o método onClick da interface View.OnClickListener que foi sobrescrito pela nossa activity. Nesse método nós instanciamos um objeto da classe URI onde especificamos o endereço web que desejamos abrir, então criamos um Intent para sinalizar a intenção de abrir essa página (http://www.google.com), por isso passamos o URI com essa informação como parâmetro do Intent e logo em seguida chamamos o startActivity para executar o nosso Intent. No momento em que o startActivity é chamado, o seu aplicativo envia uma mensagem para o SO Android para abrir o seu browser padrão. Note que não há uma diferença na utilização do Intent para uma ação local da sua aplicação e uma ação do próprio sistema operacional Android, visto que tanto para mudar de tela quanto para abrir o browser é chamado o método startActivity(Intent). No exemplo anterior nós criamos um botão e, ao clicá-lo, nós abrimos o browser e acessamos o endereço especificado no URI adicionado ao Intent. Agora vamos fazer um exemplo um pouco mais incrementado. Vamos criar um xml de layout, vamos colocar um label, um campo de texto para o usuário digitar um site e um botão em que, com um clique, nós abriremos o browser e o endereço especificado. Primeiro vamos criar o xml de layout: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android" Android:layout_width="match_parent" Android:layout_height="match_parent" Android:orientation="vertical"> Competência 02 24 <TextView Android:layout_width="match_parent" Android:layout_height="wrap_content" Android:text="Digite a URL" /> <EditText Android:id="@+id/campoTextoEnderecoWeb" Android:layout_width="match_parent" Android:layout_height="wrap_content" /> <Button Android:id="@+id/botaoCliqueAqui" Android:layout_width="wrap_content" Android:layout_height="wrap_content" Android:text="Clique aqui!" /> </LinearLayout> Em seguida, criamos a activity que estará associada a esse xml de layout: public class MainActivity extends Activity implements View.OnClickListener { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button botaoCliqueAqui = (Button) findViewById(R.id.botaoCliqueAqui); botaoCliqueAqui.setOnClickListener(this); } public void onClick(View view){ EditText campoTextoEnderecoWeb = (EditText) findViewById(R.id.campoTextoEnderecoWeb); String enderecoWeb = campoTextoEnderecoWeb.getText().toString(); Competência 02 25 Uri = Uri.parse(enderecoWeb); Intent it = new Intent(Intent.ACTION_VIEW, uri); startActivity(it); } } Até ai nenhuma novidade na parte da activity. Ao iniciá-la, o método onCreate é chamado, especificamos a view que será mostrada através da chamada do método setContentView. Depois, pegamos o botão através do seu id (R.id.botaoCliqueAqui) que foi especificado no XML e associamos a ele o evento do clique e dizemos que esse evento foi implementado nessa activity (this). O clique do botão contém o código que havíamos visto anteriormente, a diferença é que o endereço web que antes era estático agora é dinâmico e é passado pelo EditText que está no layout. Na hora de testar não se esqueça de digitar o endereço completo, por exemplo: www.google.com, não esquecer do http://. 2.2 Fazendo uma ligação para um número de telefone Agora vamos aprender como fazer uma ligação usando a classe Intent. Na sessão anterior, para abrirmos o browser, usamos a ação Intent.ACTION_VIEW e informamos o URI com o endereço web desejado. De forma similar, para fazer uma ligação, o Intent precisa ter a ação Intent.ACTION_CALL mais o número do telefone para o qual desejamos ligar. Existem aplicações que dão a opção ao usuário de fazer uma ligação pra uma central de atendimento caso ele tenha algum problema na sua utilização. Por exemplo, imagine que você está desenvolvimento uma aplicação que permite locar um carro de uma estação de origem para entregá-lo numa estação de destino. Esse carro é movido à eletricidade e não à gasolina ou álcool como os veículos comuns. No meio do seu percurso, a bateria do carro acaba ou você se envolve em algum acidente. Assim, é importante que a aplicação disponibilize um número de emergência para o qual o usuário poderá ligar. Esse número pode ser informado de modo que o usuário saia da aplicação e digite para fazer a ligação ou clique em um botão e através desse clique a aplicação envie uma ordem para o sistema operacional para efetuar a ligação. Vamos nos ater a essa última opção. Competência 02 26 Então, como faríamos para fazer uma ligação a partir do clique de um botão na nossa aplicação? Vamos ver um exemplo de um XML de layout que contém um texto explicativo e um botão que, ao clicá-lo, a ação será ligar para um número de emergência. <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android" Android:layout_width="match_parent" Android:layout_height="match_parent" Android:orientation="vertical"> <TextView Android:layout_width="match_parent" Android:layout_height="wrap_content" Android:layout_margin="20dp" Android:text="Caso você esteja tendo algum problema com a aplicação ligue para emergência."/> <Button Android:layout_width="wrap_content" Android:layout_height="wrap_content" Android:layout_margin="20dp" Android:text="Ligar para Emergência" Android:onClick="acaoLigarParaEmergencia"/> </LinearLayout> Perceba que o elemento “Button” possui um atributo chamado Android:onClicke como parâmetro desse elemento especificamos o nome do método presente na sua activity. Essa forma de especificar e implementar a ação do botão é uma forma diferente da anterior que nós havíamos visto, você se lembra? Antes, para associar uma ação ao clique do botão, nós colocamos um id no XML do layout (Android:id="@+id/botaoCliqueAqui") do botão e na activity nós pegamos esse botão pelo id (Button botaoCliqueAqui = (Button) findViewById(R.id.botaoCliqueAqui)) e associamos a ele a sua respectiva ação (botaoCliqueAqui.setOnClickListener(this)). Agora, nós fizemos diferente, associamos a ação diretamente no XML de layout. Tenha em mente essas duas formas de Competência 02 27 especificação da ação do botão, será importante você saber para poder dar manutenção num sistema já existente ou para poder implementar sua própria aplicação. Agora vamos ver como fica a activity! public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } public void acaoLigarParaEmergencia(View v) { Uri telefone = Uri.parse("tel:988998899"); Intent it = new Intent(Intent.ACTION_CALL, telefone); if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) { return; } startActivity(it); } } Antes de executar o código acima, você precisa abrir o arquivo AndroidManifest.xml e adicionar uma permissão informando que a sua aplicação pode precisar fazer uma ligação. Então, adicione a seguinte linha no seu AndroidManifest: <uses-permission Android:name="Android.permission.CALL_PHONE" /> Caso você não coloque essa linha, a chamada ao método startActivity(it) acusará o erro de permissão e você não poderá executar o código. Observação: Existe uma ação parecida com a Intent.ACTION_CALL que é a Intent.ACTION_DIAL, que ao invés de discar e fazer a ligação, apenas disca o número desejado, mas espera o usuário fazer a confirmação para efetuar a ligação. Faça o teste você mesmo, substitua e veja o que acontece. Competência 02 28 2.3 Solicitando ao google maps que exiba um local específico do mapa A classe Intent também pode ser usada para fazer com que o SO abra um aplicativo de mapa como, por exemplo, o Google Maps e mostre uma determinada localização geográfica através do seguinte código: public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Uri uriGeografico = Uri.parse("geo:0,0?q=Cidade+Universitária,Recife"); Intent it = new Intent(Intent.ACTION_VIEW, uriGeografico); startActivity(it); } } Perceba que nesse exemplo não será necessário o usuário fazer nenhuma ação, como clicar no botão, basta ele entrar nessa activity para ela chamar outra activity mostrando a localização especificada. Nesse exemplo nós estamos especificando um endereço, mas poderia ser uma coordenada geográfica (latitude e longitude), nesse caso o objeto uriGeografico ficaria da seguinte forma: // Coordenadas do Palácio do Planalto, Brasília Uri uriGeo = Uri.parse("geo:-15.7996165,-47.8591871"); Você pode colocar o seu endereço ou a sua coordenada e ver o Android localizá-la no mapa, faça o teste! Além disso, você também pode exibir uma rota de um ponto de partida até um destino específico, basta você determinar as coordenadas de origem e de destino em um serviço do google maps, atribuir ao Uri e associá-lo ao Intent. Você pode pesquisar por esse exemplo na internet e fazer o teste. Competência 02 29 2.4 Acessando contatos da agenda A classe Intent também pode ser usada pela aplicação para acessar a lista de contatos do seu usuário. Para isso, a ação que utilizada é uma conhecida nossa, a Intent.ACTION_VIEW, contudo o outro parâmetro é bem diferente. Para identificar o contato desejado é utilizado o seu ID, por exemplo: “content://com.Android.contacts/contacts/ID”, onde esse ID varia para cada contato da sua agenda. A seguir vamos ver um exemplo de como fazer com que nossa aplicação busque por um contato específico no momento em que o usuário clica em um botão. Nesse momento você já deve saber como adicionar um botão na tela e como associar a ele seu respectivo método de onClick. Você pode fazer isso através do XML ou criar um botão dinamicamente no onCreate da activity. Aqui eu mostrarei apenas o conteúdo de como ficará o evento de clique do botão, ok? Uri primeiroContato = Uri.parse("content://com.Android.contacts/contacts/1"); Intent it = new Intent(Intent.ACTION_VIEW, primeiroContato); startActivity(it); Assim como para fazer uma ligação, para você poder acessar a agenda do celular do seu usuário, no momento da instalação, é necessário que o seu APP solicite a permissão READ_CONTACTS, então você pode precisar adicionar a seguinte linha no seu AndroidManifest.xml: <uses-permissionAndroid:name="Android.permission.READ_CONTACTS"/> ATENÇÃO! Se você rodar o exemplo acima no emulador pode ser que não tenha contato cadastrado e você pode se deparar com a seguinte mensagem: “Invalid contact uir.”. Então, pra exercitar, eu recomendo você executar o exemplo anterior no seu próprio celular, caso você tenha um dispositivo Android. Competência 02 30 Caso você não saiba o ID do usuário e queira visualizar toda a lista de contatos cadastrados e deixar o usuário livre para escolher, basta você usar o mesmo Uri que usamos anteriormente omitindo apenas o ID do contato e mudar a ação para Intent.ACTION_PICK. Assim, o código do onClick modificado ficaria da seguinte forma: Uri listaDeContatos = Uri.parse("content://com.Android.contacts/contacts/"); Intent it = new Intent(Intent.ACTION_PICK, listaDeContatos); startActivity(it); Após a execução do método startActivity é enviada uma mensagem para o sistema operacional e é aberta a lista de contatos do dono do dispositivo. Contudo, no momento em que você clica em um contato qualquer a agenda fecha e retorna para activity anterior. Esse exemplo não é muito útil, pois o método startActivity tem a função apenas de abrir uma nova activity, então, quando queremos além de abrir um nova activity receber alguma informação que vem dela, utilizamos o método starctActivityForResult(intent, código). 2.5 Retornando resultados de uma activity para outra através do método startActivityForResult Existem duas formas de mudar de uma activity para outra. A que nós vemos constantemente faz apenas a mudança de activities através da chamada do método startActivity(intent). A outra forma é através da chamada do método startActivityForResult(intent, codigo) que é utilizada quando se quer recuperar alguma informação da tela que foi chamada na tela que a chamou. Vou explicar melhor, preste atenção! O método startActivityForResult(intent, código) recebe 2 parâmetros. O primeiro é o intent, ou seja, é a intenção de abrir uma nova activity e o segundo é um código, que é um valor usado para identificar a activity que será iniciada, esse código é chamado de requestCode no Android. Esse mesmo código será enviado de volta quando a activity aberta for finalizada juntamente com o resultado que se deseja recuperar. Competência 02 31 Vamos ver um exemplo prático. Através de um clique no botão, vamos abrira lista de contatos da agenda, como aprendemos anteriormente, e vamos retornar as informações do contato escolhido. Antes, quando clicávamos no contato, a activity se fechava e não fazíamos mais nada com a informação do contato escolhido, na verdade nem a tínhamos ainda, essa informação ficava perdida. Agora, chamando o método startActivityForResult no clique, nós podemos recuperar essa informação quando a activity contendo a lista de contatos for fechada, veja o exemplo a seguir. public class MainActivity extends Activity implements View.OnClickListener { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Button b = new Button(this); b.setText("Abrir Agenda Telefonica"); b.setOnClickListener(this); setContentView(b); } @Override public void onClick(View v) { Uri listaDeContatos = Uri.parse("content://com.Android.contacts/contacts/"); Intent it = new Intent(Intent.ACTION_PICK, listaDeContatos); startActivityForResult(it, 10); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if(requestCode == 10) { Uri = data.getData(); Cursor = getContentResolver().query(uri, null, null, null, null); cursor.moveToFirst(); int nameColumnIndex = Competência 02 32 cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME) ; String name = cursor.getString(nameColumnIndex); Toast.makeText(this, "Contato: " + name, Toast.LENGTH_SHORT).show(); } } } } } Perceba que no nosso exemplo temos três métodos dos quais dois você já conhece e está bem familiarizado, que são os métodos onCreate, método obrigatório da classe activity que é chamado sempre que a activity é criada e o método onClick, que é associado ao clique do botão através do código b.setOnClickListener(this);. Note que existe um método novo chamado onActivityResult que é o método que é chamado assim que a activity que foi iniciada no startActivityForResult é encerrada. O código, chamado requestCode, que passamos na chamada, é retornado no onActivityResult para identificar qual activity foi encerrada, por isso a checagem no if(requestCode == 10). Dessa forma, é feito o tratamento correto com a informação esperada. Caso essa nossa activity não tivesse apenas um botão e fosse possível iniciar mais de uma activity, essa verificação do if(requestCode == 10), faria mais sentido. O importante é que você perceba que você enviou um código identificador e que esse código foi retornado, possibilitando o programador saber de onde vem à informação desejada. A classe Toast.makeText foi utilizada somente para exibir a mensagem com o nome do usuário. Você também poderia exibir o número do contato ou qualquer outra informação retornada no Intent. Se você for pesquisar vai ver que os métodos startActivity e startActivityForResult são bem parecidos, então quando usar um ou outro? Se você quiser apenas mudar de uma tela para outra sem se importar com o retorno use o starActivity, caso contrário use o startActivityForResult e na activity que você chamou este método implemente o método onActivityResult. Esses exemplos são bem simples e didáticos, você pode fazer seus próprios exemplos e procurar exercícios e matérias complementares na internet. Competência 02 33 2.6 Intent – Resumo No decorrer desse capítulo vimos vários possíveis usos para a classe Intent. Ela pode ser usada tanto para iniciar uma activity que você criou dentro da sua aplicação quanto para chamar uma activity nativa do Android ou mesmo de outra aplicação e é isso que torna essa classe tão interessante e especial. Essa característica de poder se comunicar com outra aplicação é o ponto chave que diferencia a classe Intent das demais classes Android. Devido a essa característica pode-se ter inúmeras aplicabilidades, vai depender da utilidade e objetivo da sua aplicação. Imagine que uma aplicação rode em background e devido a algum evento o usuário precisa ser notificado urgentemente com um pop up ou uma mensagem de alerta. A aplicação pode detectar esse evento, mesmo rodando em background, e sinalizar ao usuário a sua ocorrência. Vamos a outro exemplo. Imagine que uma aplicação envia uma mensagem para o celular com a intenção de autenticar o usuário da aplicação. A aplicação pode interceptar a mensagem enviada para o dispositivo e já pegar o código de autenticação na mensagem. Isso acontece bastante em aplicação de e-mail, que envia uma mensagem com código para o usuário para ele pegar aquele número e se autenticar. Caso a aplicação seja móvel, ela pode interceptar a mensagem e já passar para o próximo passo. Outro exemplo clássico é a leitura do código de barras do celular. Você pode fazer com que a sua aplicação faça uso do recurso da câmera digital do dispositivo para fazer uma leitura do código de barras e fazer um pagamento ou ler um QRCode (Quick Response, é um código de barras bidimensional que pode ser facilmente lido pela câmera da maioria dos dispositivos móveis), isso é bem comum em aplicações de bancos. Ou ainda permitir ao usuário tirar uma foto e enviar ou anexar na sua aplicação, como acontece no WhatsApp, por exemplo. Existem outras aplicabilidades da classe Intent, aqui nós vimos apenas algumas delas. No decorrer do nosso material continuaremos utilizando a classe Intent. No próximo capítulo, falaremos sobre interface gráfica e aprofundaremos mais alguns conceitos. Competência 03 34 3.Competência 03 | Conceitos de Interface Gráfica Neste capítulo aprenderemos mais sobre os componentes de layout, como usá-los e como organizá-los, apesar de já termos vistos alguns nos capítulos anteriores, como botões e blocos de textos. No Android existem diversos gerenciadores de layout que podem organizar os elementos verticalmente, horizontalmente ou mesmo posicionar em um local específico da tela (coordenadas x e y). Mostraremos vários exemplos e falaremos detalhadamente dos principais componentes. Vamos lá? 3.1 A classe View Vamos começar a falar da classe Android.view.View que é considerada a classe mãe dos componentes visuais do Android. Toda subclasse da classe View deve implementar o método onDraw(Canvas) cuja função é desenhar o componente na tela. No Android já existem várias classes que implementam a classe View, mas nada impede que você crie sua própria classe, estenda da classe View e implemente o seu próprio comportamento para o método onDraw. No Android nós podemos distinguir dois tipos de componentes: os widgets e os gerenciadores de layout. O primeiro herda diretamente da classe View e são elementos mais concisos como Button, TextView, Chronometer, ListView, ImageButton e ImageView, por exemplo. O segundo tipo herda de ViewGroup e são chamados popularmente apenas de layout. Nós vamos ver como usar widgets e como usar gerenciadores de layout e vamos ver a diferença entre os diferentes tipos de gerenciadores. Preste atenção, porque é bastante importante você saber como usá-los e como fica a dinâmica de organização dos elementos na tela com cada um dos tipos de layout. 3.2 ViewGroup e gerenciadores de layout Um gerenciador de layout, como o próprio nome já diz, é um componente visual utilizado para organizar a disposição dos seus componentes na tela. A seguir, vamos ver uma tabela com os principais tipos de ViewGroup, ou seja, diferentes classes do Android que herdam nativamente de ViewGroup eainda possuem comportamentos específicos e são bastante usadas. Competência 03 35 COMPONENTE DESCRIÇÃO FrameLayout É um componente utilizado quando se deseja preencher toda a tela do aparelho. LinearLayout É utilizado quando se deseja organizar os seus componentes internos de forma horizontal ou vertical. RelativeLayout Juntamente com o LinearLayout é um dos componentes mais utilizados. É usado quando se deseja posicionar um componente de forma relativa a outro. Por exemplo, o elemento “A” vai ficar abaixo do “B”, ou acima ou ao lado, ou seja, a localização de “A” vai depender da posição de “B”. AbsoluteLayout É uma espécie de contêiner onde a posição dos seus componentes é especificada através de coordenadas x e y. Tabela 2 - Tipos de ViewGroup Fonte: o autor Descrição: Tabela de tipos de ViewGroup com suas descrições e características. Existem outras classes que também herdam de ViewGroup como GridLayout e TableLayout, por exemplo, contudo nesse material vamos focar nesses quatro tipos principais. Até aqui fizemos poucos exemplos utilizando arquivos de layout em XML. Em muitos exemplos instanciamos os componentes dinamicamente e associamos a sua Activity correspondente, mas a partir desse ponto utilizaremos bastante os arquivos de layout escritos em XML, que é o mais comum de ser encontrado no mercado. 3.3 FrameLayout Vamos começar pela classe mais simples dos gerenciadores de layout para você entender melhor o seu conceito. Como vimos na tabelinha, anteriormente, o FrameLayout é um componente utilizado quando se deseja mostrar algo na tela toda, como uma imagem de fundo que pode ser uma marca d’água, por exemplo. A princípio, o elemento que você colocar em um FrameLayout irá ocupar a posição superior esquerda da tela e, dependendo do seu tamanho ou do que foi definido nos seus atributos, pode ocupar toda a tela. Ainda assim é possível inserir outros elementos na tela de forma que os elementos inseridos posteriormente fiquem por cima dos elementos anteriores, seguindo o conceito de pilha, onde o último elemento fica por cima dos inseridos primeiro. Então, imagine que você tem uma aplicação e deseja colocar no fundo uma imagem, você poderia usar um Competência 03 36 FrameLayout onde seu primeiro elemento seria a sua imagem e os demais elementos seriam os outros componentes da tela que seriam mostrados por cima da imagem, tornando a imagem um background da tela. Vamos agora ver na prática como funciona o FrameLayout! O exemplo a seguir é composto de um FrameLayout contendo um ImageView e vamos ver as variações possíveis dos atributos layout_widh e layout_height, que constituem a largura e a altura do FrameLayout, respectivamente. <?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:Android="http://schemas.Android.com/apk/res/Android" Android:layout_width="wrap_content" Android:layout_height="wrap_content" Android:background="#000000"> <ImageView Android:layout_width="wrap_content" Android:layout_height="wrap_content" Android:src="@drawable/Android_mini"/> </FrameLayout> O código acima tem como saída a figura 3: Figura 3 - Imagem do resultado da utilização do componente chamado FrameLayout Fonte: O próprio autor Descrição: Imagem sendo exibida no topo do lado esquerdo da tela com um fundo da tela do aplicativo cinza. Competência 03 37 Perceba que tanto no elemento FrameLayout quanto no ImageView suas propriedades layout_width e layout_height foram setadas como wrap_content. O que isso significa? Para o FrameLayout significa que a largura e a altura ocuparão somente o tamanho necessário para exibir o seu conteúdo interno, da mesma forma o ImageView ocupará apenas o tamanho necessário para exibir a imagem Android_mini. Observe que a imagem Android_mini é transparente e o fundo preto pertence ao FrameLayout. Com as propriedades de altura e largura setadas como wrap_content o espaço ocupado pelo FrameLayout será o mesmo espaço ocupado pelo ImageView. Caso você deseje que o seu FrameLayout ocupe toda a tela, basta mudar as propriedades de largura e altura de wrap_content para match_parent, dessa forma o componente irá ocupar todo o espaço designado ao pai (parent), ocupando assim a tela toda e não mais apenas o espaço ocupado por seus elementos internos. Veja o exemplo a seguir: <?xml version="1.0" encoding="utf-8"?> <FrameLayout xmlns:Android="http://schemas.Android.com/apk/res/Android" Android:layout_width="match_parent" Android:layout_height="match_parent" Android:background="#000000"> <ImageView Android:layout_width="wrap_content" Android:layout_height="wrap_content" Android:src="@drawable/Android_mini"/> </FrameLayout> Competência 03 38 Figura 4 - Exemplo da utilização do atributo de background Fonte: O próprio autor. Descrição: É o mesmo exemplo da imagem anterior, sendo adicionado o atributo chamado background. Dessa forma, a imagem continua sendo exibida no topo do lado esquerdo, contudo o fundo da tela do aplicativo está preto com o background sendo especificado através do valor em hexadecimal de #000000 que representa a cor preta. O mesmo raciocínio é válido para o ImageView. Se quando eu coloco o tamanho do FrameLayout para match_parent ele ocupa a tela toda, você imagina o que acontecerá se você trocar o wrap_content dos atributos da imagem para match_parent? Teste você mesmo e veja o que acontece! É recomendado que a largura e Aaltura do layout principal ocupem a tela inteira. Logo, as propriedades layout_width e layout_height devem ter os valores match_parent. Caso ache necessário, para se certificar de que isso está ocorrendo, mude a cor do background do componente para poder visualizá-lo. Do contrário ele será transparente e você poderá ficar na dúvida se ele realmente está ocupando toda a tela. Esses foram apenas alguns exemplos simples da utilização de um layout juntamente com a explicação das propriedades de largura e altura. Como havíamos falado anteriormente, o frame layout coloca os elementos internos empilhados devido a sua natureza de empilhar os elementos internos, o último elemento a ser inserido ficará por cima dos elementos anteriores. Então, no caso de você colocar outra ImageView abaixo da primeira com outra imagem, você perceberá que a primeira imagem pode não ser exibida ou ficar por trás da última. Faça o teste! Um FrameLayout pode ser usado para fazer uma aplicação definindo uma imagem de fundo, fazendo com que esta imagem fique por trás do conteúdo da aplicação ou ainda pode fazer uma tela e colocar como último elemento uma ProgressBar que, quando ativado, ficará por cima de Competência 03 39 todos os elementos do layout, bloqueando as interações do usuário, fazendo com que ele espere o processamento de um determinado processo, por exemplo. Antes de começar a desenvolver uma tela, imagine como ela ficará para, então, você poder selecionar o melhor layout de acordo com as suas necessidades. 3.4 O famoso LinearLayout O LinearLayout é o gerenciador de layout mais utilizado, pois possui um conceito bastante simples: o de organizar os seus componentes internos de forma sequencial na horizontal ou na vertical. Toda classe de layout deve conter os atributos layout_width e layout_height para especificar a largura e a altura do componente, respectivamente. Além desses atributos, o LinearLayout também possui o atributo orientation, onde é possível especificara orientação dos seus componentes internos. Os valores desse atributo podem ser horizontal ou vertical, o default, ou seja, se você não especificar o valor, os elementos serão exibidos horizontalmente. Veja o exemplo a seguir. <LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android" Android:layout_width="match_parent" Android:layout_height="match_parent"> <ImageView Android:layout_width="wrap_content" Android:layout_height="wrap_content" Android:src="@drawable/Android_mini"/> <ImageView Android:layout_width="wrap_content" Android:layout_height="wrap_content" Android:src="@drawable/Android_mini2"/> </LinearLayout> Competência 03 40 Figura 5 - Imagens representando o uso do componente de LinearLayout Fonte: O próprio autor. Descrição: Duas imagens sendo exibidas lado a lado. A primeira está no topo do lado esquerdo e a segunda está posicionada logo em seguida, ao lado direito da primeira. As imagens verdes estão inseridas num fundo branco. Esse exemplo é semelhante ao exemplo do FrameLayout. Mudei apenas o tipo do ViewGroup para LinearLayout, perceba que as imagens são exibidas uma ao lado da outra, ou seja, o LinearLayout ocupa a tela toda, porque sua largura e altura foi especificada como match_parent e os seus elementos internos são exibidos lado a lado, de forma sequencial, pois não foi especificado o atributo orientation que por padrão é horizontal. Caso você tivesse especificado explicitamente como vertical (Android:orientation="vertical"), o segundo ImageView seria mostrado abaixo do primeiro, faça o teste! Se você colocar mais componentes do que é possível exibir na tela, pode ser que esses componentes não apareçam, no nosso exemplo anterior as duas ImageView apareceram na tela, mas e se ao invés de duas fossem quatro, o que aconteceria? Bom, como sobrou um pouco de espaço entre a segunda imagem e a margem direita, a terceira imagem seria redimensionada para caber no espaço restante, contudo a quarta imagem não iria aparecer, pois não existe espaço suficiente no layout para ela, então você só veria três imagens. Para visualizar a quarta imagem você pode tentar colocar o seu dispositivo na horizontal, dessa forma a largura do layout irá aumentar e será possível visualizar a outra imagem. Veja como ficariam os dois cenários descritos na figura abaixo. Competência 03 41 Figura 6 - a) Representa os quatro elementos onde só três aparecem e o terceiro aparece redimensionado para caber na tela e a figura. b) Mostra as quatro imagens sendo exibidas com o telefone na horizontal. Fonte: O próprio autor. Descrição: Existem duas imagens, uma imagem foi chamada de A e a outra de B. A imagem A representa a visão do celular na vertical onde estão sendo exibidas três imagens. A primeira imagem encontra-se no topo, do lado esquerdo, e a segunda está no topo do lado direito da primeira e assim por diante. As duas primeiras imagens estão com os tamanhos originais, a terceira encontra-se com o tamanho reduzido para caber na tela e a quarta imagem não foi exibida. A imagem B representa o celular na horizontal e mostra quatro imagens. As quatro imagens estão no topo da tela a partir do lado esquerdo e todas as imagens estão com o mesmo tamanho. Após a quarta imagem ainda sobra um pequeno espaço para acabar a tela do celular. 3.5 RelativeLayout A classe RelativeLayout também é bastante utilizada, através dela é possível posicionar um componente em relação ao outro. Como assim professor? Por exemplo, imagine que você tem uma imagem no topo da sua tela, usando o RelativeLayout é possível você especificar que um determinado elemento deve aparecer ao lado dessa imagem (o programador informa se é lado direito ou lado esquerdo), acima dela ou abaixo dela. Mas como dizer que um componente deve aparecer ao lado, abaixo ou acima de outro? Primeiro, você precisa nomear (ou referenciar, que é o termo mais comum) especificando um ID para cada componente da tela, assim o Android vai entender. Assim, por exemplo, você vai poder dizer para o Android: eu quero que o componente A fique abaixo do componente B. Vamos ver alguns atributos importantes que podem ser usados pelo RelativeLayout na tabela a seguir. ATRIBUTO DESCRIÇÃO Android:layout_below Posiciona o elemento abaixo de outro. Android:layout_above Posiciona o elemento acima de outro. Android:layout_toLeftOf Posiciona o elemento à esquerda de outro. Android:layout_toRightOf Posiciona o elemento à direita de outro. Android:layout_marginTop Utilizado para definir um espaço (margem) na parte superior (Top) do componente. Competência 03 42 Android:layout_marginBottom Utilizado para definir um espaço (margem) na parte inferior (Bottom) do componente. Android:layout_marginRight Utilizado para definir um espaço (margem) na parte direita (Right) do componente. Android:layout_marginLeft Utilizado para definir um espaço (margem) na parte esquerda (Left) do componente. Tabela 3 - Atributos do RelativeLayout Fonte: o autor Descrição: Tabela com os atributos de RelativeLayout que podem ser usados para posicionar os elementos na tela. Agora que já aprendemos o conceito de RelativeLayout e vimos os atributos de posicionamento que podem ter seus componentes internos, vamos ver um exemplo de um formulário de cadastro com nome e senha e confirmação de senha fazendo o uso do RelativeLayout. <?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:Android="http://schemas.Android.com/apk/res/Android" Android:layout_width="match_parent" Android:layout_height="match_parent"> <TextView Android:id="@+id/txtViewDescricao" Android:layout_width="match_parent" Android:layout_height="wrap_content" Android:layout_margin="20dp" Android:gravity="center" Android:textSize="20dp" Android:text="Formulário de cadastro de usuário" /> <TextView Android:id="@+id/txtViewLogin" Android:layout_width="155dp" Android:layout_height="wrap_content" Android:layout_below="@+id/txtViewDescricao" Android:layout_marginBottom="20dp" Android:layout_marginLeft="15dp" Android:text="Login" /> Competência 03 43 <EditText Android:id="@+id/editTxtLogin" Android:layout_width="match_parent" Android:layout_height="wrap_content" Android:layout_alignTop="@+id/txtViewLogin" Android:layout_toRightOf="@+id/txtViewLogin" Android:background="@Android:drawable/editbox_background" /> <TextView Android:id="@+id/txtViewSenha" Android:layout_width="155dp" Android:layout_height="wrap_content" Android:layout_below="@+id/txtViewLogin" Android:layout_marginBottom="20dp" Android:layout_marginLeft="15dp" Android:text="Senha" /> <EditText Android:id="@+id/editTxtSenha" Android:layout_width="match_parent" Android:layout_height="wrap_content" Android:layout_alignTop="@+id/txtViewSenha" Android:layout_toRightOf="@+id/txtViewSenha" Android:background="@Android:drawable/editbox_background" Android:password="true" /> <TextView Android:id="@+id/txtViewConfirmacaoDeSenha" Android:layout_width="155dp" Android:layout_height="wrap_content" Android:layout_below="@+id/editTxtSenha" Android:layout_marginBottom="20dp" Android:layout_marginLeft="15dp" Android:text="Confirmação de senha" /> Competência 03 44 <EditText Android:id="@+id/editTxtConfirmacaoDeSenha" Android:layout_width="match_parent" Android:layout_height="wrap_content" Android:layout_alignTop="@+id/txtViewConfirmacaoDeSenha"
Compartilhar