Dominando o Android

Page 1

Nelson Glauber de Vasconcelos Leal

Novatec


Copyright © 2015 da Novatec Editora Ltda. Todos os direitos reservados e protegidos pela Lei 9.610 de 19/02/1998. É proibida a reprodução desta obra, mesmo parcial, por qualquer processo, sem prévia autorização, por escrito, do autor e da Editora. Editor: Rubens Prates Revisão gramatical: Marta Almeida de Sá Editoração eletrônica: Carolina Kuwabata Assistente editorial: Priscila A. Yoshimatsu Capa: Leo Macedo ISBN: 978-85-7522-412-0 Histórico de impressões: Janeiro/2015

Primeira edição

Novatec Editora Ltda. Rua Luís Antônio dos Santos 110 02460-000 – São Paulo, SP – Brasil Tel.: +55 11 2959-6529 E-mail: novatec@novatec.com.br Site: novatec.com.br Twitter: twitter.com/novateceditora Facebook: facebook.com/novatec LinkedIn: linkedin.com/in/novatec


capítulo 1

Conceitos básicos

Neste capítulo criaremos nosso primeiro projeto Android e conheceremos sua estrutura. Em seguida, falaremos do processo de compilação e execução de um aplicativo, das ferramentas de depuração existentes e do tratamento de eventos de clique. Veremos também como funciona a alocação de recursos de uma aplicação e como iniciar aplicativos nativos do aparelho.

Iniciando um novo projeto com Android Studio Vamos criar o nosso primeiro projeto Android. Abra o Android Studio, e será exibida a tela de boas-vindas1 apresentada na figura 1.1. Nela, podemos optar respectivamente por: • criar um novo projeto; • abrir um projeto existente; • fazer checkout a partir de um sistema de controle de versão (como Git ou Subversion); • importar um projeto existente; • alterar configurações no Android Studio; • ou acessar a documentação. Selecione a opção Start a new Android Studio project e será exibida a primeira tela do assistente, similar à mostrada na figura 1.2.

1 Na parte inferior dessa tela existe a opção Check for updates. Clique nessa opção para atualizar o Android Studio para a versão mais atual.

29


30

Dominando o Android

Figura 1.1 – Tela de boas-vindas do Android Studio.

Figura 1.2 – Tela do assistente de criação de um novo projeto.

O campo Application Name é o nome do seu aplicativo que aparecerá no aparelho. Em Company Domain, devemos informar o domínio da sua empresa, e ao preenchê-lo será gerado o Package Name, que representa o pacote Java onde ficarão as classes do projeto. Esse campo é muito importante porque ele serve de identificador único do seu aplicativo, ou seja, não pode haver dois aplicativos com o mesmo nome de pacote instalados no aparelho. É essencial escolher um bom nome, pois não é possível publicar uma aplicação no Google Play com dois nomes de pacote iguais. Por fim, em Project Location podemos selecionar onde será salvo o projeto. Por padrão, os projetos ficarão armazenados no subdiretório AndroidStudioProjects dentro diretório do usuário no sistema operacional. Clique em Next para irmos para a próxima etapa do assistente exibida na figura 1.3.


Capítulo 1 ■ Conceitos básicos

31

Figura 1.3 – Selecionando o tipo do dispositivo do projeto.

Nessa tela podemos optar por criar os módulos da nossa aplicação para smartphone e tablet, TV, Wear (relógios) e Glass (óculos). Em todos os casos, devemos preencher o campo Minimum required SDK, que é a versão mínima do Android que o aparelho deve possuir para executar nossa aplicação. Quanto menor a versão, mais dispositivos poderemos suportar, porém teremos menos APIs disponíveis. Boa parte do que utilizaremos neste livro será suportada pela versão 2.3 do Android ou posterior (o que contempla a quase totalidade dos aparelhos do mercado), mas deixaremos explícito quando usarmos alguma API que necessite de uma versão específica. Por ora, selecione apenas Phone and Tablet e clique em Next para irmos à próxima tela do assistente exibida na figura 1.4. Nessa tela do assistente, podemos adicionar uma Activity ao nosso projeto. Falaremos sobre Activities no próximo capítulo, mas por ora saiba que toda tela de uma aplicação é uma Activity. Selecione Blank Activity e clique em Next para exibir a tela da figura 1.5. Nessa tela, podemos informar o nome da Activity principal da aplicação no campo Activity Name. Por convenção, sempre colocamos “Activity” no final do nome da classe. Por padrão, o assistente nomeia a classe como MainActivity. Cada activity tem o seu aspecto visual especificado em arquivos XML que chamaremos daqui em diante simplesmente de arquivos de layout. O nome desse arquivo é definido no campo Layout Name. Por fim, no campo Title, especificamos o nome da aplicação


