Você está na página 1de 255

Mobile Android

Módulo básico
m éo
to
en
na e
ei u
tr O q

Android nativo e desenvolvimento com o uso de


recursos dos smartphones
m éo
to
en
na e
ei u
tr O q

Introdução ao paradigma mobile


m éo
to
en
na e
ei u
tr O q

Características do processo de desenvolvimento de apps


m oé
to
na nã
en
tr ue
o Oq
ei

Um treinamento de Java ou de web responsiva, e nem um


treinamento avançado
m oé
to
na nã
en
tr ue
o Oq
ei

666

Sobre aplicativos híbridos e ferramentas mágicas


geradoras de código
m oé
to
na nã
en
tr ue
o Oq
ei

Ficar na teoria* * Exceto no primeiro dia


m oé
to
na nã
en
tr ue
o Oq
ei

Consultoria para um único projeto


m oé
to
na nã
en
tr ue
o Oq
ei

UM LUGAR PRA WHATSAPP/MATCH EM TINDER!


Android
Android é o nome do sistema operacional (open
source) desenvolvido pelo Google.

É baseado no kernel do Linux e tem seu uso


primário em dispositivos móveis como smartphones
e tablets.

A primeira versão comercial estava disponível


apenas no celular HTC Dream em Outubro de 2008.

Cada versão lançada tem o nome de uma


sobremesa ou doce (a primeira letra segue a ordem
do alfabeto).

Fonte: Android History, 7 de novembro de 2016


Linha do tempo Fonte: Android History, 7 de novembro de 2016

23/09/2008 27/04/2009 15/09/2009 26/10/2009 20/05/2010 06/12/2010 22/02/2011

versão 1.0 versão 1.5 versão 1.6 versão 2.0-2.1 versão 2.2-2.2.3 versão 2.3-2.3.7 versão 3.0-3.2.6
Cupcake Donut Eclair Froyo Gingerbread Honeycomb
API 1 API 3 API 4 API 5-7 API 8 API 9-10 API 11-13

- Intents (incluindo - Suporte à - Live wallpapers - Contatos e contas - Mais melhorias na - Velocidade e - Interface
compartilhar) teclados - Dicionário mais - Mensagens SMS e câmera e galeria simplicidade da UI redesenhada
- Multitasking personalizados esperto MMS - Melhor - Entrada de texto - Novo teclado
- Serviços em - Widgets - Melhorias na performance mais intuitiva - Melhorias na
background - Previsão de câmera
- Múltiplas línguas - Selecionar com seleção, cópia e
entrada de texto - Teclado virtual
- Navegador para teclado virtual um toque e cola de textos
- Calendário - Digitação por voz copiar/colar - Novas opções de
- Bluetooth - Melhor consumo conectividade
bateria - Suporte à
- Sensores para processadores
jogos multicore
- NFC - Actionbar
- Consumo de persistente
bateria por app
Linha do tempo Fonte: Android History, 7 de novembro de 2016

18/10/2011 09/07/2012 31/10/2013 12/11/2014 05/10/2015 22/08/2016

versão 4.0-4.0.4 versão 4.1-4.3.1 versão 4.4-4.4.4 versão 5.0-5.1.1 versão 6.0-6.0.1 versão 7.0
Ice Cream Sandwich Jelly Bean Kit Kat Lollipop Marshmallow Nougat
API 14-15 API 16-18 API 19-20 API 21-22 API 23 API 24

- Refinamento da UI - Maior velocidade - Novas possibilidades - Material Design - Permissões em tempo - Notificações
(unificada para todos - OpenGL ES 3.0 NFC - Maior desempenho de execução melhoradas e
dispositivos) - > conectividade BT - Framework para - Notificações mais - Configuração de facilidades na UI
- Preview do app (em - Perfis restritos impressão visíveis, acessíveis e autobackup para apps - Troca rápida e
recentes) - Sensores e localização - Novo framework configuráveis - Mais ações ao multi-janelas
- Perfis otimizados armazenamento - OpenGL ES 3.1 selecionar um texto - Picture-in-Picture
- Novos recursos da - Suporte à interno - Maior conectividade - Melhor performance - Suporte à API Vulkan
câmera internacionalização - Impactos visuais - Câmera com captura do uso de bateria - Melhora no uso de
- Pastas na homescreen - Acessibilidade e (modo de tela cheia, RAW ou YUV - Melhor conversação bateria
- Auto sincronização de automação da UI nova área de - Perfil pessoal e de com seus apps - Mais rapidez na
favoritos - Maior segurança notificações) trabalho - USB Tipo C instalação de apps
- Notificações - Mais segurança, - Compartilhamento e - Direct Share - Atualização de apps
interativas acessibilidade e captura de tela durante utilização
internacionalização
Estatísticas
Gingerbread

Versão Codenome API Distribuição Nougat Ice Cream Sandwich

Marshmallow
Jelly Bean
2.2 Froyo 8 0,1%

2.3.3 10 1,3%
Gingerbread
2.3.7

4.0.3 15 1,3%
Ice Cream Sandwich
4.0.4

4.1.x 16 4,9%

4.2.x Jelly Bean 17 6,8%

4.3 18 2,0%

4.4 KitKat 19 25,2% KitKat

5.0 21 11,3% Lollipop


Lollipop
5.1 22 22,8%

6.0 Marshmallow 23 24,0%


Fonte: Dashboards, 7 de Novembro de 2016
7.0 Nougat 24 0,3%
Market Share
Período Android iOS Windows Phone Outros

2016Q2 87,6% 11,7% 0,4% 0,3%

2016Q1 83,4% 15,4% 0,8% 0,4%

2015Q4 79,6% 18,6% 1,2% 0,5%

2015Q3 84,3% 13,4% 1,8% 0,5%

2015Q1 78,8% 17,9% 2,5% 0,5%

2014Q1 80,8% 15,3% 2,7% 0,6%

2013Q1 74,4% 18,2% 2,9% 1,3%

2012Q1 56,9% 22,5% 1,9% 11,1%

Fonte: IDC, Agosto de 2016


Arquiteturas Mobile: Arquitetura Simples (off-line)
A maior parte dos dados são obtidos e
armazenados em um banco de dados local (e isto
se existir banco de dados no aplicativo).

Prós:
De simples implementação, não apresenta
problemas de conectividade ou preocupação com
implementação de estratégias de cache
avançadas.

Contras:
Para quaisquer atualizações de informações no
aplicativo é necessário lançar uma nova versão.
Arquiteturas Mobile
Arquitetura Online Distribuída
Parte das informações e recursos estão no
aplicativo, outra parte são obtidas de um servidor
ou sistema através de webservices.

Prós:
Versões do aplicativo em diferentes plataformas
obtém informações de um ponto em comum, mas
mantém boa usabilidade por conta do seu lado
nativo. Média complexidade de implementação.

Contras:
Depende de conexão com a Internet e não possui
uma estratégia de cache muito elaborada. Delays.

Obs: a arquitetura online também pode ser centralizada, com


características de web app.
Arquiteturas Mobile: Arquitetura Corporativa (Enterprise)
As informações são obtidas de um cache presente no aplicativo. O mecanismo de cache verifica
periodicamente se há necessidade de sincronização de dados com informações provenientes de
sistemas online.

O aplicativo compartilha camadas de integração com outros sistemas e concorre com outros clientes.

Prós:
Informação sempre disponível, independente de existir conexão com a Internet. A sincronização das
informações não é perceptível para o usuário.

Contras:
Alta complexidade de implementação.
Arquiteturas Mobile: Arquitetura Corporativa (Enterprise)
Mobile First

O que é?

Ao desenvolver, devemos pensar no desenvolvimento móvel/telas pequenas


primeiro, levando em conta o menor espaço disponível e os recursos limitados
de software e hardware.
Desafios da programação mobile

RAM limitada

Bateria Fragmentação
de dispositivos

Conexão de dados
intermitente, largura Baixo poder de
de banda pequena, processamento
alta latência
O Processo de Projeto de Desenvolvimento Mobile

Escopo, Conceito e Planejamento


Contexto: Onde o produto será utilizado?

Persona: Quem é o usuário alvo?

Pesquisa de campo e entrevistas contextuais

Visão: Como o produto será utilizado?

Orçamento: Quanto tempo e dinheiro você pretende gastar no projeto e


desenvolvimento?
O Processo de Projeto de Desenvolvimento Mobile

Workshop de Projeto
- Foco em estabelecer um entendimento compartilhado por todo time do que
é o produto
- Cenários e storyboards

Prototipação
- Wireframes com post-its
- Entender fluxo das informações (Diagrama da Arquitetura da Informação)
- Testar esta navegação junto ao cliente (ex. POP app)
O Processo de Projeto de Desenvolvimento Mobile

Projeto Visual
- Protótipo de alta fidelidade (é necessário?)

- Guidelines
- Android Design
- iOS Human Interface Guidelines

- Mobile UX
O Processo de Projeto de Desenvolvimento Mobile

Desenvolvimento, Validação e Publicação


- Arquitetura (Simples, Online e Enterprise)

- Criação de recursos

- Implementação com o uso de design patterns

- Testes e homologação
- Como disponibilizar?
- Testes de usabilidade

- Publicação
UX
Experiência do Usuário, do inglês user experience (UX), é definida pela norma
ISO 9241-210 como:

"as percepções e reações de uma pessoa que resultam do uso ou


utilização prevista de um produto"

De acordo com a definição da ISO, experiência do usuário inclui todas as


emoções, crenças, preferências, percepções, respostas físicas e psicológicas,
comportamentos e realizações do usuário que ocorrem antes e após o uso.
UX é um termo "Guarda-chuva"
á rio
U su
o
c iad
n
eriê
E xp

Estratégia de
Conteúdo
Pesquisa com o
Usuário
Usabilidade

Design da
Interação
Arquitetura da
Design Informação
Visual
Mobile UX - Por quê é importante?
- A experiência importa mais para o usuário pois o dispositivo
móvel é mais importante pra ele (do que um PC)

- Os usuários mobile não pretendem ler um manual de


instruções antes de sair utilizando um app

- 25% dos usuários só abrem o app uma vez, depois nunca


mais; e 60% dos usuários que deixam de abrir o app em 7
dias, nunca mais voltam pra ele

- Notificações push podem gerar engajamento, mas seu


excesso geram desinstalação do app

- Contexto de uso do aplicativo


Os 7 maiores motivos pelos quais as pessoas desinstalam um aplicativo

Uso forçado de logins sociais 19%


Preocupação com privacidade 23%

Publicidade Intrusiva 29%

UX / UI Ruim 42%

Travamentos 48%

Registro Complexo Exigível 68%


➔ Como % entre todos os
participantes
Notificações Irritantes 71% ➔ Cada participante mencionou
3 motivos
fonte: Appiterate
Personas
1 2
Uma persona é um personagem fictício,
modelo hipotético de um grupo de usuários
Dados
reais, criada para descrever um usuário típico. Demográficos
Sketch
Nome
Slogan (opcional)
Proto-persona é o "protótipo" de uma
persona: a medida que o projeto/pesquisa 4
3
avança, essas personas podem e devem ser
atualizadas, validando ou invalidando as
Dados Necessidades e
hipóteses iniciais. Comportamentais Objetivos
Personas

- identidade: nome, sobrenome, idade, foto, etc.


- status: primária, secundária, outro stakeholder
- objetivos: quais são os objetivos desta persona?
- habilidades: qual é a especialidade desta persona? Isso inclui educação,
treinamento e competências específicas.
- tarefas: em linhas gerais, quais são as tarefas básicas ou críticas que a
persona realiza? Qual a frequência, importância e duração destas tarefas?
- relacionamentos: com quem a persona se relaciona?
- requisitos: de que a persona precisa?
- expectativas: como a persona acredita que o produto funciona? Como ela
organiza as informações no seu domínio ou trabalho?
Prototipação

Objetivo
- Horizontal: exibe a interface como um todo, podendo ser mais genérica
- Vertical: exibe uma parte da interface, com maior detalhamento

Fidelidade
- Alta Fidelidade: maior proximidade com a interface final do sistema
- Baixa Fidelidade: envolve materiais que não se assemelham com a
interface do sistema
Prototipação - Técnicas

Prototipação em papel
- Feita com poucos recursos, junto ao
cliente ou com o time para validar ideias
e interface

- Podem compor um Diagrama da


Arquitetura da Informação (DAI) para
documentar o fluxo dinamicamente

Fonte: The $1 Prototype


Prototipação - Técnicas

DAI (exemplo)
Prototipação - Técnicas

Sketch
- Técnica de mais baixa fidelidade. Ideação.

- Pode ser feito com papel ou com o uso de


ferramentas (ex. Balsamiq)
Prototipação - Técnicas

Wireframe
- Apresenta a estrutura e conteúdo da interface. Os
elementos são representados por variações similares.

- Baixa a média fidelidade. Detalhamento.

- Pode ser feito com papel ou com o uso de ferramentas


(ex. Balsamiq, Axure RP)
Prototipação - Técnicas

Mockup (ou mock-up)


- O mockup possui elementos de interface
como botões e menus entre outros
objetos. É funcional e é possível interagir
com a sua interface.

- Técnica de mais alta fidelidade.


Visualização.

- Pode ser feito com o uso de ferramentas


de prototipação profissionais ou com
linguagens de programação (ex. Axure
RP, Just in Mind)
MVP
Minimum Viable Product é a versão mais simples de um produto que pode ser
lançada com uma quantidade mínima de esforço e tempo de desenvolvimento.

Tem três características como principais:

- tem valor suficiente para que as pessoas comecem a utilizá-lo


- demonstra benefícios suficientes para reter os usuários iniciais
- fornece um ciclo de feedback para orientar o desenvolvimento futuro

Não é necessariamente o menor produto imaginável


MVP

Desejável Desejável
MVP é isto!
Utilizável Utilizável

Confiável Confiável

Funcional Funcional

MVP não é isto!


MVP

1 ano 2 anos
Design Patterns e Anti-patterns
Design Pattern (Padrão de Projeto) é uma solução geral reutilizável para um
problema que ocorre com frequência dentro de um determinado contexto no
projeto de software.

→ No desenvolvimento mobile, os design patterns são bastante frequentes na


camada de interface.
→ Na camada de negócios e persistência, grande parte dos padrões
conhecidos são aplicáveis.

Anti-pattern é uma solução para um problema frequentemente usada mas


altamente ineficiente.

Para mais informações consulte o apêndice: Patterns e Anti-patterns


Prontos para criar o
primeiro projeto?
Antes, vamos conhecer e
preparar o ambiente para o
desenvolvimento
Ambiente de desenvolvimento
Composto do Android SDK e Android Studio (IDE).

As ferramentas podem ser instaladas em Linux, Windows e OSx e são


encontradas no endereço http://developer.android.com/

A versão 32 bits está aos poucos sendo depreciada.

Na primeira execução da IDE é exibido um wizard para configuração do


ambiente, incluindo o download do Android SDK, mas a instalação pode ser feita
previamente e informada no wizard.
Configuração do ambiente no SERPRO
1. Crie uma pasta e lembre dela (será referenciada na configuração do .bashrc/.profile)
2. Baixar o Android Studio (clique no botão GET ANDROID STUDIO) e descompactar na pasta criada
3. Baixar o Java JDK e descompactar na pasta criada
4. Configurar o ambiente (ver snippet)
5. Para executar, vá na pasta /bin do Android Studio extraído (descompactado), execute o arquivo
studio.sh
6. O wizard irá baixar o Android SDK
7. Ao baixar o SDK, o arquivo ADB e FastBoot devem ser substituídos (por versões 32bits), baixe este arquivo
e descompacte em sua pasta <sdk>/platform-tools sobrescrevendo os arquivos

