Su Mario 9788575224472

29
Novatec Nelson Glauber de Vasconcelos Leal 2ª edição

description

Su Mario 9788575224472

Transcript of Su Mario 9788575224472

Page 1: Su Mario 9788575224472

Novatec

Nelson Glauber de Vasconcelos Leal

2ª edição

Page 2: Su Mario 9788575224472

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 PY20151111Assistente editorial: Priscila A. YoshimatsuRevisão gramatical: Priscila A. YoshimatsuEditoração eletrônica: Carolina KuwabataCapa: Leo Macedo

ISBN: 978-85-7522-463-2

Histórico de impressões:

Novembro/2015 Segunda ediçãoMarço/2015 Primeira reimpressãoJaneiro/2015 Primeira edição

Novatec Editora Ltda.Rua Luís Antônio dos Santos 11002460-000 – São Paulo, SP – BrasilTel.: +55 11 2959-6529E-mail: [email protected]: novatec.com.brTwitter: twitter.com/novateceditoraFacebook: facebook.com/novatecLinkedIn: linkedin.com/in/novatecPY20151111

Page 3: Su Mario 9788575224472

33

capítulo 1Conceitos 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 StudioVamos 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 (do Eclipse/ADT, por exemplo);

• importar um código de exemplo do Android;

• 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 as-sistente, 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.

Page 4: Su Mario 9788575224472

Dominando o Android – 2ª edição34

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

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

Page 5: Su Mario 9788575224472

35Capítulo 1 ■ Conceitos básicos

O campo Application Name é o nome do seu aplicativo que aparecerá no aparelho, por isso escolha um bom nome, pois é ele que o usuário visualizará no seu smartphone ou tablet. Esse nome pode ser alterado posteriormente como mostraremos adiante. Em Company Domain, devemos informar o domínio da sua empresa; caso seja um projeto pessoal, você pode usar as suas iniciais. Ao preencher o Company Domain, será gerado automaticamente 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 é pos-sível publicar uma aplicação no Google Play com um nome de pacote que já exista. Como os domínios na internet são únicos, utilizar o domínio da empresa aumenta a possibilidade de o nome do pacote do nosso aplicativo também ser único.

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 seu usuário no sistema operacional (por exemplo, C:\Uses\seu_usuario para Windows2). Clique em Next para irmos para a próxima etapa do assistente exibida na figura 1.3.

Figura 1.3 – Selecionando o tipo do dispositivo do projeto.

2 Caso o nome do seu usuário tenha acento ou espaços, você pode ter problemas durante a compi-lação da aplicação, então escolha outro local do seu computador.

Page 6: Su Mario 9788575224472

Dominando o Android – 2ª edição36

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 a aplicação. Quanto menor a versão, mais dispositivos poderemos suportar, porém teremos menos APIs disponíveis. Durante a escrita deste livro, 96% dos aparelhos estavam com a versão 4.0 (API Level 15) ou superior do Android. Dessa forma, todos os exemplos apresentados aqui devem funcionar a partir dessa versão, mas deixaremos explícito quando usarmos alguma API que necessite de uma versão específica. Por ora, selecione apenas Phone and Tablet, marque a API 15 e clique em Next para irmos à próxima etapa do assistente exibida na figura 1.4.

Figura 1.4 – Selecionando uma Activity inicial para o projeto.

Nessa tela do assistente, podemos adicionar uma Activity ao nosso projeto par-tindo de um template. Falaremos sobre Activities no próximo capítulo, mas por ora saiba que toda tela de uma aplicação é uma Activity. Selecione Empty 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. Uma convenção é colocarmos “Activity” no final do nome da classe, pois isso facilita sua identificação no decorrer do processo de desenvolvimento. Por padrão, o assistente nomeia a classe como MainActivity. Cada activity tem o seu

Page 7: Su Mario 9788575224472

37Capítulo 1 ■ Conceitos básicos

aspecto visual especificado em arquivos XML que daqui em diante chamaremos simplesmente de arquivos de layout. O nome desse arquivo é definido no campo Layout Name. Clique em Finish para concluir o assistente e criar o projeto3.

Figura 1.5 – Informando o nome da Activity principal da aplicação.

Nos próximos projetos que criarmos 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 nome 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 Hello

Package Name dominando.android.hello

Activity Name MainActivity

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

3 É 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.

Page 8: Su Mario 9788575224472

Dominando o Android – 2ª edição38

Figura 1.6 – Estrutura de um projeto no Android Studio.

Na parte superior, onde temos o ícone do Android, selecione a opção Project que nos proporcionará outra visualização do nosso projeto. Utilizaremos essa visu-alização no decorrer do livro, pois ela reflete exatamente a estrutura do projeto no sistema de arquivos.

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.

<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

package="dominando.android.hello" >

<application