32

Dominando o Android

que aparecerá para o usuário no aparelho. Clique em Finish para concluir o assistente e criar o projeto2.

Figura 1.4 – Selecionando uma Activity inicial para o projeto.

Figura 1.5 – Informando o nome da Activity principal da aplicação. 2 É importante que você tenha conexão com a internet nesse momento (principalmente a primeira vez), pois o Android Studio fará o download de algumas dependências do projeto.


Capítulo 1 ■ Conceitos básicos

33

Nos próximos projetos que criaremos no decorrer do livro, informaremos apenas o nome do projeto, do pacote e da activity principal da aplicação. Se formos definir algo diferente do que vimos aqui, deixaremos isso explícito. Fique à vontade para escolher o que preferir, e também fique atento para usar o nome de pacote que você escolheu quando for necessário. Para esse exemplo, daríamos apenas as informações mostradas a seguir. Application Name

Ex01_Hello

Package Name

dominando.android.ex01_hello

Activity Name

MainActivity

Depois que o projeto for criado, teremos uma estrutura igual à da figura 1.6.

Figura 1.6 – Estrutura de um projeto no Android Studio.

Na parte superior, selecione a opção Project que nos proporcionará outra visualização do nosso projeto. Utilizaremos essa visualização no decorrer do livro. Vamos detalhar alguns arquivos dessa estrutura agora e discutiremos outros no decorrer do livro. Focaremos inicialmente no arquivo AndroidManifest.xml e nas pastas app/src/main/java e app/src/main/res. Começando pelo AndroidManifest.xml listado a seguir.


34

Dominando o Android <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="dominando.android.ex01_hello" > <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name=".MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>

Boa parte da informação contida nesse arquivo foi criada com as informações que preenchemos no assistente de criação do projeto. Na tag <manifest>, temos o pacote da aplicação definido na propriedade package. Em seguida, na tag <application>, adicionamos algumas configurações ao nosso aplicativo. A propriedade android:allowBackup informa que o Android poderá fazer backup dos dados da aplicação. Em seguida, a propriedade android:icon define o ícone da aplicação apontando para @drawable/ic_launcher. Mas o que isso significa? Cada recurso da aplicação (imagem, texto, layout, som etc.) é mapeado em um identificador3 na classe R, que é gerada automaticamente, e esses recursos ficam localizados na pasta app/src/main/res. Por exemplo, se observarmos a pasta res/drawable-mdpi, notaremos que haverá um arquivo chamado ic_launcher.png, que estará representado na classe R pelo identificador R.drawable.ic_launcher, que poderemos usar no nosso código Java. Para usar essa mesma imagem em arquivos XML – como o AndroidManifest.xml –, usamos @drawable/ic_launcher. Mas por que temos quatro pastas drawable? As quatro pastas armazenam a mesma imagem para telas com qualidades diferentes (DPI – Dots Per Inch), que explicaremos mais adiante ainda neste capítulo. 3 Esse identificador é um inteiro de 32 bits do Java (int).


Capítulo 1 ■ Conceitos básicos

35

Voltando ao AndroidManifest.xml, na propriedade android:label, estamos apontando para @string/app_name. Seguindo a lógica do ícone da aplicação, deveríamos ter uma pasta chamada string, certo? Quase! No caso dos textos da aplicação, eles estão localizados no arquivo res/values/strings.xml. <?xml version="1.0" encoding="utf-8"?> <resources> <string name="app_name">Ex01_Hello</string> <string name="hello_world">Hello world!</string> <string name="action_settings">Settings</string> </resources>