OPCIONAL

1. Instalar o git (sudo apt-get install git)


2. Se houver problemas com o certificado do Serpro, utilizar o comando git config --global
http.sslverify false
Opções do desenvolvedor

Através das opções do desenvolvedor é possível


habilitar a depuração por USB, além de verificar
estouros de GPU e outras propriedades escondidas
por padrão.

Acima da versão 4.2, a opção está escondida e


para habilitar é necessário ir em Configurações >
Sobre o telefone e tocar 7x sobre o Número da
versão.

Não esqueça de ativar a Depuração de USB dentro


da Configurações > Opções do desenvolvedor
Git
Git é um sistema de versionamento (em linha de comando) que está muito bem
integrado ao Android Studio.

Devemos instalar primeiramente o Git utilizando o comando sudo apt-get


install git (em sistemas Linux) ou baixando através do site oficial e
instalando com o Wizard, isso para sistemas Windows.

Depois, configurar na IDE em File > Settings > Version Control > Git e
verificar que o Path to Git executable esteja correto (clique em Test).

Adicionalmente, instalar o plugin em File > Settings > Plugins indo na opção
Browse repositories… e instalando o plugin .ignore.

Veja como utilizar o GIT de forma fácil clicando aqui.


Git - Fluxo básico

commit push

workspace repo local repo remoto

pull fetch
Ufa!
Agora vamos
criar nosso
projeto
Criando um novo projeto com Android Studio
Ao abrir o Android Studio pela primeira vez, vemos algumas opções, entre estas
temos Start a new Android Studio Project

Configuração
Application name > Como o nome diz, é o nome da sua aplicação (ex:
Facebook, Gmail, Instagram), no nosso caso Android Básico

Company Domain > É o domínio da sua empresa, no nosso caso serpro.gov.br

Package name > gerado a partir do domínio e nome da aplicação (também é


possível editar)

Project location > pasta de destino que conterá os fontes e recursos da


aplicação
Minimum, target e compile SDK versions

Minimum SDK significa qual a cobertura do seu aplicativo, sempre considerar as


informações do Dashboards.

Target SDK significa qual versão você dará suporte (geralmente se escolhe a
última versão estável disponível).

Compile SDK é a versão que será utilizada para compilar o aplicativo, sendo
altamente recomendado compilar com a última versão disponível.

minSdkVersion <= targetSdkVersion = compileSdkVersion


(menor possível) (última SDK disponível)
Criando um novo projeto com Android Studio
A tela seguinte exibe diversos templates, vamos começar com Empty Activity.

Activity name > É o nome da nossa primeira Activity, pode ser renomeada
(refatorada) posteriormente

Generate Layout File > Ao marcar a opção (default), um arquivo de layout


será criado e associado para a Activity gerada

Layout name > Se a opção Generate Layout File estiver marcada, o nome do
layout gerado e que será associado à Activity deve ser informado aqui,
também pode ser renomeado posteriormente

Clique em Finish e o projeto será criado.


Interface do Android Studio barra de
navegação

barra de
ferramentas
janela de
edição

janelas de
ferramentas

monitores
e logcat
barra de
status
Processo de compilação

Gradle
Gradle Byte code
ADB
Projeto Instalar no
Build Resources Sign
Android dispositivo
Manifest
APK
Android Debug Bridge - ADB
O ADB é uma ferramenta da linha de comando que permite a conexão com
emuladores ou dispositivos conectados.

É composto de três componentes: cliente, servidor e daemon (que roda no


dispositivo ou emulador).

A ferramenta ADB se encontra em <sdk>/platform-tools/

daemon
cliente e servidor
Fonte: Android Debug Bridge | Android Developers
Android Debug Bridge - ADB
Comandos úteis
adb devices > Exibe a lista de dispositivos conectados e com permissão
autorizada

adb kill-server > Para o servidor

adb start-server > Inicia o servidor

adb install -r <app>/build/apk/app-debug-unaligned.apk > Instala a


aplicação no dispositivo

adb shell am.start -n br.gov.serpro.<app>.MainActivity > Inicia a


aplicação previamente instalada
Estrutura do projeto DICA
Você pode trocar a forma de
exibição através destes botões
Um módulo Android é composto dos seguintes
itens:

manifests > Contém o arquivo


AndroidManifest.xml

java > Contém todo o código fonte Java,


separado por nomes de pacotes, incluindo os
códigos de teste JUnit

res > Contém todos os recursos (não código),


como layouts XML, strings e imagens bitmap,
divididos em sub-diretórios
Estrutura do projeto - Manifests

Activity (Tela onde o usuário


pode interagir)

Package name, min-sdk, Services (Operações de


longa execução em segundo
permissões, etc plano, sem UI)

AndroidManifest.xml

Content Provider (Fornece


Intent (Abstração/mensagem
uma interface para armazenar
descrevendo a operação a ser
e recuperar dados persistentes
realizada)
no app por outras aplicações)
Broadcast Receiver (Usado
para “ouvir”
mensagens/eventos do
sistema Android)
Estrutura do projeto - Código-fonte (java)
Pasta /src (visão Project Files no Android Studio)

Como em um projeto Java, contém todos os pacotes e código Java da aplicação,


além dos códigos de teste.

Ao navegar na pasta, a estrutura é exibida desta maneira:

Pastas estrutura

/src
/main
/java
/res
/androidTest
Estrutura do projeto - Resources
Pasta /res contendo as subpastas:

/anim
arquivos xml que são compilados em objetos animados

/color
arquivos xml que descrevem cores

/drawable
pastas de imagens (PNG, JPG ou GIF), arquivos de imagem 9-patch, e
arquivos xml que descrevem formas ou objetos que contém múltiplos estados
(normal, pressed ou focused) separados por densidades
Estrutura do projeto - Resources
Pasta /res contendo as subpastas:

/mipmap
ícones da aplicação (também separados por densidades)

/layout
arquivos xml que representam parte ou totalidade de uma tela

/menu
arquivos xml que definem menus da aplicação
Estrutura do projeto - Resources
Pasta /res contendo as subpastas:

/raw
arquivos brutos da aplicação, o mesmo que salvar na pasta assets mas com a
forma diferente de acesso na aplicação (uso de R.)

/values
arquivos xml que definem recursos por tipo de elemento XML

/xml
arquivos xml que configuram componentes da aplicação
Estrutura do projeto - Scripts Gradle
Gradle é um sistema de construção automatizado e muito bem integrado com o
Android Studio, através de scripts de linguagem simples

Código layout geral de um arquivo .gradle

apply plugin: 'com.android.application'