android:allowBackup="true"

android:icon="@mipmap/ic_launcher"

android:label="@string/app_name"

android:supportsRtl="true"

android:theme="@style/AppTheme" >

Page 9: Su Mario 9788575224472

39Capítulo 1 ■ Conceitos básicos

<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 pro-priedade android:allowBackup informa que o Android poderá fazer backup dos dados da aplicação (falaremos com mais detalhes sobre ela no capítulo 7). Em seguida, a propriedade android:icon define o ícone da aplicação apontando para @mipmap/ic_launcher. Mas o que isso significa?

Cada recurso da aplicação (imagem, texto, layout, som etc.) é mapeado em um identificador4 na classe R, que é gerada automaticamente, e esses recursos fi-cam localizados na pasta app/src/main/res. Por exemplo, se observarmos a pasta res/mipmap-mdpi, notaremos que haverá um arquivo chamado ic_launcher.png, que estará representado na classe R pelo identificador R.mipmap.ic_launcher, que pode-remos usar no nosso código Java. Para usar essa mesma imagem em arquivos XML – como o AndroidManifest.xml –, usamos @mipmap/ic_launcher. Mas por que temos quatro pastas mipmap? As quatro pastas armazenam a mesma imagem para telas com qualidades diferentes (DPI – Dots Per Inch), que explicaremos mais adiante ainda neste capítulo.

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">Hello</string>

</resources>

4 Esse identificador é um inteiro de 32 bits do Java (int).

Page 10: Su Mario 9788575224472

Dominando o Android – 2ª edição40

Assim, para acessar o texto “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/mipmap/ic_launcher.png R.mipmap.ic_launcher @mipmap/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

Voltando ao AndroidManifest.xml, na tag <application> informamos que nosso aplica-tivo dará suporte a idiomas em que a leitura e a escrita são feitas da direita para a esquerda (Right To Left) por meio da propriedade android:supportsRtl.

Todas as activities da aplicação que serão exibidas para o usuário devem estar declaradas no AndroidManifest.xml com a tag <activity>, e na propriedade android:name informamos o nome da classe. Já em android:label, informamos o texto que aparece-rá 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.

Vamos analisar agora o código da classe MainActivity listado a seguir.

import android.support.v7.app. AppCompatActivity;

import android.os.Bundle;

public class MainActivity extends AppCompatActivity {

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

}

}

Page 11: Su Mario 9788575224472

41Capítulo 1 ■ Conceitos básicos

Ela está definida no pacote que indicamos no assistente de criação do projeto e herda da classe AppCompatActivity. Essa é uma subclasse de Activity que permite que a nossa aplicação utilize alguns recursos de versões mais recentes do Android em versões mais antigas, como, por exemplo, 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.

O método onCreate(Bundle) é chamado quando a Activity é criada5, e nele chama-mos o método setContentView(int) para informar qual é o arquivo de layout dessa tela, ou seja, qual é seu aspecto visual. 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 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

5 Não devemos usar o construtor de uma subclasse de Activity para fazer inicializações.

Page 12: Su Mario 9788575224472

Dominando o Android – 2ª edição42

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 apare-lhos. Caso tenha problemas em visualizar, tente mudar a versão do Android (ou instale-a), pois provavelmente você pode não ter essa versão.

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:

<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:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="Hello World!" />

</RelativeLayout>

Falaremos em layouts e componentes detalhadamente nos capítulos 3, 4 e 5. Entretanto vamos fazer algumas observações aqui para você ter uma ideia do que está acontecendo. O RelativeLayout é um gerenciador de layout que posi-ciona 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 na verdade estamos apontando para o @dimen. Vá até o diretório res/values/dimens.xml e verá a declaração desses valores. Esse é um espaçamento de margens recomendado pelos padrões de design do Android, e usar o arquivo dimens.xml nos permite colocar esse tipo de informação em um único local.

Page 13: Su Mario 9788575224472

43Capítulo 1 ■ Conceitos básicos

<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.

Executando a aplicaçãoPara executar a aplicação, conecte seu aparelho ao computador ou inicie o emu-lador. 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.

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

Page 14: Su Mario 9788575224472

Dominando o Android – 2ª edição44

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

Processo de compilaçãoApó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 é fei-to de uma forma um pouco diferente de uma aplicação Java convencional (para desktop ou web).

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

Page 15: Su Mario 9788575224472

45Capítulo 1 ■ Conceitos básicos

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.6

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

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 interessantes7 que você pode utilizar por meio da linha de comando:

adb devices

adb kill-server

adb start-server

adb install -r SuaApp.apk

adb shell pm uninstall –k pacote.da.app

adb push arquivo.jpg /mnt/sdcard

adb 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.

6 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 29.

7 Se estiver usando Mac OS X ou Linux, adicione o “./”