Assim, para acessar o texto “Ex01_Hello” em nosso código Java, usaríamos o método getString(int) passando o identificador R.string.app_name como parâmetro, enquanto em arquivos XML usamos @string/app_name. O resumo de alguns recursos e seu mapeamento na classe R e a forma de acessá-los em arquivos XML estão descritos na tabela 1.1. Tabela 1.1 – Mapeamento dos recursos na classe R e no XML Recurso

ID da classe R

Em arquivos XML

res/drawable/ic_launcher.png

R.drawable.ic_launcher

@drawable/ic_launcher

res/layout/activity_main.xml

R.layout.activity_main

@layout/activity_main

res/menu/menu_main.xml

R.menu.menu_main

@menu/menu_main

res/values/strings.xml <string name="ola"> R.string.ola

@string/ola

res/values/dimens.xml <dimen name="margem"> R.dimen.margem

@dimen/margem

Mais uma vez voltando ao AndroidManifest.xml, todas as activities da aplicação devem estar declaradas nesse arquivo com a tag <activity>, e na propriedade android:name informamos o nome da classe. Já em android:label, informamos o texto que aparecerá no título da tela (mais uma vez usando o texto declarado no res/values/strings.xml). Também explicaremos as tags <intent-filter>, <action> e <category> mais adiante, mas, por enquanto, devemos apenas saber que a ação android.intent.action.MAIN indica que essa activity é um ponto de entrada da aplicação, ou seja, por onde o usuário pode acessá-la, e a categoria android.intent.category.LAUNCHER indica que a Activity aparecerá na lista de aplicações do aparelho.


36

Dominando o Android

Vamos analisar agora o código da classe MainActivity listado a seguir. package dominando.android.ex01_hello; import import import import

android.support.v7.app.ActionBarActivity; android.os.Bundle; android.view.Menu; android.view.MenuItem;