android {

compileSdkVersion 23
buildToolsVersion "23.0.3"
defaultConfig { ... } // base para todos os flavors
signingConfigs { ... } // antes de buildTypes para os buildTypes "enxergar"
buildTypes { ... }
productFlavors { ... } // suporta as mesmas propriedades de buildTypes (sobreescreve)

dependencies { … } // todas as libs da sua aplicação


Gradle
Flavors são diferentes builds que podem ser construídas com mínimas alterações

Código diferentes flavors

productFlavors {

free {
buildConfigField "boolean", "IS_PRO", "false"
}

pro {
buildConfigField "boolean", "IS_PRO", "true"
}
}

Para acessar esse atributo em sua aplicação,


utiliza-se BuildConfig.IS_PRO
PRONTO!
Já sei como criar um
projeto, conheço a
estrutura e sei
compilar e executar
no dispositivo e no
emulador.
FIM DO CURSO!
Application
Código exemplo de AndroidManifest.xml
Classe base que mantém o estado da
<?xml version="1.0" encoding="utf-8"?>
aplicação. Possui seu ciclo de vida. <manifest
xmlns:android="http://schemas.android.com/apk/res/android"
Você pode criar a sua própria package="br.gov.serpro.androidbasico">
<application
implementação criando uma android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
subclasse e especificando o seu nome android:label="@string/app_name"
qualificado no atributo android:name android:supportsRtl="true"
android:theme="@style/AppTheme">
da tag <application> no arquivo <activity android:name=".MainActivity">
<intent-filter>
AndroidManifest.xml. <action android:name="android.intent.action.MAIN" />
<category
Todas as Activities que criar devem android:name="android.intent.category.LAUNCHER" />
</intent-filter>
ser declaradas dentro da tag </activity>
</application>
<application>. </manifest>
Activity
Activity é a representação de uma tela com interação do usuário.

Toda tela possui uma UI associada (layout inflado), e essa UI pode conter views
(componentes e outros layouts), menus, caixas de diálogo.

Também pode navegar para outra Activity (ou outras), o que significa abrir
uma nova tela.

Uma Application precisa de ao menos uma activity e estas devem estar


declaradas no manifest.
ANALOGIA
Toda Activity possui seu ciclo de vida.
Um website possui várias páginas
Um app possui várias activities
Ciclo de vida da Activity Fonte: Android activities & views

Fundo Frente

Activity ATIVA (running)


- Visível, em foco, activity em primeiro plano que pode receber input do usuário
- No topo da pilha
- Se mantém viva a qualquer custo!
- Se não houver recursos necessários para esta activity, outras activities serão
destruídas
Ciclo de vida da Activity Fonte: Android activities & views

Fundo Frente

Activity PAUSADA (paused)


- Visível mas não em foco
- Este estado é alcançável se uma activity transparente ou uma activity não tela cheia
está ativa em frente à esta
- Tratada como ativa, mas sem interação com o usuário
Ciclo de vida da Activity Fonte: Android activities & views

Fundo Frente

Activity PARADA (stopped)


- Não visível
- Permanece em memória, mantendo toda as informações do estado
- É candidata para terminar quando o sistema requer memória
Ciclo de vida da Activity Fonte: Android activities & views

Fundo Frente

Activity INATIVA (destroyed)


- Removida da pilha de Activity
- Precisa ser reiniciada antes de ser exibida e utilizada
Ciclo de vida da Activity

Fonte: Android Developers


Ciclo de vida da Activity Fonte: Android activities & views

Diferenças em apertar HOME e BACK

Pressionar HOME: A Activity que está


em primeiro plano NÃO é destruída
Operações: onPause() - onStop()

Pressionar BACK: A Activity é destruída


Operações: onPause() - onStop() - onDestroy()

Nota: o comportamento no emulador pode variar


Ciclo de vida da Activity
ATENÇÃO!

A Activity é destruída e recriada cada vez que o usuário girar a tela ou a tela é
redimensionada (ex: quando exibe o teclado).

Quando a tela altera a orientação, o sistema destrói e recria a atividade porque


pode ser necessário carregar recursos alternativos (como o layout).

Para resolver, há algumas formas como neste link ou utilizando um atributo na


Activity de seu AndroidManifest:

android:configChanges="orientation|screenSize"

Confira mais sobre o atributo configChanges clicando aqui e aqui.


Fragment
Um Fragment representa o comportamento ou uma parte da interface do
usuário em uma Activity.

É possível combinar vários Fragments em uma única atividade para compilar


uma UI de painéis múltiplos e reutilizar um fragmento em diversas atividades.

Um Fragment é como uma seção modular de uma atividade, que tem o próprio
ciclo de vida, recebe os próprios eventos de entrada e que pode ser adicionado
ou removido com a atividade em execução (uma espécie de "sub-atividade" que
pode ser reutilizada em diferentes atividades).

Activities podem conter zero ou mais fragments.


Fragment
Ciclo de vida do Fragment
Logs (android.util.Log)
Deve-se evitar spam de logs.
Uma convenção é declarar uma constante TAG em sua classe:

public final String TAG = "NOME";

Níveis de log:
Log.e(TAG, “error”) sempre capturado e útil quando algo ruim acontece
Log.w(TAG, “warning”) sempre capturado e útil quando algo que você não espera acontece
Log.i(TAG, “info”) sempre capturado e útil para resultados de operações
Log.d(TAG, “debug”) apenas em modo de depuração e útil para variáveis
Log.v(TAG, “verbose”) sempre capturado e exibido e não utilizar em versão de produção

Para ver o log, utilize o comando: adb logcat


? ?
? ?
Minha primeira
? ? app está muito
simples, o que
mais eu consigo
fazer?
View(android.view.View)
É um contêiner, com largura (width) e altura
(height) definidas que é exibida na tela do View (tipo
TextView)
dispositivo.
Texto
Cada tipo de View possui um conteúdo que será Conteúdo
desenhado e que consegue lidar com eventos do
usuário (toque, segurar…).
View (tipo
ImageView)
O conteúdo de cada contêiner pode ser
posicionado através do atributo gravity, sendo Conteúdo
que esse conteúdo pode ser menor que o
contêiner.

Existem atributos de margin e padding para


ajustar a View em relação aonde está contida
(parent).
View(android.view.View) SurfaceView VideoView

ImageView
Existem diversas Views e o desenvolvedor pode
usar ou criar views personalizadas
Space
(extendendo).
EditText
TextView
Uma ViewGroup é uma View especializada, View Button
sendo sua definição: um contêiner invisível que
ProgressBar
consegue organizar filhos Views. GridLayout

Ao lado estão apenas alguns exemplos de FrameLayout

Views, sendo as mais comuns mostradas neste


ViewGroup RelativeLayout
curso.
LinearLayout

RecyclerView
Componentes UI Componentes não podem conter outros componentes dentro.

Atributos úteis
View > É um retângulo plano. layout_width > largura, medida em dp ou utilizando o
máximo possível do pai ao qual está inserido
(match_parent) ou o mínimo possível do conteúdo interno
Código View (wrap_content)
<View
android:layout_width="match_parent"
layout_height > altura, com as mesmas possibilidades da
android:layout_height="100dp" largura
android:background="#FFA000"
android:visibility="visible" background > informa qual o tipo de drawable que será
android:id="@+id/view_amarela" />
exibido como fonte do ImageView

visibility > define a visibilidade, se visible, invisible


Resultado View
(mantém o espaço reservado) ou gone (some com o objeto
e também com a espaço informado na largura e altura)

id > define que esse componente/objeto é único no layout


(não necessariamente único em TODOS layouts)
O que é id?
Quando o aplicativo é compilado, aapt* gera a classe R, que contém IDs de
recursos para todos os recursos no diretório res/. Para cada tipo de recurso, há
uma subclasse R (por exemplo, R.drawable para todos os recursos desenháveis)
e, para cada recurso daquele tipo, há um número inteiro estático (por exemplo,
R.drawable.icon).
Esse número inteiro é o ID do recurso que pode ser usado para recuperá-lo.

*Aapt (Android Asset Packaging Tool) permite visualizar, criar e atualizar arquivos Zip-compatíveis (zip,
jar, apk). Também permite compilar recursos em binários. É a base de construção para aplicações
Android.
Como acessar um recurso pelo id?

Código Java
Usando um número inteiro estático de uma subclasse de sua classe R, como:

R.string.nome_app > string é o tipo de recurso e nome_app é o nome do


recurso. Há muitas APIs do Android que podem acessar os seus recursos
quando você fornece um ID de recurso nesse formato.
Como acessar um recurso pelo id?

No XML
Usando uma sintaxe XML especial que também corresponde ao ID de recurso
definido em sua classe R, como:

@string/nome_app > string é o tipo de recurso e nome_app é o nome do


recurso. Você pode usar essa sintaxe em um recurso XML em qualquer lugar
em que um valor é esperado e que seja fornecido em um recurso.
Qual a diferença entre @+id e @id?

@+id/nome > serve para associar um nome ao componente, ele cria uma entrada
na classe R.

@id/nome > apenas identifica/faz referência ao componente, como por exemplo


num RelativeLayout quando se quer indicar a posição de um componente em
relação a outro.

@id/nome > só pode ser utilizado após a utilização de @+id/nome


findViewById(id_do_recurso)
Criar um componente/layout (View e ViewGroup) no XML já estamos
aprendendo, mas e se queremos manipular esse objeto em nosso código?
Para isso utilizamos um método que existe tanto em Activity, quanto em View
que é o findViewById(id_do_recurso).
Este método nos retorna um objeto do tipo View que nos permite trabalhar
interações com o usuário e alterações em atributos.

Código obtenção de View através do método Activity.findViewById(...)

TextView textViewNavegarExemploFrameLayout = (TextView) findViewById(R.id.navegar_para_exemplo_framelayout);

Cast para o tipo utilizado no XML


Componentes UI Componentes não podem conter outros componentes dentro.

Atributos úteis
Button > Botão com label de texto onClick > informe um método em sua Activity que
responderá à um clique no botão. Esse método deve
ter a seguinte assinatura public void
nomeDoMetodo(View view) {}

Código Button

<Button
android:id="@+id/button" Resultado Button
android:layout_gravity="center_horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Clique aqui" />
Componentes UI Componentes não podem conter outros componentes dentro.

Button > Botão com label de texto e imagem (utilizar drawable como atributo e em qual posição)

Código Button com imagem (drawable)

<Button
Resultado Button com drawable
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:drawableLeft="@android:drawable/ic_delete"
android:text="Não clique aqui" />

ImageButton > Botão com label de texto ou imagem


Código ImageButton

<ImageButton Resultado ImageButton


android:id="@+id/button"
android:layout_gravity="center_horizontal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@android:drawable/ic_delete" />
Componentes UI Componentes não podem conter outros componentes dentro.

Atributos úteis
TextView > Exibe um texto, inclusive podendo text > O texto que será exibido
exibir conteúdo HTML (diretamente de arquivo de
recursos ou programaticamente) lines > Faz o TextView ser exatamente da altura das
linhas informadas
Código TextView
ellipsize > Quando informado, quebra o texto até
<TextView o tamanho máximo da view
android:id="@+id/text_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
textSize > O tamanho da fonte, usado com a
android:gravity="center_horizontal" medida sp
android:text="Curso Android\nMódulo Básico"
android:textAppearance="?android:textAppearanceLarge" textColor > A cor da fonte, em HEXA ou recurso
android:textColor="#FBC02D"
android:textStyle="bold" />
textStyle > O estilo do texto (negrito, itálico...)

Resultado fontFamily > A família de fonte a ser utilizada

style > Estilo para facilitar a aparência da fonte


Componentes UI Componentes não podem conter outros componentes dentro.

Atributos úteis
hint > Texto que é exibido de dica quando o campo
EditText > É um campo de texto que você está vazio
pode digitar
inputType > Tipo de dado que será permitido ao
usuário informar, pode trabalhar com múltiplos tipos
ao utilizar PIPE | (exemplo: textMultiLine|number)

Código EditText

<EditText Resultado EditText


android:id="@+id/album_description_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Endereço"
android:inputType="textMultiLine" />
Componentes UI Componentes não podem conter outros componentes dentro.

ImageView > Exibe imagens de diferentes Atributos úteis


scaleType > Opções de escala dos limites de uma
fontes (como recursos ou content providers) e
imagem para os limites dessa view
provê diversas opções como escala e pintura
(tinting) src > Informa qual o tipo de drawable que será
exibido como fonte do ImageView

Código ImageView

<ImageView Resultado
android:id="@+id/image_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:scaleType="centerCrop"
android:src="@drawable/logo_serpro" />
AH! É só
colocar as
imagens na
pasta RES,
não é?
Resolução de tela
Existem milhares de novos aparelhos sendo lançados por ano e cada aparelho
possui um tipo de resolução de tela (e tamanho de tela, em polegadas).

Para facilitar o agrupamento de tantos modelos, foram criados 4 tipos de grupos


de tamanhos (baseados apenas na resolução de tela):

xlarge resolução de pelo menos 960dp x 720dp


large resolução de pelo menos 640dp x 480dp
normal resolução de pelo menos 470dp x 320dp
small resolução de pelo menos 426dp x 320dp
Densidade de pixels
É o número de pixels que cabem em uma polegada (dpi - dots per inch, pontos por
polegada).

Scaleable Pixels (sp) tem a mesma função do que dp, só que para fontes.

Telas de alta densidade possuem mais pixels por polegada do que telas de baixa
densidade.

Isso resulta em componentes de UI (como Buttons) fisicamente maiores em telas de baixa


densidade do que alta densidade.

Clique aqui e calcule o dpi ou utilize a fórmula:

Como converter: px = dp * (dpi / 160)


Densidade de pixels
Para simplificar, existem 6 grupos de densidades de tela:

Nome amigável dpi Escala Tamanho da imagem (em


pixels)

xxxhdpi (extra-extra-extra-high) 640 4.0 400 x 400

xxhdpi (extra-extra-high) 480 3.0 300 x 300

xhdpi (extra-high) 320 2.0 200 x 200

hdpi (high) 240 1.5 150 x 150

mdpi (medium) 160 1.0 100 x 100

ldpi (low) 120 0.75 75 x 75

mdpi é a densidade base


Densidades e pastas
Certo, mas e para que serve saber de tudo isso?
Como temos problemas de limitação de hardware, o Android utiliza a melhor
imagem disponível (mais otimizada para seu celular, usando a densidade da tela)
para exibição. Isso permite que tenha ganho de performance (carregar imagens
de tamanhos desnecessários é lento e custoso) além de permitir que seu layout
tenha o mesmo aspecto em diferentes resoluções.
Densidades e pastas
E como podemos fazer?
Cada pasta /res/drawable-<densidade> existe
com um único propósito, carregar a imagem
correta para o
dispositivo correto.

Se não houver recurso do tamanho


correto, o sistema utiliza o recurso da próxima
escala menor disponível.
Componentes UI Componentes não podem conter outros componentes dentro.

CheckBox > Permite ao usuário selecionar uma ou Atributos úteis


mais opções em um conjunto. checked > Põe um valor padrão de
Deve ser registrado um click listener para cada marcado/desmarcado
CheckBox.

Código Checkbox

<CheckBox
android:id="@+id/checkbox"
android:layout_width="wrap_content" Resultado Checkbox
android:layout_height="wrap_content"
android:text="Aceito receber spam"
android:textAppearance="?android:textAppearanceMedium" />
Componentes UI Componentes não podem conter outros componentes dentro.

Atributos úteis
Switch > Interruptor ligado/desligado que pode switchPadding > Espaço mínimo entre o
ser deslizado ou apenas tocado para troca de Switch e o texto
estado.
switchMinWidth > Largura mínima

switchTextAppearance > Estilo do texto

Código Switch

<Switch
android:id="@+id/backup_switch" Resultado Switch
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="true"
android:text="Fazer backup de arquivos inúteis"
android:textAppearance="?android:textAppearanceSmall" />
Componentes UI Componentes não podem conter outros componentes dentro.

Spinner Atributos úteis


Clique nele para exibir uma lista (dropdown) de entries > informa valores pré-determinados
opções através de um array de Strings (utilize o
arquivo de recursos strings

Código Spinner

<Spinner Resultado Spinner


android:id="@+id/spinner"
android:layout_width="match_parent"
android:layout_height="wrap_content" />

Para popular um spinner, é necessário um adapter.


Componentes UI Componentes não podem conter outros componentes dentro.

SeekBar Atributos úteis


Exibe progresso e permite ao usuário arrastar o max > informa o valor máximo (número inteiro)
controle em qualquer local da barra.
progress > informa o progresso padrão
(número inteiro entre 0 e o máximo)

Código SeekBar
Resultado SeekBar
<SeekBar
android:id="@+id/seek_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:max="100"
android:progress="20" />
Componentes UI Componentes não podem conter outros componentes dentro.

ProgressBar Atributos úteis


max > informa o valor máximo (número inteiro)
Indicador de progresso horizontal
progress > informa o progresso padrão
(número inteiro entre 0 e o máximo)
Código ProgressBar horizontal

<ProgressBar indeterminate> se habilitado a barra de


android:id="@+id/progress_bar" progresso tem animação infinita
style="@style/Widget.AppCompat.ProgressBar.Horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:indeterminate="false"
android:max="100"
android:progress="40" />

Resultado ProgressBar horizontal


Componentes UI Componentes não podem conter outros componentes dentro.

RadioButton
Permite ao usuário selecionar apenas um item em
um grupo de RadioButtons.

Código RadioButton

<RadioGroup
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
<RadioButton
android:layout_width="wrap_content" Resultado RadioButton
android:layout_height="wrap_content"
android:text="Com certeza"
android:textAppearance="?android:textAppearanceMedium" />
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="NUNCA!"
android:textAppearance="?android:textAppearanceMedium" />
</RadioGroup>
Componentes UI Componentes não podem conter outros componentes dentro.

RatingBar Atributos úteis


É uma extensão de SeekBar e ProgressBar que numStars > informa o número de estrelas para
mostra a classificação por estrelas. Os estilos exibir na tela
ratingBarStyleSmall e ratingBarStyleIndicator
não possuem interação, apenas indicam classificação. stepSize > informa o valor mínimo de
diferença entre avaliações (pode ser float)

rating > informa a avaliação padrão (número


pode ser float se definido no stepSize)
Código RatingBar

<RatingBar
android:id="@+id/rating_bar"
style="?android:attr/ratingBarStyle"
android:layout_width="wrap_content" Resultado RatingBar
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:numStars="5"
android:rating="3.5"
android:stepSize="0.5" />
Componentes UI Componentes não podem conter outros componentes dentro.

FloatingActionButton Atributos úteis


É uma extensão de ImageButton que foi introduzido no src > informa o drawable que servirá como
android com o Material Design. ícone no FAB

Utilizado para promover a ação principal de um Tamanhos


determinado aplicativo ou funcionalidade. Padrão: 56 x 56dp
Mini: 40 x 40dp
Esse é um componente novo que não existe em todas as
APIs, para isso, utilize a versão de suporte, como o
exemplo abaixo (não esqueça da dependência).
Código FloatingActionButton
Resultado FloatActionButton
<android.support.design.widget.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_margin="16db"
android:src="@drawable/ic_compose" />
Componentes UI Componentes não podem conter outros componentes dentro.

SearchView
Campo de busca que ao informar o termo (ou termos) exibe uma lista que permite clicar em um item ou
resultado.

Código SearchView Resultado SearchView

<SearchView
android:id="@+id/search_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:iconifiedByDefault="false"
android:queryHint="Nome do legume" />

SearchView não será estudado neste curso.

Confira alguns patterns importantes clicando aqui!


Ok, já entendi como
colocar componentes,
mas só
consigo
fazer isso?
Layouts
Define a estrutura visual para uma interface do usuário, como a UI de uma Activity ou de
um widget. É possível declarar um layout de dois modos:

● Declarar elementos da IU em XML. O Android fornece um vocabulário XML direto que


corresponde às classes e subclasses de View, como as de widgets e layouts.
● Instanciar elementos do layout em tempo de execução. o aplicativo pode criar objetos
View e ViewGroup (e processar suas propriedades) programaticamente.

A vantagem de declarar a IU em XML é separar melhor a apresentação do aplicativo do


código que controla seu comportamento. As descrições da IU são externas ao código do
aplicativo, ou seja, é possível modificá-las ou adaptá-las sem modificar o código-fonte e
recompilar. Por exemplo, é possível criar layouts XML para diferentes orientações de tela,
diferentes tamanhos de tela de dispositivos e diferentes idiomas. Além disso, a declaração
de layout em XML facilita a exibição da estrutura da sua IU, o que facilita a depuração de
problemas. Assim sendo, este documento se concentrará em ensinar a declarar o layout
em XML.
Layouts
Como carregar um recurso XML?
Ao compilar o aplicativo, cada arquivo de layout XML é compilado em um recurso
View.

O carregamento de um recurso de layout tem o nome de inflate (inflar), e a


forma de inflar uma view é diferente para:

● Activity > no método onCreate utilizamos o método


setContentView(R.layout.nome);
● Fragment > no método onCreateView utilizamos o método
inflater.inflate(R.layout.nome, container, false); que retorna
uma view para o método.
ScrollView(android.widget.ScrollView)
ScrollView é um contêiner que pode
ser rolado (scroll) pelo usuário, Código ScrollView
permitindo o conteúdo ser maior que o <?xml version="1.0" encoding="utf-8"?>
display físico. <ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
Um ScrollView só pode conter um android:layout_height="match_parent">

filho em seu contêiner, que será <LinearLayout


android:layout_width="match_parent"
rolado, mas esse filho pode ser uma android:layout_height="match_parent">

hierarquia complexa de objetos [...]

(ViewGroup). </LinearLayout>

</ScrollView>
ScrollView somente suporta rolagem
vertical. Para rolagem horizontal,
utilize HorizontalScrollView.
LinearLayout(android.widget.LinearLayout)

Perfeito para organizar uma


coleção de views uma abaixo
da outra (na vertical) ou uma ao
lado da outra (na horizontal).

Para especificar a direção do


layout, utiliza-se o atributo
android:orientation
modificando o seu valor para
horizontal ou vertical.

VERTICAL HORIZONTAL
LinearLayout(android.widget.LinearLayout)
Código LinearLayout Resultado

<?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"
android:padding="16dp">

<View
android:layout_width="match_parent"
android:layout_height="128dp"
android:background="#d32f2f" />
<View
android:layout_width="match_parent"
android:layout_height="64dp"
android:layout_marginTop="16dp"
android:background="#7B1FA2" />
<View
android:layout_width="match_parent"
android:layout_height="128dp"
android:layout_marginTop="16dp"
android:background="#FBC02D" />

</LinearLayout>
LinearLayout(android.widget.LinearLayout)
Weight
LinearLayout suporta o valor de weight individualmente para os filhos,
utilizando-se do atributo android:layout_weight.

Esse atributo informa um valor “importante” para a view em termos de quanto


espaço será ocupado da tela (proporção).

Como esse valor será distribuído entre os filhos, será calculado automaticamente
usando-se os dados do dispositivo, para isso, o valor deve ser 0dp variando
conforme o tipo de orientação:

VERTICAL HORIZONTAL
height=”0dp” width=”0dp”
LinearLayout - Weight(android.widget.LinearLayout)
Código LinearLayout - weight Resultado

<?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"
android:padding="16dp">
<View
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="25"
android:background="#d32f2f" />
<View
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginTop="16dp"
android:layout_weight="25"
android:background="#7B1FA2" />
<View
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginTop="16dp"
android:layout_weight="50"
android:background="#FBC02D" />
</LinearLayout>
FrameLayout(android.widget.FrameLayout)
É o tipo mais simples de layout, funciona como um contêiner simples para seus
elementos. Usualmente possui apenas um elemento filho.

Os filhos (views) são posicionados em uma pilha, um sobre o outro. Cada filho é
alinhado como referência aos limites do frame (canto superior esquerdo).

É a escolha ideal quando se deseja sobrepôr views.


FrameLayout(android.widget.FrameLayout)
Resultado
Código FrameLayout

<?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">

<View
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/verde" />

<View
android:layout_width="match_parent"
android:layout_height="80dp"
android:background="@color/amarelo" />

<View
android:layout_width="match_parent"
android:layout_height="80dp"
android:layout_gravity="bottom"
android:background="@color/roxo" />
</FrameLayout>
Mas agora que eu já criei
mais do que um layout,
como eu faço para
exibir uma nova tela
no meu aplicativo?
startActivity() e Intent
Para iniciar uma nova activity utilizamos o método
Activity.startActivity(intent).

Intents são usados como um mecanismo de passagem de mensagens que


funcionam tanto internamente na sua aplicação ou entre aplicações distintas.

Você pode utilizar intents para:

- Explicitamente iniciar um Service ou Activity, usando o nome da sua classe.


- Iniciar um Service ou Activity para executar uma ação com (ou sobre) um
conjunto de dados em particular.
- Transmitir que um evento aconteceu.
Intents são provavelmente o conceito mais exclusivo e
importante no desenvolvimento Android.
Intent(android.content.Intent)
Extra
Para enviar dados entre activities, utilizamos pares de valores-chave chamados
extras.

Assim é possível trafegar dados que podem ser necessários para a execução das
tarefas/ações que são iniciadas com startActivity().

Existem métodos específicos para enviar extras e para recuperar extras, um para
cada tipo básico (como boolean, int, string).

Também é possível criar um objeto Bundle com todos os dados extras e, em


seguida, inserir o Bundle na Intent com putExtras().
Intent(android.content.Intent)
Flags
Sinalizadores definidos na classe Intent que funcionam como metadados para a
intenção.

Os sinalizadores podem instruir o sistema Android sobre como inicializar uma


atividade (por exemplo, a qual tarefa a atividade deve pertencer) e como tratá-la
após sua inicialização (por exemplo, se ela pertencer a uma lista de atividades
recentes).

Confira um pouco mais sobre o setFlags() e as flags clicando aqui.


Intent(android.content.Intent)
Intents explícitas
Especificam o componente a iniciar, pelo nome da classe.

Código Intent explícita - exemplo 1

textViewClicavel.setOnClickListener(new View.OnClickListener() {
@Override
PrimeiraActivity
public void onClick(View v){
Intent intent = new Intent(PrimeiraActivity.this, SegundaActivity.class);
startActivity(intent);
}
}); intent

Código Intent explícita - exemplo 2


SegundaActivity
Intent intent = new Intent(this, SegundaActivity.class);
intent.putExtra("mais_5_minutinhos", true);
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(intent);
Intent(android.content.Intent)

Intents implícitas
Não nomeiam nenhum componente específico, mas declaram uma ação geral a
realizar, o que permite que um componente de outro aplicativo a trate.

Código Intent implícita

Intent sendIntent = new Intent(Intent.ACTION_SEND);


[…] Toca no ícone

String title = getResources().getString(R.string.compartilhar_via);


Intent chooser = Intent.createChooser(sendIntent, title);

// Verifica se o intent irá resolver para ao menos uma activity


if (sendIntent.resolveActivity(getPackageManager()) != null) {
startActivity(chooser);
}
Intent Explícita Intent Implícita

s
! nho o
Ei amigo, pega Esta é somente escol
ha Eu te os!
Me filtr
Esta mensagem! pra mim! Não posso te
ajudar, cara...

Preciso de uma
câmera!
Intent
Intent filter
Para anunciar quais intents implícitas o seu aplicativo pode receber, utiliza-se
um ou mais intent filters. Cada intent filter especifica o tipo de
intenções aceito com base na action e category. Você pode consultar quais os
tipos existentes clicando aqui.

O sistema fornecerá uma intenção implícita ao componente do seu aplicativo


somente se ela puder passar por um dos filtros.
Código AndroidManifest, declaração da Activity com intent filter

<activity android:name=".CompartilharActivity">
<intent-filter>
<action android:name="android.intent.action.SEND"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="text/plain"/>
</intent-filter>
</activity>
RelativeLayout(android.widget.RelativeLayout)

Neste layout, as views são posicionadas relativas a outras views.

Os alinhamentos podem ser combinados.

O RelativeLayout é o mais poderoso gerenciador de layouts do Android, mas


também é um dos mais difíceis de usar sem o apoio de uma ferramenta visual.

Cada componente de interface incluído, se torna um ponto de âncora assim que


adicionado ao layout.

Podemos dividir os pontos de âncora em dois grupos:

- Relativos ao layout (os elementos em relação ao pai)


- Relativos aos elementos irmãos
RelativeLayout (âncoras relativas ao Layout)
Ponto de âncora Explicação Parâmetro XML

Parent bottom Alinha a borda inferior do filho à borda inferior do pai android:layout_alignParentBottom

Parent left Alinha a borda esquerda do filho à borda esquerda do pai android:layout_alignParentLeft

Parent right Alinha a borda direita do filho à borda direita do pai android:layout_alignParentRight

Parent top Alinha a borda superior do filho à borda superior do pai android:layout_alignParentTop

Center horizontally Centraliza o filho horizontalmente, respeitando os limites do pai android:layout_centerHorizontal

Center vertically Centraliza o filho verticalmente, respeitando os limites do pai android:layout_centerVertical

Center Centraliza o filho, respeitando os limites do pai android:layout_center


RelativeLayout (âncoras relativas aos componentes irmãos)
Ponto de Âncora Explicação Parâmetro XML

Above Alinha a borda inferior com a borda superior de um irmão android:layout_above

Below Alinha a borda superior com a borda inferior de um irmão android:layout_below

Left of Alinha a borda direita com a borda esquerda de um irmão android:layout_toLeftOf

Right of Alinha a borda esquerda com a borda direita de um irmão android:layout_toRightOf

Align baseline Alinha a linha base do componente com a de um irmão android:layout_alignBaseline

Align bottom Alinha a borda inferior do componente com a de um irmão android:layout_alignBottom

Align left Alinha a borda esquerda do componente com a de um irmão android:layout_alignLeft

Align right Alinha a borda direita do componente com a de um irmão android:layout_alignRight

Align top Alinha a borda superior do componente com a de um irmão android:layout_alignTop


RelativeLayout(android.widget.RelativeLayout)
Código RelativeLayout Resultado

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="16dp">
<View
android:id="@+id/view_1"
android:layout_width="60dp"
android:layout_height="80dp"
android:background="#E64A19" />
<View
android:id="@+id/view_2"
android:layout_width="match_parent"
android:layout_height="80dp"
android:layout_marginLeft="16dp"
android:layout_toRightOf="@+id/view_1"
android:background="#AFB42B" />
<View
android:id="@+id/view_3"
android:layout_width="match_parent"
android:layout_height="120dp"
android:layout_below="@+id/view_2"
android:layout_marginTop="16dp"
android:background="#0288D1" />
</RelativeLayout>
GridLayout
É um viewgroup que divide a tela em linhas e colunas
Resultado gridlayout.xml
(grid retangular)
Código layout: gridlayout.xml
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:background="#CE93D8"
android:columnCount="5"
android:orientation="horizontal"
android:rowCount="4">

...
<TextView
style="@style/Widget.AppCompat.Button.Borderless"
android:gravity="center"
android:minHeight="60dp"
android:minWidth="60dp"
android:text="/"
android:textColor="#689F38"
android:textSize="30sp" />

</GridLayout>
Toast
É uma forma simples de feedback sobre uma operação em um pequeno popup
que some automaticamente após um tempo.
Não é possível colocar interações sobre um Toast, para isso,
utilize a nova forma: Snackbar.

Também é possível posicionar o Toast em outra posição ou


criar um Toast personalizado (não veremos neste curso,
mas você pode conhecer clicando aqui).

Código Uso de Toast

Toast.makeText(
this, // contexto
"Toast demorado", //texto
Toast.LENGTH_LONG //duração
).show(); //não se esqueça de exibir o Toast!
Tipos de menu
Menu de opções e barra de ação
Coleção principal de itens de menu para uma atividade (deve-se colocar ações
que tem impacto global no aplicativo).

Exemplo 1: item Arquivo contém um submenu

Exemplo 2: itens com app:showAsAction=”collapseActionView”


Tipos de menu
Modo de ação contextual e menu de contexto
É um menu flutuante que aparece quando o usuário realiza um clique longo em
um elemento. Fornece ações que afetam o conteúdo selecionado ou a estrutura
do contexto.
Tipos de menu
Menu pop-up
Exibe itens de uma lista vertical ancorada à view que apresentou o menu. Bom
para fornecer ações relacionadas a conteúdo específico ou opções de
fornecimento de uma segunda parte de um comando. Não devem afetar
diretamente o conteúdo correspondente.
Menu
Os menus são definidos na pasta res/menu/ do projeto e com os seguintes
elementos:

<menu> - Define um Menu, que é um recipiente para os itens de menu. Um


elemento <menu> deve ser o módulo raiz para o arquivo e pode ter um ou mais
elementos <item> e <group>.

<item> - Cria um MenuItem, que representa um único item em um menu. Este


elemento pode conter um elemento <menu> aninhado para criar um submenu.

<group> - Um recipiente invisível e opcional para os elementos <item>. Permite


que você categorize itens de menu para que eles compartilhem propriedades
como estado ativo e visibilidade.
Menu de opções
O elemento <item> é compatível com vários atributos que você pode usar para definir a aparência ou o
comportamento de um item. Abaixo estão os atributos mais importantes que devem ser usados (há
outros disponíveis):

android:id > Um ID de recurso que é único para o Código exemplo de menu_principal.xml


item. Ele permite que o aplicativo reconheça o <?xml version="1.0" encoding="utf-8"?>
item quando o usuário o seleciona. <menu
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
android:icon > Uma referência a um Drawable <item
para usar como o ícone do item. android:id="@+id/locais"
android:icon="@drawable/ic_list_white_24dp"
android:title="Lista de locais"
android:title > Uma referência a uma string app:showAsAction="ifRoom" />
para usar como o título do item. <item
android:id="@+id/config"
android:icon="@drawable/ic_settings_white_24dp"
app:showAsAction > Especifica quando e como android:title="Configurações"
este item deve aparecer como um item de ação na app:showAsAction="ifRoom" />
</menu>
barra de ação.
Menu de opções
Para inflar nosso menu sobrescrevemos o método
Activity.onCreateOptionsMenu(Menu menu) e para tratar os itens do menu
utilizamos o método Activity.onOptionsItemSelected(MenuItem item)
como mostram os exemplos abaixo.

Código método onCreateOptionsMenu(Menu menu) Código método onOptionsItemSelected(MenuItem item)

@Override @Override
public boolean onCreateOptionsMenu(Menu menu) { public boolean onOptionsItemSelected(MenuItem item) {
MenuInflater inflater = getMenuInflater(); switch (item.getItemId()) {
inflater.inflate(R.menu.menu_principal, menu); case R.id.locais:
return super.onCreateOptionsMenu(menu); // tratar clique em locais
} return true;
case R.id.config:
// tratar clique em config
return true;
default:
return super.onOptionsItemSelected(item);
}
}
Dialogs
São pequenas janelas (não ocupam a tela toda) onde o
usuário toma uma decisão ou insere informações
adicionais.

Dialog > classe base para custom dialog.

AlertDialog > pode exibir um título, até três botões,


uma lista de itens selecionáveis ou um layout
personalizado.

DatePickerDialog ou TimePickerDialog > possui


uma UI predefinida que permite ao usuário selecionar
data ou hora.
AlertDialog(android.app.AlertDialog)
Código Exemplo de uso do AlertDialog Resultado

AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);

alertDialogBuilder.setTitle("DESTRUIÇÃO DO MUNDO");

alertDialogBuilder
.setMessage("Deseja prosseguir?")
.setCancelable(false)
.setPositiveButton("Com certeza",new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,int id) {
[…]
}
})
.setNegativeButton("Talvez amanhã",new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog,int id) {
dialog.cancel(); // fecha o dialog
}
});