Page 16: Su Mario 9788575224472

Dominando o Android – 2ª edição46

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 documen-taçã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 recursosTodos os recursos de uma aplicação (strings, imagens, estilos, layouts etc.) devem obrigatoriamente estar na 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.

• mipmap – Ícone da aplicação.

• 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) e style (estilos).

• 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 nome-ados com todas as letras minúsculas (não é permitido nenhuma letra maiúscula) e não devem conter quaisquer símbolos (exceto underline “_”), mas podem conter 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,

Page 17: Su Mario 9788575224472

47Capítulo 1 ■ Conceitos básicos

adicionando sufixos a eles, e o Android se encarregará de obter o recurso mais adequado. A tabela 1.2 lista os principais sufixos em ordem de prioridade com alguns exemplos.

Tabela 1.2 – Sufixos para alocação de recursos

Configuração Exemplo do sufixo Recurso para

Operadoramcc724-mnc05

mcc724-mnc31Operadora do Brasil (mcc-724) e código 05 (Claro) e 31 (Oi)

Idioma

en

en-rUS

pt

pt-rBR

es

fr

de

Inglês (qualquer país) Inglês dos Estados Unidos Português (qualquer país) Português do Brasil Espanhol Francês Alemão

Tamanho de tela (ver tabela 1.5)

small

normal

large

xlarge

Telas pequenas Telas normais Telas grandes Telas extragrandes

Orientação de telaport

landPortrait (vertical) Landscape (horizontal)

Densidade da tela (ver tabela 1.3)

ldpi

mdpi

tvdpi

hdpi

xhdpi

xxhdpi

xxxhdpi

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)

API Level (ver tabela 0.1)

v10

v11

v14

Aparelhos com Android 2.3 ou superior Aparelhos com Android 3.0 ou superior Aparelhos com Android 4.0 ou superior

É importante ressaltar que podemos combinar os sufixos descritos anteriomente, como por exemplo layout-pt-rBR-large; values-mcc724-mnc31-v11 ou drawable-land-hdpi. Outro detalhe importante é 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. Abra o arquivo res/values/strings.xml e adicione o texto a seguir:

Page 18: Su Mario 9788575224472

Dominando o Android – 2ª edição48

<resources>

<string name="app_name">Hello</string>

<string name="hello_world">Hello World!</string>

</resources>

Agora vamos referenciar essa string no arquivo res/layout/activity_main.xml fazendo a seguinte modificação:

<RelativeLayout ...>

<TextView

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="@string/hello_world" />

</RelativeLayout>

A única mudança que fizemos foi adicionar a referência à string que acabamos de criar. Nunca devemos utilizar textos hard-coded; todos os textos da aplicação devem estar declarados no res/layout/strings.xml, pois isso facilita a internacionali-zação do seu aplicativo, ou seja, a tradução para outros idiomas.

Agora 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 Locale 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.

Page 19: Su Mario 9788575224472

49Capítulo 1 ■ Conceitos básicos

Figura 1.12 – Selecionando o idioma da pasta values.

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">Olá</string>

<string name="hello_world">Olá Mundo!</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 aparelho8

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 mipmap para nós:

res/mipmap-hdpi

res/mipmap-mdpi

res/mipmap-xhdpi

res/mipmap-xxhdpi

Isso fará com que o sistema operacional selecione o ícone da aplicação de acordo com a qualidade da tela, que é medida em DPIs (Dots Per Inch – Pontos por polegadas).

8 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.

Page 20: Su Mario 9788575224472

Dominando o Android – 2ª edição50

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.

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

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. En-tão é importante que tenhamos imagens para cada densidade de tela que iremos trabalhar, pois, caso contrário, elas podem aparecer distorcidas. Caso você queira que uma determinada imagem mantenha suas dimensões independentemente da densidade, podemos utilizar o sufixo –nodpi.

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 combi-nando ambas). A tabela 1.4 exibe alguns exemplos comuns de pastas de layout.

Tabela 1.4 – Exemplo de pastas de Layout

Pasta Propósito

res/layoutLayout em portrait ou landscape, independente do tamanho da tela

res/layout-port Layout em portrait independente do tamanho da tela

res/layout-large Layout em portrait ou landscape, para telas grandes

res/layout-xlarge-land Layout para telas extra grandes em landscape

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.

Page 21: Su Mario 9788575224472

51Capítulo 1 ■ Conceitos básicos

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)

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 acor-do com o aparelho por meio da classe android.content.res.Configuration ou da classe android.util.DisplayMetrics. Adicione o código a seguir no método onCreate(Bundle) da sua Activity.

Configuration configuration = getResources().getConfiguration();

DisplayMetrics metrics = getResources().getDisplayMetrics();

int orientation = configuration.orientation;

float density = metrics.density;

float height = metrics.heightPixels;