public class MainActivity extends ActionBarActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.menu_main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { // Handle action bar item clicks here. The action bar will // automatically handle clicks on the Home/Up button, so long // as you specify a parent activity in AndroidManifest.xml. int id = item.getItemId(); if (id == R.id.action_settings) { return true; } return super.onOptionsItemSelected(item); } }

Ela está definida no pacote que indicamos no assistente de criação do projeto e herda da classe ActionBarActivity. Essa é uma subclasse de Activity que permite que a nossa aplicação use a action bar, que é a barra localizada na parte superior da tela, onde ficam o título e as opções de menu. Fazendo uma analogia com aplicações desktop, ela seria uma mistura de barra de título, menu de opções e barra de ferramentas. Exploraremos a ActionBar no capítulo 6.


Capítulo 1 ■ Conceitos básicos

37

O método onCreate(Bundle) é chamado quando a Activity é criada4, e nele chamamos o método setContentView(int) para informar qual é o arquivo de layout dessa tela. O arquivo de layout é um XML com a descrição dos componentes que devem ser exibidos na tela e está localizado em res/layout/activity_main.xml. Notem que também estamos usando a classe R para nos referenciar a ele, usando R.layout.activity_main. Ao dar um Ctrl+Clique (ou Command+Clique no Mac), será exibido o editor visual de layouts, similar ao da figura 1.7.

Figura 1.7 – Editor visual de layouts.

A paleta com os componentes que podemos adicionar ao nosso arquivo de layout está localizada no lado esquerdo. No canto superior direito, temos o Component Tree, que nos permite visualizar a estrutura do arquivo de layout, ou seja, como os componentes estão organizados hierarquicamente. Já na parte inferior direita, temos a lista de propriedades do componente, as quais podemos editar. Na parte central, além da pré-visualização do layout, temos na área superior algumas opções interessantes para simularmos variações em nosso layout, como vê-lo em landscape (na horizontal), em um idioma diferente ou em outros aparelhos. Na parte inferior é possível notar duas abas: Design e Text. A segunda exibe o XML do arquivo de layout, que deve estar como este: 4 Não devemos usar o construtor de uma subclasse de Activity para fazer inicializações.


38

Dominando o Android <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity"> <TextView android:text="@string/hello_world" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </RelativeLayout>

Falaremos em layouts e componentes detalhadamente nos capítulos 2 e 3. Entretanto vamos fazer algumas observações aqui para você ter uma ideia do que está acontecendo. O RelativeLayout é um gerenciador de layout que posiciona cada componente em relação aos demais ou às bordas. Nesse exemplo, definimos a propriedade android:padding (que é um espaçamento dado entre a borda do componente e o seu conteúdo) usando @dimen/activity_horizontal_margin e @dimen/activity_vertical_margin. Mas você deve estar vendo o valor 16dp, certo? Porém, se você pausar o cursor sobre o valor, verá que estamos apontando para o @dimen. Vá até o diretório res/values/dimens.xml e verá a declaração desses valores. Esse valor é uma recomendação do Android para margens, e usar o arquivo dimens.xml nos permite colocar esse tipo de informação em um único local. <resources> <!-- Default screen margins, per the Android Design guidelines. --> <dimen name="activity_horizontal_margin">16dp</dimen> <dimen name="activity_vertical_margin">16dp</dimen> </resources>

Outro detalhe que queremos destacar no arquivo de layout é a tag <TextView> que representa um texto estático na tela e que tem sua propriedade android:text apontando para mais um texto definido res/values/strings.xml. Discutiremos os métodos onCreateOptionsMenu(Menu) e onOptionsItemSelected(MenuItem) quando formos falar da ActionBar.


Capítulo 1 ■ Conceitos básicos

39

Executando a aplicação Para executar a aplicação, conecte seu aparelho ao computador ou inicie o emulador. Em seguida, clique no botão Run app (botão verde em forma de play) e será exibida a tela da figura 1.8, onde podemos selecionar o dispositivo (se houver mais de um) no qual desejamos executar a aplicação. Clique em OK e o aplicativo será exibido no dispositivo selecionado conforme a figura 1.9.

Figura 1.8 – Seleção do aparelho para executar a aplicação.

Figura 1.9 – Aplicação Hello World rodando no emulador.

Pronto! Nossa primeira aplicação está em execução e na próxima seção veremos as etapas que ocorreram para que isso acontecesse.


40

Dominando o Android

Processo de compilação Após observarmos a aplicação executando, é importante entender o que aconteceu durante esse processo. O processo de build (ou construção) envolve a compilação, a assinatura, o empacotamento e a execução do aplicativo. No Android isso é feito de uma forma um pouco diferente de uma aplicação Java convencional (para desktop ou web).

Figura 1.10 – Processo de build de uma aplicação Android.

Conforme podemos ver na figura 1.10, temos as seguintes etapas: • O Android Asset Packaging Tool (aapt) obtém os recursos da aplicação e os compila, gerando a classe R.java e os recursos compilados (resources.arsc). O aapt também gera o AndroidManifest.xml encriptado. • Todo o seu código Java, incluindo a classe R.java, será compilado em arquivos .class usando o compilador javac. • A ferramenta dex converte esses arquivos .class em bytecodes da máquina virtual do Android. Até o KitKat, a máquina virtual era a Dalvik, mas a partir do Lollipop (5.0) a máquina virtual passou a ser o ART (Android Runtime). • O apkbuilder empacota o resources.arsc, o classes.dex e o AndroidManifest.xml (encriptado) em um arquivo .apk (Android Package), que é o arquivo usado para instalação da aplicação. Entranto esse arquivo deve ser assinado pelo jarsigner para poder ser instalado no aparelho. Por padrão, eles são assinados com uma chave de debug.5 5 Toda aplicação Android é assinada com o arquivo debug.keystore, que encontra-se no subdiretório .android na pasta do usuário. Para publicar no Google Play, usa-se uma outra chave gerada pelo próprio desenvolvedor. Veremos esse processo no capítulo 26.


Capítulo 1 ■ Conceitos básicos

41

Uma vez que o .apk é gerado, ele é salvo em seu_projeto/app/build/outputs/apk/app-debug.apk e a IDE utiliza a ferramenta adb (Android Debug Bridge) para instalar a aplicação no dispositivo. Essa ferramenta encontra-se no subdiretório platform-tools dentro da pasta do SDK. O adb tem alguns comandos interessantes6 que você pode utilizar por meio da linha de comando: adb adb adb adb adb adb adb

devices kill-server start-server install -r SuaApp.apk shell pm uninstall –k pacote.da.app push arquivo.jpg /mnt/sdcard pull /mnt/sdcard/arquivo.jpg /Users/nglauber/Desktop

O comando devices listará os dispositivos conectados ao seu computador. O kill-server encerrará a execução do adb, enquanto o start-server iniciará o serviço. Para instalar um APK no aparelho, podemos usar o comando install, onde o parâmetro -r indica que a aplicação deve ser reinstalada caso já exista. O uninstall irá desinstalar o aplicativo de acordo com o pacote passado como parâmetro. Já os comandos push e pull servem para copiar arquivos para o aparelho e do aparelho respectivamente, passando o local de origem e de destino. Consulte a documentação para conhecer outros comandos do adb. Na próxima seção estudaremos um recurso bastante poderoso: a alocação dinâmica de recursos.

Alocação dinâmica de recursos Todos os recursos que usamos na nossa aplicação (strings, imagens, estilos, layouts etc.) ficam dentro da pasta res (abreviação de resources), mas cada subdiretório tem um objetivo específico, os principais são: • anim e animator – arquivos XML de animações quadro-a-quadro ou de efeito. • drawable – arquivos de imagens da aplicação. • menu – arquivos XML com as opções de menu. • layout – arquivos XML com os layouts de telas. 6 Se estiver usando Mac OS X ou Linux, adicione o “./”


42

Dominando o Android

• values – arquivos XML que contêm valores tais como strings (texto simples), string arrays (lista de valores), dimensões (definição de tamanhos), color (definição de cores), style (estilos) etc. • xml – essa pasta normalmente armazena arquivos XML de metadados da aplicação. • raw – outros tipos de arquivos que podem ser usados no projeto. Todos os arquivos armazenados nessas pastas devem obrigatoriamente ser nomeados com todas as letras minúsculas, mas podem conter underline “_” ou números a partir do segundo caractere. O Android tem um conceito de alocação dinâmica de recursos, em que o sistema operacional seleciona o recurso mais apropriado de acordo com a configuração do aparelho. Para isso, nós precisamos apenas criar variações dos diretórios, adicionando sufixos a eles, e o Android se encarregará de obter o recurso mais adequado. A tabela 1.2 lista os principais sufixos com alguns exemplos. Tabela 1.2 – Sufixos para alocação de recursos Configuração Operadora

Idioma

Tamanho de tela (ver tabela 1.5) Orientação de tela

Densidade da tela (ver tabela 1.3)

API Level (ver tabela 0.1)

Exemplo do sufixo mcc724-mnc05 mcc724-mnc31 en en-rUS pt pt-rBR small normal large xlarge port land ldpi mdpi tvdpi hdpi xhdpi xxhdpi xxxhdpi v10 v11 v14

Recurso para Operadora do Brasil (mcc-724) e código 05 (Claro) e 31 (Oi) Inglês (qualquer país) Inglês dos Estados Unidos Português (qualquer país) Português do Brasil Telas pequenas Telas normais Telas grandes Telas extragrandes Portrait (vertical) Landscape (horizontal) Baixa densidade (120 dpi) Média densidade (160 dpi) Densidade de TV (213 dpi) Alta densidade (240 dpi) Densidade extra-alta (320 dpi) Densidade extra-alta (480 dpi) Densidade extra-alta (640 dpi) Aparelhos com Android 2.3 ou superior Aparelhos com Android 3.0 ou superior Aparelhos com Android 4.0 ou superior


Capítulo 1 ■ Conceitos básicos

43

É importante ressaltar que podemos combinar os sufixos descritos anteriomente, como por exemplo layout-pt-rBR-large; values-v11-mcc724-mnc31 ou drawable-land-hdpi. Outro detalhe é que o Android buscará o recurso mais próximo, e caso não exista ele procurará algo mais genérico. Para fixar os conceitos apresentados, vamos internacionalizar nosso aplicativo criando o diretório res/values-pt e colocar os textos em português no arquivo strings.xml. Assim, quando o aparelho estiver com o idioma configurado para português, os textos da aplicação mudarão automaticamente. Clique sobre a pasta app/src/main/res e escolha a opção New > Android Resource Directory, e será exibida a tela da figura 1.11. Selecione a opção values no campo Resource type, em seguida selecione Language na listagem da esquerda e clique no botão >>. Na tela da figura 1.12, selecione o idioma português e clique em OK.

Figura 1.11 – Criando um novo diretório de recursos.

Figura 1.12 – Selecionando o idioma da pasta values.


44

Dominando o Android

Agora copie o arquivo strings.xml da pasta res/values para a pasta res/values-pt. E modifique-o para ficar como a seguir. <?xml version="1.0" encoding="utf-8"?> <resources> <string name="app_name">Ex01_Olá</string> <string name="hello_world">Olá mundo!</string> <string name="action_settings">Configurações</string> </resources>

Por padrão, o idioma do emulador é o inglês, então, se executarmos a aplicação, o texto “Hello world” ainda será exibido. Agora modifique o idioma do aparelho7 para português, indo nas configurações do aparelho e selecionando a opção Language & input, e por fim o idioma português no campo Language. Execute a aplicação e agora o texto “Olá mundo!” deverá ser exibido. Voltando para nossa discussão sobre alocação de recursos, podemos notar que, quando o projeto foi criado, o próprio Android Studio adicionou quatro variações da pasta drawable para nós: res/drawable-hdpi res/drawable-mdpi res/drawable-xhdpi res/drawable-xxhdpi

Isso fará com que o sistema operacional selecione a imagem de acordo com a qualidade da tela, que é medida em DPIs (Dots Per Inch – Pontos por polegadas). Atualmente temos dispositivos Android de diversos tamanhos e com qualidade de tela diferentes. É importante conhecermos a tabela 1.3 para definirmos imagens adequadamente para cada uma delas. O que essa tabela nos diz? Que imagens para aparelhos xxhdpi devem ter o dobro do tamanho (largura e altura) de imagens para aparelhos hdpi, por exemplo. Então é importante que tenhamos imagens para cada densidade de tela que iremos trabalhar, pois, caso contrário, elas podem aparecer distorcidas. Seguindo o mesmo princípio, é possível criar arquivos de layout para quando o aparelho estiver em landscape ou para resoluções de tela diferentes (ou combinando ambas). A tabela 1.4 exibe alguns exemplos comuns de pastas de layout. 7 A forma de mudar o idioma do aparelho pode variar um pouco de acordo com o modelo do aparelho e/ou versão do Android. Tente achar a opção correspondente no seu aparelho.


Capítulo 1 ■ Conceitos básicos

45 Tabela 1.3 – Densidades de tela

Densidade

Dots per inch

Proporção

ldpi

120dpi

0.75

mdpi

160dpi

1.00

tvdpi

213dpi

1.33

hdpi

240dpi

1.50

xhdpi

320dpi

2.00

xxhdpi

480dpi

3.00

xxxhdpi

640dpi

4.00

Tabela 1.4 – Exemplo de pastas de Layout Pasta

Propósito Layout em portrait ou landscape, independente do tamanho da tela

res/layout res/layout-port

Layout em portrait independente do tamanho da tela

res/layout-large

Layout em portrait ou landscape, para telas grandes

res/layout-land-xlarge

Layout em landscape para telas extra grandes

Mas o que determina se uma tela é pequena, normal, grande ou extragrande? O Android estipula alguns intervalos para classificá-las que estão listados na tabela 1.5. Tabela 1.5 – Classificação de telas Classificação

Tamanho mínimo

small

426 dp x 320 dp

normal

470 dp x 320 dp

large

640 dp x 480 dp

xlarge

960 dp x 720 dp

Se você observar, a medida da tela é definida em DP (ou DIP – Density Independent Pixels), que é uma unidade de medida que leva em consideração a quantidade de pixels na tela em sua área física. Sendo assim, quanto mais pixels tivermos por área, melhor será a qualidade da tela. Então como saber qual o tamanho da tela em dp? Basta usar a seguinte fórmula: dp = pixels / (dpi / 160)


46

Dominando o Android

Por exemplo, qual o tamanho da tela em dp de um aparelho com resolução de 1.024 por 768 pixels com densidade HDPI (240 dpi)? dp = 1024 / (240 / 160) dp = 1024 / 1,5 dp = 680

dp = 768 / (240 / 160) dp = 768 / 1,5 dp = 512

Com base na tabela 1.5 podemos constatar que uma tela de 680 dp x 512 dp é considerada grande (large). É possível descobrir todas as configurações de recursos que podem variar de acordo com o aparelho por meio da classe android.content.res.Configuration. Adicione o código a seguir no método onCreate(Bundle) da sua Activity. Configuration configuration = getResources().getConfiguration(); int density = configuration.densityDpi; int orientation = configuration.orientation; int height = configuration.screenHeightDp; int width = configuration.screenWidthDp; int mcc = configuration.mcc; int mnc = configuration.mnc; Locale locale Log.d("NGVL", Log.d("NGVL", Log.d("NGVL", Log.d("NGVL", Log.d("NGVL", Log.d("NGVL", Log.d("NGVL",

= configuration.locale; "density: "+ density); "orientation: "+ orientation); "height: "+ height); "width: "+ width); "language: "+ locale.getLanguage() + "-" + locale.getCountry()); "mcc: "+ mcc); "mnc: "+ mnc);

Se o código apresentar erro, é porque falta importar essas classes. Posicione o cursor em cima do nome da classe e selecione o menu Code > Optimize imports.... Com as informações obtidas no código anterior você pode criar os recursos mais apropriados para o seu aparelho. Mas o que faz o Log.d(String, String)?

Android Debug Monitor e Logcat O Android SDK vem com uma poderosa ferramenta para análise e depuração de aplicações. O Debug Monitor – mostrado na figura 1.13 – nos permite visualizar os processos que estão sendo executados no aparelho, o sistema de arquivos, o


Capítulo 1 ■ Conceitos básicos

47

consumo de memória, threads, logs da aplicação etc. Ele pode ser acessado no menu Tools > Android > Android Device Monitor. Na janela Devices temos a lista dos dispositivos conectados ao computador, e uma função muito útil nessa janela é a opção de tirar um screenshot da tela do aparelho, bastando para isso selecionar o aparelho e clicar no botão com o ícone de uma câmera. O Debug Monitor também nos permite visualizar o sistema de arquivos do aparelho por meio da janela File Explorer, onde podemos enviar ou obter arquivos do aparelho. Mas, sem dúvida, a janela mais importante dessa ferramenta é a Logcat, pois com ela podemos visualizar todos os logs gerados pelas aplicações.

Figura 1.13 – Android Debug Monitor.

No Logcat podemos filtrar os logs por aplicação, por textos específicos, por número de processo e por nível, que pode ser: verbose, debug, info, warning e error. Para criar um filtro, basta clicar no botão ”+” e preencher as informações do filtro. O LogCat e a janela Devices estão disponíveis também dentro do Android Studio, conforme podemos ver na figura 1.14.

Figura 1.14 – Logcat dentro do Android Studio.


48

Dominando o Android

Para entender melhor o log, vejamos o que é exibido: na primeira coluna temos a hora do log; depois o número do processo seguido do id da thread (separado por “-“); logo após, temos o nome do pacote da aplicação; o tipo do log (“D” de debug) e a tag separados por “/”; e por último a mensagem do log.

findViewById e evento de clique Agora vamos adicionar alguma interação à nossa aplicação. Veremos como obter a referência de um componente declarado em um arquivo de layout e como tratar o evento de clique em botões. Crie um novo projeto com os dados a seguir. Application Name

Ex02_Activity

Package Name

dominando.android.ex02_activity

Activity Name

MainActivity

Abra o arquivo res/layout/activity_main.xml, remova o TextView que contém o “Hello World” e em seguida adicione um Plain Text arrastando-o da seção Text Fields da paleta de componentes. Abaixo dele, adicione um Button que encontra-se na seção Widgets. Agora abra o XML para fazermos alguns ajustes conforme a seguir. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity"> <EditText android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/editText" android:layout_alignParentLeft="true" android:layout_alignParentStart="true"/> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/btn_toast"


Capítulo 1 ■ Conceitos básicos

49

android:id="@+id/button" android:layout_below="@+id/editText" android:layout_alignParentLeft="true"/> </RelativeLayout>

O resultado deve ficar igual ao da figura 1.15.

Figura 1.15 – Arquivo de layout do segundo projeto.

Nos próximos exemplos, para montar os arquivos de layout, aconselho adicionar os componentes por meio da paleta de componentes e ajustar as propriedades manualmente no XML. Utilize a combinação de tecla Ctrl+Espaço para facilitar a procura pela propriedade desejada e evitar erros de digitação. Note que na propriedade android:text usamos a @string/btn_toast, então adicione essa string no res/values/strings.xml. <resources> ... <string name="btn_toast">Exibir toast</string> </resources>

Um ponto importante que queremos ressaltar aqui é a propriedade android:id, na qual atribuímos o identificador do componente. Os valores @+id/editText e @+id/button indicam que esses ids serão criados na classe R, assim teremos R.id. editText e R.id.button respectivamente.


50

Dominando o Android

A propriedade android:layout_alignParentStart indica que o EditText ficará no topo superior esquerdo do seu pai, ou seja, do próprio RelativeLayout. Para indicar que o Button ficará abaixo do EditText, definimos a propriedade android:layout_below passando o id. Por fim, a propriedade android:layout_alignParentLeft indica que o componente ficará alinhado à esquerda do RelativeLayout. Agora deixe o código da Activity conforme a seguir8: import import import import import import

android.os.Bundle; android.support.v7.app.ActionBarActivity; android.view.View; android.widget.Button; android.widget.EditText; android.widget.Toast;

public class MainActivity extends ActionBarActivity implements View.OnClickListener { EditText edtTexto; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); edtTexto = (EditText) findViewById(R.id.editText); Button button = (Button) findViewById(R.id.button); button.setOnClickListener(this); } @Override public void onClick(View view) { String texto = edtTexto.getText().toString(); Toast.makeText(this, texto, Toast.LENGTH_SHORT).show(); } }