AlertDialog alertDialog = alertDialogBuilder.create();

alertDialog.show(); // exibe o dialog


CustomDialog
Para o uso de um CustomDialog devemos trabalhar em dois passos:

Passo 1
Criação de um layout específico para o dialog, lembre-se que é possível utilizar
qualquer layout, não apenas o do exemplo (do próximo slide).

Passo 2
Utilizar a classe Dialog para a criação desse CustomDialog, inflando o layout
novo e definindo as ações do dialog (ações referentes ao dialog e ações
referentes a buttons que possam existir).

Não esqueça de utilizar o método show() para exibir o dialog.


CustomDialog
Código Layout: custom_dialog.xml Código Continuação do layout: custom_dialog.xml
<RelativeLayout <TextView
xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/texto_2"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"> android:layout_height="wrap_content"
<FrameLayout android:layout_below="@+id/texto_1"
android:id="@+id/frame_warning" android:paddingLeft="16dp"
android:layout_width="match_parent" android:paddingRight="16dp"
android:layout_height="80dp" android:text="Alguém apertou o botão de destruição
android:background="#d32f2f"> do mundo"
<ImageView android:textSize="20sp" />
android:id="@+id/image"
android:layout_width="wrap_content" <Button
android:layout_height="wrap_content" android:id="@+id/button_ok"
android:layout_gravity="center" style="?attr/buttonBarPositiveButtonStyle"
android:src="@drawable/ic_warning_white_36dp" /> android:layout_width="wrap_content"
</FrameLayout> android:layout_height="wrap_content"
<TextView android:layout_alignParentRight="true"
android:id="@+id/texto_1" android:layout_below="@+id/texto_2"
android:layout_width="match_parent" android:padding="8dp"
android:layout_height="wrap_content" android:text="Sem problemas, eu quem apertei!"
android:layout_below="@+id/frame_warning" android:textColor="#00796B" />
android:gravity="center_horizontal" android:padding="16dp"
android:text="CORRAM PARA AS COLINAS!" </RelativeLayout>
android:textColor="#C2185B" android:textSize="26sp" />
CustomDialog
Resultado

Código CustomDialog

final Dialog dialog = new Dialog(this);

// remove o título. ANTES do setContentView


dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
// não fecha o dialog se clicar fora dele
dialog.setCanceledOnTouchOutside(false);
// infla o layout personalizado
dialog.setContentView(R.layout.custom_dialog);

Button dialogButton = (Button) dialog.findViewById(R.id.button_ok);


dialogButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dialog.dismiss();
}
});

// não esqueça de exibir o dialog!


dialog.show();
Drawable
É qualquer tipo de gráfico que pode ser desenhado na tela, e diferente de uma
View, não recebe eventos ou possui interação com o usuário.

Drawables XML são usados para descrever shapes (cor, borda, gradiente), state,
transitions e mais. Drawables também podem ser escritos programaticamente.

Existem diversos tipos de Drawable:

Estes NÃO SERÃO apresentados neste curso Estes SERÃO apresentados

BitmapDrawable TransitionDrawable StateListDrawable


NinePatchDrawable InsetDrawable ShapeDrawable
LayerDrawable ClipDrawable AnimationDrawable
LevelListDrawable ScaleDrawable
ShapeDrawable (xml)
Com esse Drawable, é possível criar diferentes formas. Resultado aplicação do shape_1