float width = metrics.widthPixels;

int mcc = configuration.mcc;

int mnc = configuration.mnc;

Locale locale = configuration.locale;

Log.d("NGVL", "density: "+ density);

Page 22: Su Mario 9788575224472

Dominando o Android – 2ª edição52

Log.d("NGVL", "orientation: "+ orientation);

Log.d("NGVL", "height: "+ height);

Log.d("NGVL", "width: "+ width);

Log.d("NGVL", "language: "+ locale.getLanguage() + "-" + locale.getCountry());

Log.d("NGVL", "mcc: "+ mcc);

Log.d("NGVL", "mnc: "+ mnc);

Se o código apresentar erro, é porque falta importar alguma classe. 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. O atributo density da classe Metrics traz a propor-ção da densidade da tela, como vimos na tabela 1.3. Já os atributos heightPixels e widthPixels trazem a largura e a altura da área útil da tela, ou seja, desconsiderando a barra de título e a barra com os botões de navegação. Com a classe Configuration obtemos o MCC e o MNC da operadora de telefonia que o aparelho está utili-zando. Por fim, com o objeto Locale conseguimos saber o idioma e o país que estão definidos nas configurações do aparelho. Mas o que faz o Log.d(String, String)?

Android Debug Monitor e LogcatO 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 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.

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.

Page 23: Su Mario 9788575224472

53Capítulo 1 ■ Conceitos básicos

Figura 1.13 – Android Debug Monitor.

O LogCat e a janela Devices estão disponíveis também dentro do Android Studio, basta acessar o menu View > Tool Windows > Android Monitor, conforme podemos ver na figura 1.14.

Figura 1.14 – Logcat dentro do Android Studio.

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.

Page 24: Su Mario 9788575224472

Dominando o Android – 2ª edição54

findViewById e evento de cliqueAgora 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 Activity

Package Name dominando.android.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"

android:id="@+id/button"

android:layout_below="@+id/editText"

android:layout_alignParentLeft="true"

android:layout_alignParentStart="true"/>

</RelativeLayout>

Page 25: Su Mario 9788575224472

55Capítulo 1 ■ Conceitos básicos

Note que na propriedade android:text usamos a @string/btn_toast, então adicione essa string ao res/values/strings.xml.

<resources>

...

<string name="btn_toast">Exibir toast</string>

</resources>

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.

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.

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

Page 26: Su Mario 9788575224472

Dominando o Android – 2ª edição56

componente ficará alinhado à esquerda do RelativeLayout. Agora deixe o código da Activity conforme a seguir9:

import android.os.Bundle;

import android.support.v7.app.AppCompatActivity;

import android.view.View;

import android.widget.Button;

import android.widget.EditText;

import android.widget.Toast;

public class MainActivity extends AppCompatActivity

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.

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

9 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.

Page 27: Su Mario 9788575224472

57Capítulo 1 ■ Conceitos básicos

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, conforme podemos observar na figura 1.16.

Figura 1.16 – Exibindo uma mensagem com um Toast.

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 View10 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;

}

}

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

Page 28: Su Mario 9788575224472

Dominando o Android – 2ª edição58

Debug no Android StudioÉ possível depurar aplicações Android adicionando breakpoints e clicando no botão “Debug ‘app’”, como mostra a figura 1.17. Os breakpoints, como o próprio nome diz, são pontos de parada que queremos adicionar ao nosso código para inspecionar a sua execução linha a linha.

Figura 1.17 – Adicionando breakpoints ao código da aplicação.

Quando o fluxo de execução da aplicação encontrar um breakpoint, a aplicação ficará suspensa, então poderemos visualizar as variáveis em memória por meio da janela Debugger, como mostra a figura 1.18. Pause o mouse sobre os botões dessa janela e você verá uma dica do seu funcionamento. Os principais são:

• Step Over – Executará a linha corrente e passará para a próxima.

• Step Into – Se a linha corrente for a chamada de um método, o fluxo de exe-cução mudará para a primeira linha desse método.

• Step Out – Se estiver em um método, o fluxo sairá desse método e voltará para o fluxo anterior.

• Evaluate expression – É possível avaliar um trecho de código em tempo de execução.

• Resume Program – Fará com que o fluxo de execução continue.

• Stop Program – Encerra a depuração da aplicação.

• View breakpoints – Podemos visualizar todos os breakpoints adicionados ao projeto.

Page 29: Su Mario 9788575224472

59Capítulo 1 ■ Conceitos básicos

Figura 1.18 – Janela de debug do Android Studio.

A partir de agora, quando algo der errado na sua aplicação, procure fazer a de-puração do seu código para analisar o que está acontecendo. Aconselho também usar essa abordagem para entender melhor o fluxo de execução dos exemplos que construiremos ao longo do livro.

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