No método onCreate(Bundle) obtemos a referência do EditText por meio do findViewBydId(int) passando o id do componente que definimos no arquivo de layout e fazemos o mesmo com o botão. Para tratar o evento do clique do botão, devemos chamar o método setOnClickListener(View.OnClickListener) passando um objeto que implemente a interface View.OnClickListener, que no nosso caso é a própria Activity. Dessa forma, quando clicarmos no botão, o método onClick(View) será chamado. 8 Perceba que omitimos o nome do pacote no código-fonte. Faremos isso no decorrer do livro, mas você deve adicioná-lo no seu código-fonte.


Capítulo 1 ■ Conceitos básicos

51

Nele, obtemos o texto contido no EditText e depois criamos um Toast com o método makeText(Context, String, int). Um Toast é uma mensagem que aparece durante um tempo e depois desaparece automaticamente. A duração pode ser LENGTH_SHORT e LENGTH_LONG, em que com a primeira a mensagem fica cerca de 2 segundos e com a segunda, 3,5 segundos. Execute a aplicação, digite algum texto e pressione o botão. A mensagem será exibida centralizada na parte inferior da tela. Uma pergunta que você pode estar se fazendo é: “se eu tiver mais de um botão, como eu vou saber qual deles foi clicado?”. Se você observar, o método onClick(View) recebe um objeto View9 como parâmetro, que indica o componente que disparou o evento. Assim, se tivéssemos mais de um botão, poderíamos descobrir qual componente disparou o evento baseado no seu id. @Override public void onClick(View view) { switch (view.getId()) { case R.id.button: String texto = edtTexto.getText().toString(); Toast.makeText(this, texto, Toast.LENGTH_SHORT).show(); break; case R.id.outroBotao: // Tratar o outro botão aqui break; } }

Agora que já fizemos a primeira interação da nossa aplicação, veremos como criar e exibir novas telas, bem como passar parâmetros para elas.

9 No Android, todos os componentes visuais herdam direta ou indiretamente da classe android. view.View.


Issuu converts static files into: digital portfolios, online yearbooks, online catalogs, digital photo albums and more. Sign up and create your flipbook.