Código shape_1.xml Resultado shape_1.xml

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


<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<stroke
android:width="2dp"
android:color="#FFFFFFFF" />
<gradient
android:angle="90"
android:endColor="#DDBBBBBB"
android:startColor="#DD777777" />
<corners
android:bottomLeftRadius="7dp"
android:bottomRightRadius="7dp"
android:topLeftRadius="7dp"
android:topRightRadius="7dp" />
</shape>
StateDrawable (xml)
Define diferentes estados para um mesmo objeto (como um botão).

Código state_drawable_1.xml

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


<selector
xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@color/colorAccent"
android:state_pressed="true" />
<item android:drawable="@color/colorPrimary"
android:state_focused="true" />
<item android:drawable="@color/colorPrimaryDark" />
</selector>
AnimationDrawable (xml)
Permite carregar uma série de recursos Drawable, um após o outro para criar
uma animação.
Código animation_1.xml

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


<animation-list
xmlns:android="http://schemas.android.com/apk/res/android" Código código Java para executar animação
android:id="@+id/selected"
android:oneshot="false"> ImageView img =
<item (ImageView)findViewById(R.id.imageview_animacao);
android:drawable="@drawable/anima_1" img.setBackgroundResource(R.drawable.animation_1);
android:duration="100" />
<item AnimationDrawable frameAnimation;
android:drawable="@drawable/anima_2"
android:duration="100" /> frameAnimation = (AnimationDrawable) img.getBackground();
[...] frameAnimation.start();
<item
android:drawable="@drawable/anima_6"
android:duration="100" />
</animation-list>
ListView
É uma subclasse de view otimizada para exibir listas com diversas cópias de um
mesmo layout (os itens).

Código ListView

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


<ListView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">

</ListView>

NUNCA utilizar ScrollView com ListView, porque o ListView sabe como realizar seu próprio
rolamento. Mais importante, ao fazer isso todas as importantes otimizações em uma ListView para
trabalhar com listas extensas são perdidas, fazendo com que a ListView exiba a lista TODA de itens
para preencher o espaço infinito provido pela ScrollView.

ListView é populada através de um Adapter


Adapter
Um Adapter faz a ponte entre uma fontes de dados (data sources) em Views que
serão construídas e populadas para cada um dos itens da fonte de dados.

Existem diferentes tipos de Adapters (ArrayAdapter, CursorAdapter e


SimpleCursorAdapter) e também é possível criar seu próprio Adapter.

Neste curso iremos abordar apenas o ArrayAdapter.

ArrayAdapter
Exibe cada item através de um TextView (método toString()).

Caso necessite de uma View diferente de TextView, é necessário sobrescrever o


método getView().
ArrayAdapter Resultado

Código ListView com ArrayAdapter

public class MainActivity extends Activity {


final String[] nomes = new String[]{"Alberto", "Marcelo", "Roberto", "Wagner"};

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

ListView listView = (ListView) findViewById(R.id.listview);

ArrayAdapter adapter = new ArrayAdapter(


this, // contexto
android.R.layout.simple_list_item_1, // layout do item
android.R.id.text1, // contexto
nomes // array
);

listView.setAdapter(adapter);
}
}
CustomAdapter Código layout: pessoa_item.xml

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


<LinearLayout
Para o uso de um xmlns:android="http://schemas.android.com/a
CustomAdapter devemos pk/res/android"
android:layout_width="match_parent"
trabalhar em três passos: android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp">
Passo 1 <TextView Resultado pessoa_item.xml
android:id="@+id/nome_textview"
android:layout_width="wrap_content"
Criação de um layout android:layout_height="wrap_content"
android:text="Nome"
específico para o item da lista android:textColor="#F57C00"
(ou do grid), lembre-se que é android:textSize="20sp" />

possível utilizar qualquer <TextView


android:id="@+id/profissao_textview"
layout, não apenas o do android:layout_width="wrap_content"
android:layout_height="wrap_content"
exemplo ao lado. android:layout_marginTop="4dp"
android:text="Profissão"
android:textSize="16sp" />
</LinearLayout>
CustomAdapter
Código ListView com ArrayAdapter custom: PessoasAdapter.java
Passo 2 public class PessoasAdapter extends ArrayAdapter<Pessoa> {
public PessoasAdapter(Context context, ArrayList<Pessoa> Pessoas) {
Extender a classe super(context, 0, Pessoas);
}
ArrayAdapter,
@Override
sobrescrevendo o public View getView(int position, View convertView, ViewGroup parent) {
método getView(), Pessoa pessoa = getItem(position);

que irá inflar o layout if (convertView == null) {


convertView = LayoutInflater.from(getContext()).inflate(R.layout.pessoa_item, parent, false);
criado para o item no }
Passo 1, populado com as
TextView tvName = (TextView) convertView.findViewById(R.id.nome_textview);
informações da posição TextView tvHome = (TextView) convertView.findViewById(R.id.profissao_textview);
passada nos
tvName.setText(pessoa.nome);
parâmetros do método tvHome.setText(pessoa.profissao);
(usando o método return convertView;
getItem(...)) e }
}
retornando a View
inflada.
CustomAdapter
Passo 3
Código Pessoa.java Resultado Activity.java

public class Pessoa {


public String nome;
Na Activity, public String profissao;

instanciar o public Pessoa(String nome, String profissao) {


this.nome = nome;
CustomAdapter criado this.profissao = profissao;
}
no Passo 2, passando o }

array necessário para Código trecho da Activity.java

popular a lista. // Criação de um array usando o modelo Pessoa


ArrayList<Pessoa> pessoasArray = new ArrayList<>();
pessoasArray.add(new Pessoa(...));
E por último definir o
// Instanciação de CustomAdapter
adapter em sua PessoasAdapter adapter = new PessoasAdapter(this,
pessoasArray);
ListView com o
// Definindo o adapter da ListView
método listView.setAdapter(adapter);
setAdapter(...).
GridView
É um viewgroup que exibe itens em um scrollable grid Resultado

bidimensional.

Os itens são inseridos automaticamente no layout


através de um ListAdapter.
Código layout: gridview_layout.xml

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


<GridView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/gridview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:horizontalSpacing="8dp"
android:numColumns="2"
android:padding="8dp"
android:stretchMode="columnWidth"
android:verticalSpacing="8dp"
tools:listitem="@layout/pessoa_grid_item" />
GridView
Código Custom adapter: PessoasGridAdapter.java

public class PessoasGridAdapter extends ArrayAdapter<Pessoa> {


Context context;
public PessoasGridAdapter(Context context, ArrayList<Pessoa> Pessoas) {
super(context, 0, Pessoas);
this.context = context;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
Pessoa pessoa = getItem(position);

if (convertView == null) {
convertView = LayoutInflater.from(getContext()).inflate(R.layout.pessoa_grid_item, parent, false);
}

TextView tvName = (TextView) convertView.findViewById(R.id.nome_textview);


TextView tvProfissao = (TextView) convertView.findViewById(R.id.profissao_textview);
ImageView ivProfissao = (ImageView) convertView.findViewById(R.id.imagem_profissao);
FrameLayout frame = (FrameLayout) convertView.findViewById(R.id.frame);
tvName.setText(pessoa.nome);
tvProfissao.setText(pessoa.profissao);
ivProfissao.setImageDrawable(ContextCompat.getDrawable(context, pessoa.idDrawable));
frame.setBackgroundColor(pessoa.idColor);

return convertView;
}
}
GridView
Código MainActivity.java

public class MainActivity extends Activity {

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

GridView gridView = (GridView) findViewById(R.id.gridview);

ArrayList<Pessoa> pessoasArray = new ArrayList<>();


pessoasArray.add(new Pessoa("Mr. Bit", "Desenvolvedor", R.drawable.ic_desenvolvedor, Color.parseColor("#C2185B")));
pessoasArray.add(new Pessoa("Rayannie", "Dentista", R.drawable.ic_dentista, Color.parseColor("#512DA8")));
pessoasArray.add(new Pessoa("Lobervaldo", "Pintor", R.drawable.ic_pintor, Color.parseColor("#1976D2")));
pessoasArray.add(new Pessoa("Zaratrusta", "Atendente", R.drawable.ic_atendente, Color.parseColor("#00796B")));
pessoasArray.add(new Pessoa("Waldigley", "Enfermeiro", R.drawable.ic_enfermeiro, Color.parseColor("#689F38")));
pessoasArray.add(new Pessoa("Bond, James Bond", "Espião", R.drawable.ic_espiao, Color.parseColor("#FBC02D")));
pessoasArray.add(new Pessoa("Zé do Picadinho", "Assassino", R.drawable.ic_assassino, Color.parseColor("#F57C00")));
pessoasArray.add(new Pessoa("Sr. Furtado", "Ladrão", R.drawable.ic_ladrao, Color.parseColor("#5D4037")));

PessoasGridAdapter adapter = new PessoasGridAdapter(this, pessoasArray);

gridView.setAdapter(adapter);
}
}
Shared Preferences
Utilizado para gravar um conjunto pequeno de valores-chave.

Um objeto SharedPrefences indica um arquivo que contém pares de


valores-chave e fornece métodos simples para ler e gravar.

Cada arquivo SharedPrefences pode ser privado ou compartilhado.

putString(“NOME”, “Marcelo”)

CHAVE VALOR
Shared
NOME Marcelo Preferences

getString(“NOME”, “Sem nome”)


Shared Preferences
Activity.getSharedPreferences(...) > Quando há vários arquivos de
preferência, utiliza-se este método identificando pelo nome no primeiro
parâmetro.
Código SharedPrefences gravando valor

String PREFERENCIAS = "prefs_android_basico";

SharedPreferences sharedpreferences = getSharedPreferences(PREFERENCIAS, Context.MODE_PRIVATE);

SharedPreferences.Editor editor = sharedpreferences.edit();


editor.putString("chave", "valor");
editor.commit();

Código SharedPrefences recuperando valor

String PREFERENCIAS = "prefs_android_basico";

SharedPreferences sharedpreferences = getSharedPreferences(PREFERENCIAS, Context.MODE_PRIVATE);

String valorSalvo = sharedpreferences.getString("chave", "valor padrão");


Shared Preferences
Activity.getPreferences(...) > Se precisar usar apenas um arquivo de
preferência compartilhada para a atividade (não é necessário fornecer um
nome).

Código SharedPrefences gravando valor

SharedPreferences sharedpreferences = getPreferences(Context.MODE_PRIVATE);

SharedPreferences.Editor editor = sharedpreferences.edit();


editor.putString("chave", "valor");
editor.commit();

Código SharedPrefences recuperando valor

SharedPreferences sharedpreferences = getPreferences(Context.MODE_PRIVATE);

String valorSalvo = sharedpreferences.getString("chave", "valor padrão");


PreferenceScreen
PreferenceScreen é a definição de tela de
preferências (configurações) do usuário. Com
ela é possível integrar com
SharedPreferences.

O layout deve ficar dentro de res/xml e a


estrutura pode ser criada com diversas tags,
podendo criar não só os itens, mas também
categorias para dividir melhor o conteúdo
(representado na cor azul na imagem ao lado).
PreferenceScreen
TAGS
PreferenceScreen > nó raiz que possui diversos elementos Preference e cada
filho é exibido como um item único na lista. Ao incluir um PreferenceScreen
como filho, é definida como uma subtela de configuração.

PreferenceCategory > é a divisão da tela de preferência em grupos (muito útil


quando possuir muitos itens de configuração).

Preference > representa o bloco de construção básico, existem diversos tipos


de subclasses, como CheckBoxPreference, EditTextPreference,
ListPreference. Consulte a documentação para ver as restantes.
PreferenceScreen

Código preferences.xml

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


android:key <PreferenceScreen
define o nome da chave que xmlns:android="http://schemas.android.com/apk/res/android"
é utilizada na android:title="Preferências">
<CheckBoxPreference
SharedPreferences
android:defaultValue="true"
android:key="pref_notif"
android:summary="Recebe notificações"
android:title="Habilitar notificações" />
<CheckBoxPreference
android:defaultValue="true"
android:dependency android:dependency="pref_notif"
depende do nome da android:key="pref_hora_notif"
chave informada estar android:summary="Vibrar ao receber notificações"
habilitada android:title="Vibrar" />
</PreferenceScreen>
PreferenceScreen
Utilizamos PreferenceFragment ao criar uma tela de preferências para versão
do Android superior à 3.0 (> API 11).

Código ConfiguracoesActivity.java

public class ConfiguracoesActivity extends AppCompatActivity {


@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getFragmentManager().beginTransaction().replace(android.R.id.content, new ConfiguracoesFragment()).commit();
}

public static class ConfiguracoesFragment extends PreferenceFragment {


@Override
public void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
}
}
}
Threads

Na Main Thread (UI Thread) ocorrem todos os eventos de input e output, por isso
deve-se evitar longas operações.

Para evitar o travamento da interface, deve-se executar threads em background


como AsyncTask ou Services.

AsyncTask deve ser utilizada em operações rápidas, de poucos segundos.


AsyncTask(android.os.AsyncTask)
Main/UI Background
Thread Thread

onPreExecute()

onProgressUpdate(Progress...) publishProgress(Progress...) doInBackground(Params...)

onPostExecute(Result)
AsyncTask(android.os.AsyncTask)
Código DownloadFilesTask TIPOS GENÉRICOS

{
public class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
protected Long doInBackground(URL... urls) {
int count = urls.length; Params, o tipo dos parâmetros que
long totalSize = 0; serão enviados para a task.
for (int i = 0; i < count; i++) {
totalSize += Downloader.downloadFile(urls[i]);
publishProgress((int) ((i / (float) count) * 100)); Progress, o tipo das unidades de
if (isCancelled()) break; progresso publicadas durante a
}
return totalSize; execução em background.
}

protected void onProgressUpdate(Integer... progress) { Result, o tipo de resultado da


definirProgresso(progress[0]); execução em background. Obter
}
com método get().
protected void onPostExecute(Long result) {
exibirDialog("Baixado " + result + " bytes");
} Se não usar algum dos
} parâmetros, utilizar Void
Notificações
Uma notificação é uma mensagem que pode ser exibida ao
usuário fora da UI normal do aplicativo.

Quando você diz ao sistema para emitir uma notificação,


ela primeiro aparece como um ícone na área de
notificação.

Para ver os detalhes da notificação, o usuário abre a


gaveta de notificação.
Notificações
Você especifica as ações e informações da UI para uma
notificação no objeto NotificationCompat.Builder.
Para criar a própria notificação, chama-se
NotificationCompat.Builder.build(), que retorna um
objeto Notification contendo suas especificações. Para
emitir a notificação, passa-se o objeto Notification ao
sistema chamando NotificationManager.notify().
Código criação de uma notificação e emissão

NotificationCompat.Builder notificationBuilder = new


NotificationCompat.Builder(this)
.setTicker("Texto da notificação")
.setColor(ContextCompat.getColor(this, R.color.colorNotification))
.setSmallIcon(R.drawable.ic_stat_cake)
.setAutoCancel(true)
.setContentTitle("Título da notificação")
.setContentText("Descrição");

NotificationManager notificationManager = (NotificationManager)


getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(12345, notificationBuilder.build());
Ações da notificação
Apesar de serem opcionais, deve-se adicionar pelo menos uma ação à
notificação. Uma ação permite que os usuários direcionem-se diretamente da
notificação para uma Activity no aplicativo, onde podem visualizar um ou mais
eventos ou realizar outros trabalhos.
Dentro de uma Notification, a própria ação é definida por uma
PendingIntent contendo uma Intent que inicia uma Activity no aplicativo.
Para associar a PendingIntent a um gesto, chame o método adequado de
NotificationCompat.Builder.
Por exemplo, se quiser iniciar Activity quando o usuário clicar no texto da
notificação na gaveta de notificação, deve-se adicionar um PendingIntent
chamando setContentIntent() (este é o cenário mais comum).
Ações da notificação

Código Adição de uma ação para a notificação já criada

NotificationCompat.Builder notificationBuilder = new […]

// Cria um intent explícito


Intent resultIntent = new Intent(this, TratamentoNotificaoActivity.class);

//Cria um objeto de pilha de tarefas artificial (back stack) para a Activity iniciada
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addParentStack(TratamentoNotificaoActivity.class);
stackBuilder.addNextIntent(resultIntent);

PendingIntent resultPendingIntent =
stackBuilder.getPendingIntent(
0, //Código de requisição
PendingIntent.FLAG_UPDATE_CURRENT //Flags
);

notificationBuilder.setContentIntent(resultPendingIntent); //Adiciona o PendingIntent à notificação


Banco de dados
O Android armazena seu banco de dados (SQLite) no espaço privado do disco
associado ao aplicativo. Seus dados estão protegidos porque, por padrão, essa
área não pode ser acessada por outros aplicativos.
Para o uso de banco de dados, seguimos 3 passos:

Passo 1
Definir um modelo de domínio/modelo de entidades.

gatos
_id : integer
nome : text
data_nascimento : text
cor_pelo : text
peso : real
tamanho : integer
Banco de dados
Passo 2
Definir uma classe de contrato, que é o contêiner das constantes que definem
nomes para URIs, tabelas e colunas.
A classe de contrato permite usar as mesmas constantes em outras classes no
mesmo pacote.
Também permite que você altere o nome da coluna em um local e que a
mudança se propague pelos seus códigos.
Este passo é opcional, apesar de altamente recomendado.

PENSE NA MANUTENÇÃO DO SEU CÓDIGO!


Banco de dados
Código definição de um contrato

public final class GatoContract {


public GatoContract() {}
Implementando a
// Define a tabela de gatos
public static abstract class GatosEntry implements BaseColumns { interface BaseColumns,
public static final String TABLE_NAME = "gatos";
sua inner class pode
public static final String COLUMN_NOME = "nome";
public static final String COLUMN_DATA_NASCIMENTO = "data_nascimento"; herdar um campo-chave
public static final String COLUMN_COR_PELO = "cor_pelo";
public static final String COLUMN_PESO = "peso";
primário chamado _ID
public static final String COLUMN_TAMANHO = "tamanho"; importante para classes
public static final String COLUMN_NULL = "null"; como CursorAdapter.
}
}

Contrato especifica claramente o layout do esquema de forma sistemática e


autodocumentada.
Banco de dados
Passo 3
Criar um Helper, (através do SQLiteOpenHelper). Usando esta classe para obter
referências para seu banco de dados, o sistema realiza operações de possível
longa execução para criar e atualizar o banco de dados apenas quando
necessário e não durante a inicialização do aplicativo.
Este Helper contém o número da versão do banco, o nome do arquivo de banco,
e os métodos sobrescritos necessários para criação, atualização e deleção do
banco, conforme sua aplicação necessitar.
Banco de dados
Código declaração básica para criação de tabela (simplificada)

public static final String PRIMARY_KEY = " PRIMARY KEY";


public static final String INTEGER_TYPE = " INTEGER";
public static final String TEXT_TYPE = " TEXT";
public static final String REAL_TYPE = " REAL";
public static final String COMMA_SEP = ",";

private static final String SQL_CRIAR_BANCO =


"CREATE TABLE IF NOT EXISTS " + GatoContract.GatosEntry.TABLE_NAME +
" (" +
GatoContract.GatosEntry._ID + INTEGER_TYPE + PRIMARY_KEY + COMMA_SEP +
GatoContract.GatosEntry.COLUMN_NOME + TEXT_TYPE + COMMA_SEP +
GatoContract.GatosEntry.COLUMN_DATA_NASCIMENTO + TEXT_TYPE + COMMA_SEP +
GatoContract.GatosEntry.COLUMN_COR_PELO + TEXT_TYPE + COMMA_SEP +
GatoContract.GatosEntry.COLUMN_PESO + REAL_TYPE + COMMA_SEP +
GatoContract.GatosEntry.COLUMN_TAMANHO + INTEGER_TYPE +
" )";

Esta declaração básica é utilizada em seu Helper, o próximo slide contém o restante
das informações.
Banco de dados
Código exemplo de SQLiteOpenHelper utilizando a estrutura básica do slide anterior

public class GatosDbHelper extends SQLiteOpenHelper {


// Ao mudar o esquema do banco, incrementar o número da versão
public static final int DATABASE_VERSION = 1;
// Nome do seu banco
public static final String DATABASE_NAME = "gatos.db";

public GatosDbHelper(Context context) {


super(context, DATABASE_NAME, null, DATABASE_VERSION);
}

public void onCreate(SQLiteDatabase db) {


db.execSQL(SQL_CRIAR_BANCO);
}

public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {


// executar as verificações baseadas no oldVersion e newVersion
}

public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {


// não necessário
}
}
Banco de dados Código lendo registros no banco de dados

Utilize o método GatosDbHelper dbHelper = new GatosDbHelper(this);


SQLiteDatabase db = dbHelper.getReadableDatabase();
correspondente para trabalhar
com um banco apenas de // Define quais colunas serão retornadas
String[] projection = {
leitura ou leitura/escrita
GatoContract.GatosEntry._ID,
getReadableDatabase() ou GatoContract.GatosEntry.COLUMN_NOME,
getWritableDatabase(). GatoContract.GatosEntry.COLUMN_DATA_NASCIMENTO,
GatoContract.GatosEntry.COLUMN_COR_PELO,
GatoContract.GatosEntry.COLUMN_PESO,
GatoContract.GatosEntry.COLUMN_TAMANHO
Ler informações };

do banco de String sortOrder = GatoContract.GatosEntry.COLUMN_NOME + " DESC";

Cursor cursor = db.query(


dados GatoContract.GatosEntry.TABLE_NAME, // a tabela da query
projection, // as colunas que serão retornadas
null, // as colunas para a cláusula WHERE
Para ler do banco, null, // os valores da cláusula WHERE
null, // não agrupar as linhas
utilize o método null, // não filtrar por grupos de linhas
sortOrder // ordenação
query(). );
Banco de dados
Código CONTINUAÇÃO - recuperando dados da query

ArrayList<Gato> gatosList = new ArrayList<>();

if (cursor.getCount() > 0) {
while (cursor.moveToNext()) {
Gato gato = new Gato();

gato.id = cursor.getInt(cursor.getColumnIndex(GatoContract.GatosEntry._ID));
gato.nome = cursor.getString(cursor.getColumnIndex(GatoContract.GatosEntry.COLUMN_NOME));
gato.dataNascimento = cursor.getString(cursor.getColumnIndex(GatoContract.GatosEntry.COLUMN_DATA_NASCIMENTO));
gato.corPelo = cursor.getString(cursor.getColumnIndex(GatoContract.GatosEntry.COLUMN_COR_PELO));
gato.peso = cursor.getDouble(cursor.getColumnIndex(GatoContract.GatosEntry.COLUMN_PESO));
gato.tamanho = cursor.getInt(cursor.getColumnIndex(GatoContract.GatosEntry.COLUMN_TAMANHO));

gatosList.add(gato);
}
}

GatosAdapter adapter = new GatosAdapter(this, gatosList);


listView.setAdapter(adapter);
Após obter os dados da query, para recuperar cada item do cursor, deve-se mover para
o primeiro ou próximo item e obter a informação da coluna através do método
getColumnIndex() ou getColumnIndexOrThrow()
Banco de dados
Código inserindo informações de um novo evento (APP) no banco

Como colocar public long inserirGato(Gato gato) {


GatosDbHelper dbHelper = new GatosDbHelper(this);
informações no SQLiteDatabase db = dbHelper.getWritableDatabase(); // modo de gravação

banco de dados
// Cria um novo mapa de valores para serem inseridos no banco
ContentValues values = new ContentValues();
values.put(GatoContract.GatosEntry.COLUMN_NOME, gato.nome);
values.put(GatoContract.GatosEntry.COLUMN_DATA_NASCIMENTO,
Coloque dados no gato.dataNascimento);
values.put(GatoContract.GatosEntry.COLUMN_COR_PELO, gato.corPelo);
banco de dados values.put(GatoContract.GatosEntry.COLUMN_PESO, gato.peso);
transmitindo um values.put(GatoContract.GatosEntry.COLUMN_TAMANHO, gato.tamanho);

objeto ContentValues // Insere a nova linha, retornando a chave primária dessa nova linha
return db.insert(
para o método GatoContract.GatosEntry.TABLE_NAME,
GatoContract.GatosEntry.COLUMN_NULL,
insert(). values);
}
Banco de dados

Excluir
Código exclusão de informação do banco de dados

private void apagarGato(int id) {


informações GatosDbHelper dbHelper = new GatosDbHelper(this);

SQLiteDatabase db = dbHelper.getWritableDatabase(); // modo de gravação


A exclusão leva em
// define a cláusula WHERE
conta os critérios de String selection = GatoContract.GatosEntry._ID + " = ?";
// especifica os argumentos da identificação
identificação. String[] selectionArgs = {String.valueOf(id)};
// execução da exclusão
db.delete(GatoContract.GatosEntry.TABLE_NAME, selection, selectionArgs);
}
Banco de dados

Código atualização de informação

Atualizar
public void atualizarEvento(Gato gato, long id) {
GatosDbHelper dbHelper = new GatosDbHelper(this);

informações SQLiteDatabase db = dbHelper.getWritableDatabase();

// novo valor para uma coluna


Para atualização das ContentValues values = new ContentValues();
values.put(GatoContract.GatosEntry.COLUMN_NOME, gato.nome);
informações, utiliza-se
// cláusula WHERE
o método update(). String selection = GatoContract.GatosEntry._ID + " = ? ";
String[] selectionArgs = { String.valueOf(id) };
Deve-se informar qual
int count = db.update(
item atualizar através GatoContract.GatosEntry.TABLE_NAME,
values,
da cláusula WHERE. selection,
selectionArgs);
}
Content Provider
Gerenciam um conjunto compartilhado de dados do aplicativo. É possível
armazenar os dados no sistema de arquivos, em um banco de dados SQLite ou
em qualquer local de armazenamento persistente que o aplicativo possa acessar.
Por meio do provedor de conteúdo, outros aplicativos podem consultar ou até
modificar os dados (se o provedor de conteúdo permitir).

Você irá precisar quando:

- Sua aplicação precisar compartilhar dados com outras aplicações localmente


- Em aplicações mais complexas, que requeiram uma melhor separação entre
o gerenciamento dos dados e os outros componentes da aplicação
- Em aplicações corporativas com estratégias de cache avançadas (abordagem
arquitetural centrada no ContentProvider)
A implementação do ContentProvider não será estudada neste curso.
Content Provider
O framework ContentProvider tem vários componentes:

- Contrato > uma classe Java qualquer que simplesmente define constantes
necessárias pelos clientes que precisam utilizar o provider .
- ContentResolver > uma parte da biblioteca Android que usa serviços a nível
de sistema para identificar o ContentProvider que esteja registrado como o
gerenciador de um conjunto de dados correspondente de uma URI específica.
O ContentResolver encaminha as requisições ao ContentProvider.
- ContentProvider > gerencia o conjunto de dados, fornecendo aos clientes
uma visão consistente dos dados e gerenciando o acesso aos mesmos.
- ContentObserver > é uma API que suporta um sistema de notificações
baseadas em URIs, que torna possível que os clientes descubram mudanças
em um conjunto de dados.
Uso de recursos do dispositivo
Para a utilização de recursos do dispositivo (como câmera, GPS, gravar dados no
armazenamento…) devemos informar no AndroidManifest qual a
permission/feature que nosso aplicativo está solicitando.
Permissions:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

Features (previne que celulares que não possuem a feature instalem seu app):
<uses-feature android:name="android.hardware.camera" />

Após a declaração das permissions/features é que temos a certeza que o recurso


do dispositivo estará habilitado (não é necessário permission de câmera se você
usa um intent para acessá-la) e disponível para uso.
Publicação do aplicativo
Publicar um aplicativo significa disponibilizá-lo (ou as suas atualizações) em uma
loja de aplicativos, como a Google Play. O processo de publicação de um
aplicativo Android envolve:

● Assinar o aplicativo com chave de produção (obrigatório)


● Ofuscar o código do aplicativo (recomendado)
● Preparar o material de publicação (alguns itens são obrigatórios)
● Publicar em testes alfa, beta ou produção

Dependendo dos recursos utilizados no seu aplicativo, pode ser necessário gerar
chaves e tokens de permissão para cada um destes recursos. Por exemplo, para
o Google Maps.
Assinatura
O Android exige que todos os APKs sejam assinados digitalmente com um
certificado antes de serem instalados.

Um certificado contém a chave pública de um par de chaves público/privada,


como também os metadados que identificam o dono da chave (por exemplo
nome e localização). O dono do certificado é quem possui a chave privada. O
certificado serve como uma "digital" (fingerprint) que associa unicamente o APK
à você e sua correspondente chave privada.

Keystore é um arquivo binário que contém uma ou mais chaves privadas.


Quando você assina um APK para release usando o Android Studio, você pode
escolher entre gerar uma nova keystore e chave privada ou usar uma keystore e
chave privada já existente. Deve-se utilizar uma senha forte para sua keystore, e
uma senha forte para cada chave privada armazenada na keystore.
Guarde sua keystore em um lugar seguro.
Ofuscação e encolhimento
Para tornar seu APK o menor possível, você deve habilitar o encolhimento
(shrinking), que remove o código e recursos não utilizados em seu release.

ProGuard é o responsável por diminuir o seu código, detectando e removendo


classes, campos, métodos e atributos não utilizados do seu pacote, incluindo as
bibliotecas adicionadas ao projeto (ajudando com o limite de 64k). Também
otimiza o bytecode, removendo instruções de código não utilizadas, ofuscando
as classes, campos e métodos com nomes curtos. O código ofuscado ajuda a
prevenir a engenharia reversa do seu APK.

A diminuição dos recursos existe como um plugin para o Gradle, que remove
recursos não utilizados do seu pacote, incluindo recursos não utilizados em
bibliotecas importadas.
Ofuscação e encolhimento
Abaixo há uma explicação dos atributos para encolhimento e ofuscação que
devem ser inseridos no seu arquivo build.gradle.

Código build.gradle (shrinking) Habilita o encolhimento dos


recursos
android {
buildTypes {
release { Habilita o encolhimento do código
shrinkResources true
minifyEnabled true
Padrão do ProGuard localizado em
proguardFiles getDefaultProguardFile(‘proguard-android.txt'),
'proguard-rules.pro'
tools/proguard/
}
} Seu arquivo de regras (na raiz junto
… ao build.gradle)
}
Google Play

Google Play é a loja online da Google para distribuição de aplicações, jogos,


filmes, música e livros para dispositivos com o sistema Android. Anteriormente a
loja chamava-se Android Market.
Para ser um desenvolvedor e publicar seus apps na loja, você precisa:
inscrever-se numa conta de desenvolvedor, aceitar o contrato, pagar a taxa de
inscrição (U$ 25) e inserir os outros detalhes da conta.
A venda de apps e produtos na loja é dividida da seguinte forma: 70% para o
desenvolvedor e 30% como taxa de transação.
Se o seu produto ainda não receber os valores em Reais, há ainda uma taxa de
25% de imposto retido na fonte.

Link para o console do desenvolvedor: https://play.google.com/apps/publish/


Material de publicação
Compõem o material de publicação elementos textuais e recursos gráficos:

- Título (30 caracteres)*


- Breve descrição (80 caracteres)*
- Descrição completa (4000 caracteres)*
- Capturas de tela (telefone, tablet, android tv, android wear)*
- Ícone de alta resolução (512 x 512 px, PNG de 32 bits, com alpha)*
- Gráfico de recursos (1024 i x 500 px, JPG ou PNG de 24 bits, sem alpha)*
- Gráfico promocional (180 i x 120 px, JPG ou PNG de 24 bits, sem alpha)
- Banner de TV (1280 x 720 px, JPG ou PNG de 24 bits)
- Vídeo promocional (URL do vídeo no YouTube)

* Obrigatório
Fabric
O Fabric é a suíte modularizada criada pela empresa Twitter com ferramentas de
apoio aos desenvolvedores mobile.

Cada ferramenta é disponibilizada em kits, de fácil configuração e uso tanto em


aplicativos nativos Android quanto para iOS (integrações disponíveis para
Android Studio, IntelliJ, XCode e Unity).

Os principais kits são:

- Crashlytics
- Beta
- Answers
- Twitter
- MoPub
Crashlytics
Pode ser considerado o núcleo da suíte Fabric, tem como objetivo prover
estabilidade aos aplicativos. Fazem parte do Crashlytics o Beta e o Answers.

Principais recursos
- Captura detalhes do erro e do dispositivo no qual
o erro aconteceu
- Envia ao desenvolvedor um e-mail ou notificação
com pistas da linha de código aonde o erro
aconteceu, mesmo com o aplicativo ofuscado
- Armazena estatísticas dos últimos 365 dias
- Identifica quando um erro já corrigido "regressa"
em uma nova versão do aplicativo
- Após consertar o erro, o desenvolvedor pode
marcá-lo como "closed"
Crashlytics - Beta
Facilita o processo de distribuição de versões de testes e de homologação dos
aplicativos.

Principais recursos
- Cadastro de testadores e homologadores,
individualmente ou em grupos
- Não "queima" versões do aplicativo
- Distribui novas versões apenas para os usuários
selecionados. Estas permissões podem ser
alteradas ou revogadas a qualquer momento
- Notifica os usuários quando uma nova versão
está disponível no Beta
- Versões históricas via App Beta
- Armazena estatísticas dos testes de cada versão
Crashlytics - Answers
Provê dados analíticos em tempo real ou através de informações coletadas nos
últimos 365 dias pelo aplicativo.

Principais recursos
- Usuários utilizando o app no momento
- Consolidações diversas como: quantidades de
instalações no dia, de usuários ativos no dia, de
usuários livres de bugs e de sessões de usuários
- Dashboard com gráficos intuitivos
- Detalhamento dos dados consolidados
- Funcionalidades mais utilizadas
- Cadastro de logs e eventos personalizados
Twitter Kit
Kit que facilita a integração de um aplicativo aos serviços do microblog social
Twitter. Pode ser utilizado para promover o crescimento da sua base de
usuários.
Principais recursos
- Acesso a API Rest do Twitter (tweets, favoritos,
buscas, listas de tweets e coleções)
- Exibição de Tweets de uma determinada hashtag
- Exibição de linhas do tempo
- Logar com conta do Twitter (OAuth)
- TweetComposer que permite escrever tweets
adicionando fotos ou vídeos de maneira simples
MoPub
Simplifica a integração de publicidades (ads) em um aplicativo adicionando
recursos de monetização ao aplicativo.

Principais recursos:
- Agrega diversos serviços de publicidade em um
único lugar (mediação)
- Suporte melhor que o do Google (Admob)
- Alguns recursos de publicidade utilizam
componentes nativos para não comprometer a
experiência do usuário
Apêndice I:
Bibliotecas de Compatibilidade
Support Library
Bibliotecas de compatibilidade
As bibliotecas de compatibilidade do Android oferecem:

● retrocompatibilidade a componentes de versões do framework


● elementos de UI para implementar os padrões de layout recomendados
● suporte para diferentes meios, como tvs e wearables (relógios, óculos,
pulseiras…)
● diversas utilidades

Existem muitas bibliotecas e nos slides a seguir estão apenas algumas das mais
usadas
v4
Para: Android 1.6 (API 4) e superior
Localização: <sdk>/extras/android/support/v4/
Dependência: compile 'com.android.support:support-v4:23.3.0'

O que contempla (23.3.0)


Fragment > encapsulamento da UI e funcionalidade com os Fragments
NotificationCompat > melhores notificações
LocalBroadcastManager > registro e recebimento de intents sem transmissão global (pelo app)
ViewPager > ViewGroup que gerencia o layout de seus filhos, usuário pode utilizar swipe
PagerTitleStrip > campo de título não interativo que pode ser adicionado à um filho do ViewPager
PagerTabStrip > modo de navegação entre views paginadas e que pode ser utilizado com ViewPager
DrawerLayout > criação de um Navigation Drawer que pode ser puxado pelas bordas de uma janela
SlidingPaneLayout > widget para criação de sumário e detalhes de views que se adaptam a várias telas
Loader > carregamento de data assíncrono
FileProvider > compartilhamento de arquivos privados entre aplicações
Além de diversas implementações para acessibilidade e outras funcionalidades
Multidex Localização: <sdk>/extras/android/support/multidex/
Dependência: compile 'com.android.support:multidex:1.0.0'

Suporte para a construção de apps com múltiplos arquivos DEX (Dalvik


Executable).

Apps que fazem referência à mais de 65536 métodos exigem a configuração de


multidex.
Código build.gradle (dependencies) Código AndroidManifest.xml

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


[…] <manifest
multiDexEnabled true xmlns:android="http://schemas.android.com/apk/res/android"
} package="br.gov.serpro.teste">
<application
dependencies { […]
[…] android:name="android.support.multidex.MultiDexApplication">
compile 'com.android.support:multidex:1.0.0' […]
} </application>
</manifest>
v7
Para: Android 2.1 (API 7) e superior
Localização: <sdk>/extras/android/support/v7/
Dependência: compile 'com.android.support:<NOME_PACOTE>-v7:23.3.0'

O que contempla (23.3.0)


appcompat <sdk>/extras/android/support/v7/appcompat/
Adiciona suporte para o design pattern Action Bar. Também inclui suporte para UI com material design.

cardview <sdk>/extras/android/support/v7/cardview/
Adiciona suporte para a utilização do widget CardView.

gridlayout <sdk>/extras/android/support/v7/gridlayout/
Suporte para a classe GridLayout, que permite organizar a UI com um grid de células retangulares.

mediarouter <sdk>/extras/android/support/v7/mediarouter/
Provê meios de controlar a exibição de canais de mídia e stream do dispositivo para telas externas,
autofalantes e outros dispositivos de destino.
v7
Para: Android 2.1 (API 7) e superior
Localização: <sdk>/extras/android/support/v7/
Dependência: compile 'com.android.support:<NOME_PACOTE>-v7:23.3.0'

O que contempla (23.3.0)


palette <sdk>/extras/android/support/v7/palette/
Permite extrair cores de destaque de uma imagem.

recyclerview <sdk>/extras/android/support/v7/recyclerview/
Adiciona a classe RecyclerView.

preference <sdk>/extras/android/support/v7/preference/
Provê APIs para suportar diferentes objetos de preferências, como CheckBoxPreference e ListPreference
Annotation Localização: <sdk>/extras/android/support/annotations/
Dependência: compile 'com.android.support:support-annotations:23.3.0'

O que contempla (23.3.0)


Provê APIs para uso de anotações nos apps.

Design Localização: <sdk>/extras/android/support/design/


Dependência: compile 'com.android.support:design:23.3.0'

O que contempla (23.3.0)


Provê APIs de suporte para componentes e padrões do material design nos apps.
Apêndice II:
Patterns e Anti-Patterns
ANTI
Sign Up / Sign In
P TTERN
Categoria Exemplo
Welcome Experience

Quando e como acontece


Acontece quando um aplicativo exige que o usuário
em potencial se cadastre e efetue login antes utilizar
o aplicativo pela primeira vez.

Porque evitar
Exigir cadastro antes de poder utilizar o app =
usuário apaga o app.

Dica
Utilizar login social ao invés deste anti-padrão
(Google, Facebook, Twitter, dentre outros fornecem
este tipo de serviço)
ANTI
EULA (End User Lisence Agreement)
P TTERN
Categoria Exemplo
Welcome Experience

Quando e como acontece


Tipicamente exibido quando o usuário abre o
aplicativo pela primeira vez. Ele não consegue fazer
mais nada a menos que aceite o EULA.

Porque evitar
Além de não serem requeridos, notadamente
ninguém os lê.
Tutorial
PATTERN
Categoria Exemplo
Welcome Experience

Como funciona
Durante as boas vindas, o usuário recebe uma
pequena lição de como usar o app.

Quando e como usar


Quando o app tiver funcionalidade não muito óbvias
para o usuário (que passem despercebidas em um
teste de usabilidade). Deve aparecer apenas na
primeira execução do app, mas acessível em outros
momentos.

Por que usar


Utilize para evitar a frustração do usuário.
List of Links (Springboard, Hub-and-Spoke)
PATTERN
Categoria Exemplo
Home Screen

Como funciona
A tela inicial atua como uma área que apresenta links
e ícones para as funcionalidades primárias do app.

Quando e como usar


Utilizar preferencialmente quando o aplicativo
possuir entre 4 e 9 funcionalidades principais. Muito
popular mas em declínio, o uso de tiles pode
modernizar a sua aparência.

Por que usar


É um dos padrões mais fáceis e intuitivos para um
novato navegar.
Dashboard
PATTERN
Categoria Exemplo
Home Screen

Como funciona
Quando o usuário abre o aplicativo, ele recebe um
instantâneo das informações mais relevantes que ele
precisa saber.

Quando e como usar


A qualquer momento que se possa obter dados que
sejam importantes para o usuário do app. Apresente
estas informações consolidadas graficamente.

Por que usar


Prover informações de maneira agregada e
instantânea é um aspecto crucial do paradigma móvel
Updates
PATTERN
Categoria Exemplo
Home Screen

Como funciona
A tela inicial exibe uma ou mais marcações ou
mensagens na linha de tempo do usuário no app.

Quando e como usar


Utilizar quando o usuário tiver interesse em ser
regularmente atualizado. Bastante útil em apps
guiados por comunicação, como os de redes sociais e
de email.

Por que usar


Para manter o usuário atualizado e engajado no uso
do aplicativo.
Skeuomorphic
PATTERN
Categoria Exemplo
Home Screen, Navigation

Como funciona
Quando uma interface é desenhada para ficar similar
à sua contraparte do mundo real.

Quando e como usar


Utilizar quando a usabilidade do seu aplicativo for
beneficiada ao emular um objeto ou ferramenta do
mundo real. Seu uso mais comum é em apps de
jogos.

Por que usar


Para tornar o uso do aplicativo mais intuitivo.
Browse
PATTERN
Categoria Exemplo
Home Screen

Como funciona
Quando a tela inicial carrega, são exibidos alguns
itens atualizados e categorias de itens de interesse
do usuário.

Quando e como usar


Sempre que o seu app tiver algum conteúdo que
possa ser de interesse do usuário.

Por que usar


Incentiva o usuário a navegar pelo seu conteúdo.
Map
PATTERN
Categoria Exemplo
Home Screen, Navigation

Como funciona
Quando a tela carrega, ela exibe um mapa da área da
localização do usuário e exibe pontos de interesse
do usuário relacionados ao aplicativo.

Quando e como usar


Utilize em qualquer momento que informações
geocêntricas sejam de interesse e possam ser
apontadas no mapa.

Por que usar


Com o auxilio do GPS você pode fornecer
informações em um mapa no contexto do usuário.
Side Drawer (Drawable Menu)
PATTERN
Categoria Exemplo
Navigation

Como funciona
Ao deslizar de fora da tela (esquerda) para o centro,
um menu de opções é exibido para o usuário. É
comum que o drawer também seja exibido no ícone
hamburguer.

Quando e como usar


Utilize o Side Drawer quanto o app possuir uma
funcionalidade que seja nitidamente a principal, ao
invés de levar o usuário a uma lista de opções.

Por que usar


O Side Drawer é um padrão emergente.
Integration: The Final Frontier
PATTERN
Categoria Exemplo
Navigation

Como funciona
Quando as necessidades dos seus usuários excedem
as capacidades do seu app, você precisa navegar para
um app diferente que complete a tarefa para o
usuário.

Quando e como usar


Use este padrão a qualquer momento que o seu app
precise prover serviços já consolidados em outro
aplicativo familiar para o usuário.

Por que usar


Não reinvente a roda.
Popover Menu
PATTERN
Categoria Exemplo
Navigation

Como funciona
Quando o usuário toca em ações, um menu pop-up
com mais ações é aberto para revelar mais opções
para este usuário.

Quando e como usar


Quando o app tiver mais ações disponíveis para o
usuário do que o espaço limitado da tela comporte.

Por que usar


A complexidade dos aplicativos aumenta a cada dia e
o toque com o dedo na tela não tem a mesma
precisão do que um clique com um mouse.
ANTI
Pogosticking
P TTERN
Categoria Exemplo
Navigation

Quando e como acontece


Acontece no momento em que cada item de uma
listView está ligado à uma tela de detalhamento
que contém informação adicional. Quando os itens
da lista não provêm informações suficientes, o
usuário é forçado a ficar navegando entre itens e
detalhes até achar o que realmente está procurando.

Porque evitar
Você não deve desperdiçar o tempo do usuário. Caso
o usuário se sinta perdido ao procurar a informação
no pogosticking, ele irá desinstalar o app.
Toolbar
PATTERN
Categoria Exemplo
Tools

Como funciona
A barra de ferramentas é uma das formas mais
comuns de provês ações específicas de uma tela.

Quando e como usar


Cada plataforma tem sua terminologia e guias de
uso para a Toolbar. Respeite os guias de uso para
criar uma boa barra de ferramentas.

Por que usar


É um dos padrões mais populares e intuitivo de
todas as plataformas.
Contextual Tools
PATTERN
Categoria Exemplo
Tools

Como funciona
Apresenta ações específicas para um objeto ou
tarefa.

Quando e como usar


Apresentar estas ações apenas quando o contexto
for estabelecido, por exemplo após um
pressionamento longo sobre um item ou em toque
em um botão de expandir.

Por que usar


Para não poluir a interface com botões de ação
desnecessários fora de um contexto.
Search from Toolbar
PATTERN
Categoria Exemplo
Search

Como funciona
Após o usuário tocar no botão de busca (lupa), a
caixa de pesquisa é expandida e num segundo toque
a busca é realizada.

Quando e como usar


A qualquer momento que você tenha uma barra de
ferramentas com algum espaço e que busca seja um
recurso importante para o usuário.

Por que usar


Forma oficial (bancada pela Google) de efetuar
buscas em um aplicativo móvel.
Auto-Complete & Auto-Suggest
PATTERN
Categoria Exemplo
Search

Como funciona
Após o usuário entrar com alguns caracteres no
campo de busca, o app exibe uma "camada" com
sugestões de palavras para o usuário, que decide
escolher uma das sugestões ou continuar digitando.

Quando e como usar


A qualquer momento que uma palavra-chave possa
ser usada para buscar informações no seu app.

Por que usar


Padrão para buscas explícitas. Evita o fat-finger.
Tap Ahead & Auto-Suggest
PATTERN
Categoria Exemplo
Search

Como funciona
Implementa o Auto-Suggest uma palavra por vez,
através de uma espécie de navegação por
palavras-chave.

Quando e como usar


Utilizar quando a auto-sugestão não é restrita a
busca por palavras sozinhas, mas voltada pra
orações.

Por que usar


Evita o problema da dificuldade de digitar num
dispositivo móvel e a intermitência de sinal.
Search Results (View Results)
PATTERN
Categoria Exemplo
Search

Como funciona
Após uma busca ser efetuada, os resultados são
exibidos na mesma tela ou em uma tela dedicada.

Quando e como usar


Os resultados podem ser exibidos em uma tabela,
em listas, em cards, em um mapa, como miniaturas
ou em caso de resultado único, já em uma tela de
detalhamento.

Por que usar


O objetivo de qualquer busca é a exibição dos
resultados.
ANTI
Separate Search and Refinement
P TTERN
Categoria Exemplo
Search

Quando e como acontece


A qualquer momento no qual a pesquisa por
palavras-chave e as opções de refinamento estejam
separadas. Apesar deste tipo de comportamento ser
comum no iOS, é considerado um problema no
Android.

Porque evitar
Na mente da maioria das pessoas, busca é uma
atividade iterativa e há pouca distinção entre
palavras-chave, filtros e opções de ordenação. Todas
são ferramentas para encontrar o que elas precisam.
Pull to Refresh
PATTERN
Categoria Exemplo
Search

Como funciona
O usuário é apresentado a uma longa lista de
atualizações, tipicamente ordenada por tempo: mais
recentes primeiro. Quando ele quer atualizar a lista,
ele simplesmente a puxa para baixo.

Quando e como usar


Sempre que o aplicativo apresentar resultados de
buscas ou atualizações ordenadas por "mais
recentes primeiro".

Por que usar


Usa um gesto ao invés de um botão; é intuitivo.
Tabs
PATTERN
Categoria Exemplo
Sorting and Filtering, Navigation

Como funciona
Abas no topo da tela permitem que o usuário
alternem entre views ou apliquem opções de
filtragem e ordenação.

Quando e como usar


Quando um grande conjunto de informações puder
ser segmentado em "baldes" de informações e
quando o usuário precisar alternar rapidamente
entre diferentes visões.

Por que usar


Fácil de descobrir e intuitivo de utilizar.
Parallel Architecture
PATTERN
Categoria Exemplo
Sort and Filtering

Como funciona
Os resultados podem ser acessados de duas formas:
através de uma busca simples ou através de uma
busca avançada com mais opções.

Quando e como usar


Quando as condições de busca puderem ser melhor
alcançadas com uma busca minimalista, mas em que
haja casos nos quais a busca avançada seja a ideal.

Por que usar


Oferece ao usuário uma ferramenta de busca
poderosa quando ele domina o aplicativo.
Error Messages
PATTERN
Categoria Exemplo
Feedback and Affordance, Forms

Como funciona
Acontece algum erro de validação ou navegação no
app e o usuário é informado acerca do problema.

Quando e como usar


As mensagens de erros devem ser expressas em
texto plano (sem códigos), indicar precisamente o
problema, e sugerir uma solução construtiva. Devem
ser preferencialmente exibidas na tela ao invés de
em uma caixa de diálogo modal.

Por que usar


Prover feedback ao usuário caso algo dê errado.
Confirmation
PATTERN
Categoria Exemplo
Feedback and Affordance

Como funciona
Provê uma confirmação quando uma ação é tomada.

Quando e como usar


Evite usar janelas de confirmação. Utilize recursos
de confirmação que não interrompam o fluxo do
usuário. Mensagens Toast e Snackbars são ótimos
recursos para oferecer feedback transiente.

Por que usar


O paradigma mobile considera que o usuário sempre
efetua uma ação corretamente.
ANTI
Idiot Boxes
P TTERN
Categoria Exemplo
Feedback and Affordance

Quando e como acontece


"Uma pessoa entra em um estado mental altamente
produtivo trabalhando em harmonia com suas
ferramentas. Interromper o fluxo do usuário sem
bons motivos é parar os procedimentos com idiotice"
- Alan Cooper

Porque evitar
O usuário sabe o que está fazendo. Mensagens de
confirmação desnecessárias só o perturbam.

Dica
Ofereça opções de desfazer para ações arriscadas.
System Status
PATTERN
Categoria Exemplo
Feedback and Affordance

Como funciona
Mostra para o usuário indicadores de carregamento
e processamento.

Quando e como usar


Quando um carregamento demorado é executado,
como aqueles que dependem de conexão com a
internet. Mas sempre que possível torne estes
carregamentos menos perceptíveis para não
incomodar o usuário.

Por que usar


Para dar feedback do estado do sistema ao usuário.
Tap
PATTERN
Categoria
Feedback and Affordance

Como funciona
Torna visível quando os elementos da UI são tocáveis.

Quando e como usar


Com o aumento da popularidade do design flat a usabilidade de alguns
apps diminuiu. Utilize as informações dos guias de uso oficiais pois os
usuários reconhecerão as áreas de toque mais facilmente.

Por que usar


Para promover o reconhecimento dos elementos de tela no oceano flat.
Swipe / Flick
PATTERN
Categoria Exemplo
Feedback and Affordance

Como funciona
Torna reconhecível quando uma interação de deslizar
está disponível no app.

Quando e como usar


Exiba conteúdo além das bordas e usuário entenderá
que há mais informação para ser visualizada. Animações
que reajam ao toque em um elemento capaz de receber
o swipe também o tornam reconhecível.

Por que usar


A ação de deslizar é intuitiva, mas nem sempre o usuário
percebe que pode ser utilizada.
Drag
PATTERN
Categoria Exemplo
Feedback and Affordance

Como funciona
Permite que o usuário arraste componentes de UI ou
delimite áreas com um toque de arrastar.

Quando e como usar


No mobile a ação de arrastar geralmente é acessada em
um modo específico, como num modo de edição ou num
pressionamento longo. Um indicador de alça também
pode tornar reconhecível esta ação.

Por que usar


Apesar de pouco reconhecíveis, os elementos arrastáveis
oferecem boa usabilidade ao aplicativo.
ANTI
Square Peg in a Round Hole
P TTERN
Categoria Exemplo
Feedback and Affordance

Quando e como acontece


Geralmente é o resultado de uma decisão infundada
tomada no nível executivo, ou numa tentativa de
entrar no mercado rapidamente, ou de ambas.
Ferramentas mágicas geradoras de código ou
aplicativos híbridos também podem causar este tipo
de efeito.

Porque evitar
Gera desconforto aos usuários da plataforma original
pois prejudica o reconhecimento dos elementos de
UI e comprometem a usabilidade dos apps.
Social Registration
PATTERN
Categoria Exemplo
Social Patterns

Como funciona
Quando um app solicita que o usuário permita que
este aplicativo utilize suas credenciais de uma rede
social para se autenticar.

Quando e como usar


Utilizar quando você necessitar de um registro rápido
ou que garanta a unicidade de um usuário.

Por que usar


Facilita o processo de registro e o usuário não terá
mais uma combinação de usuário e senha para lembrar.
Por que o seu app mereceria um registro exclusivo?
Gamification
PATTERN
Categoria Exemplo
Social Patterns

Como funciona
Uso de elementos de jogos em um não-jogo.

Quando e como usar


Mais do que prover insígnias, você pode incluir
elementos de subir de nível, pontuações e placar de
líderes. Tome muito cuidado com a ludificação, seu
uso inadequado ou uma implementação mal feita
pode ser um tiro pela culatra.

Por que usar


Elementos de ludificação geram engajamento e
fidelização dos usuários.
ANTI
Lack of Interface Efficiency
P TTERN
Categoria Exemplo
Avoiding Missing and Undersirable Results

Quando e como acontece


Este anti-padrão é comum em aplicativos que não
gastaram tempo suficiente projetando interfaces de
tratamento de erros e mecanismos de recuperação.
Ao invés disto culpam o usuário exibindo mensagens
de erros ou janelas que exibam um toque adicional
pra dispensar.

Porque evitar
Irritam o usuário causando frustração.
Did You Mean?
PATTERN
Categoria Exemplo
Avoiding Missing and Undersirable Results

Como funciona
O usuário informa uma palavra-chave que não é
reconhecida na pesquisa, mas o sistema oferece um
conjunto de substituições semelhantes à entrada
original.

Quando e como usar


Quando você tiver um vocabulário controlado em
suas buscas e seja fácil identificar erros de digitação.

Por que usar


Evita o fat-finger e ajuda e diminuir a falta de
resultados ou os resultados inesperados.
Textbox with Input Mask
PATTERN
Categoria Exemplo
Data Entry

Como funciona
Quando um determinado campo aceita apenas um
tipo específico de dados, como um e-mail, número de
telefone, ou CEP, o aplicativo pode oferecer o tipo
correto de teclado.

Quando e como usar


Sempre que usuários precisem informar dados em um
EditText forneça a eles o tipo correto de teclado.

Por que usar


Dispositivos móveis são notoriamente ruim em
capturar entrada de dados via teclado.
Textbox with Atomic Entities
PATTERN
Categoria Exemplo
Data Entry

Como funciona
O usuário inicia uma busca utilizando caracteres,
mas o sistema efetua uma busca dinâmica e retorna
entidades atômicas (ou discretas) como resultado.

Quando e como usar


Utilizar quando você o sistema permitir que uma ou
mais entidades de uma longa coleção (50 ou mais
objetos) em um simples campo. Estas entidades
podem representar Contatos, Aeroportos, etc.

Por que usar


Às vezes um nome ou id não é tão representativo.
Callback Validation
PATTERN
Categoria Exemplo
Forms

Como funciona
O dado informado pelo usuário é validado em um
servidor de maneira assíncrona, retornando os estados
de falha ou conformidade e a UI precisa ser atualizada.

Quando e como usar


Quando a validação do lado cliente não for robusta ou
conter informação suficiente para efetuar a validação,
utilize este padrão como método preferido de validação.

Por que usar


Provê uma validação consistente e ao mesmo tempo
trata problemas de conexão intermitente.
Cancel / OK
PATTERN
Categoria Exemplo
Forms

Como funciona
No Android o padrão de posicionamento dos botões
em um formulário ou caixa de diálogo é Cancel / OK
e não OK / Cancel.

Quando e como usar


Padrão que deve ser utilizado em cada formulário do
seu aplicativo. Nunca inverter.

Por que usar


A maior parte dos usuários é destra, e o botão OK
ficará mais acessível ao toque do polegar.
Top-Aligned Labels
PATTERN
Categoria Exemplo
Forms

Como funciona
Quando o formulário é apresentado ao usuário e seus
labels aparecem acima dos campos de entrada.

Quando e como usar


A qualquer momento que você apresentar um formulário
ao usuário que contenha labels. Para EditText, um hint
pode ser o suficiente, mas a implementação ótima é que
o hint se torne um Top-Aligned Label quando o EditText
ganhar o foco.

Por que usar


É versátil e provê bastante usabilidade no mobile.
Getting Input from the Enviroment
PATTERN
Categoria Exemplo
Forms

Como funciona
Quando um formulário precisa ser preenchido o
dispositivo móvel usa seus recursos físicos (sensores de
voz, gestos, acelerômetro, localização, imagens, vídeo e
luz ambiente) como forma de entrada de dados.

Quando e como usar


Sempre que você tiver um formulário ou funcionalidade
pense: quais entradas eu posso obter do ambiente?

Por que usar


Dados do ambiente são mais eficientes, efetivos e
praticamente exclusivos aos dispositivos móveis.
Apêndice III:
Livros Recomendados
Mobile e UX
Descrição
Com quase 200 páginas, é um livro bastante abrangente
sobre a prototipação em papel.

Prós
Ebook de preço acessível para kindle.

Contras
Não existe versão impressa.
Mobile e UX
Descrição
Livro sobre prototipação mobile de alta fidelidade.

Prós
Linguagem clara e objetiva, com várias dicas específicas
para a prototipação mobile com uma ferramenta
poderosa, o Axure.

Contras
O Axure é uma ferramenta cara, e está disponível apenas
para Windows e Mac OS X.
Mobile e UX
Descrição
Livro sobre padrões de projeto para mobile.

Prós
Com qualidade visual impecável, este livro não se restringe
apenas a Android, mas também apresenta design patterns
para iOS e Windows Phone, inclusive apresentando
diferenças aplicáveis a cada plataforma.

Contras
Pré Material Design, suas imagens estão começando a ficar
desatualizadas.
Android
Descrição
Livro bastante abrangente de Android.

Prós
Livro bastante completo e, de longe, o melhor livro de
Android já escrito. Equilibra muito bem teoria e prática
com exercícios muito interessantes. Uma atualização está
"no forno" (para maio de 2017).

Contras
Está desatualizado.
Android
Descrição
Livro abrangente de Android de autor brasileiro.

Prós
É um livro muito bom, mesmo sendo em português. Não é
um livro superficial.

Contras
Não chega a Android avançado apesar do subtítulo.
Algumas explicações do livro deixam a desejar.
Android
Descrição
Livro de padrões de projeto Android.

Prós
Antes de adentrar nos padrões, o livro apresenta nuances
do paradigma mobile e técnicas de desenvolvimento.

Contras
A versão em português traduz os nomes dos padrões.
Catálogo completo porém desatualizado. Alguns padrões
e anti-padrões não existem mais.
Android
Descrição
Livro de implementação de interface para não designers.

Prós
Fala a língua do desenvolvedor, e não a do designer
gráfico. Com ele um programador de backend consegue
fazer um projeto de UI mais que simplesmente aceitável.
Foco em Material Design. Qualidade e acabamento
primorosos.

Contras
Não é muito extenso, com isto alguns detalhes não são
explorados.
Android
Descrição
Livro de implementação de interface para aplicativos
nativos Android responsivos em smartphones e tablets.

Prós
Livro com linguagem clara e objetiva e visual bem cuidado,
com exemplos coloridos e fonte agradável. Foca em layout
mas também apresenta alguns design patterns.

Contras
Não é um livro muito grande e o preço acaba sendo alto
em relação ao seu conteúdo.
Android
Descrição
Ebook sobre bancos de dados Android.

Prós
Dá uma visão geral da persistência em banco de dados
android. Ebook bastante barato e fácil de "terminar".

Contras
Parece um compilado de um blog. Livro curto e com
conceitos abordados muito superficialmente.
Android
Descrição
Livro avançado de bancos de dados Android. Indicado para
desenvolvedores experientes na plataforma.

Prós
Explica cada mecanismo envolvido e necessário para uma
arquitetura android enterprise.

Contras
Não muito extenso, alguns conceitos não são bem
explicados. Alguns exemplos não são intuitivos.

Você também pode gostar