1. Antes de começar
Este codelab apresenta um novo app, chamado Lemonade, que você vai criar por conta própria. O codelab mostra os passos para concluir o projeto, incluindo a configuração e os testes no Android Studio.
Este codelab é diferente dos outros deste curso. Ao contrário dos codelabs anteriores, o objetivo deste não é fornecer um tutorial detalhado sobre como criar um app. A ideia é configurar um projeto que será concluído de forma independente, com instruções sobre como concluir o app e verificar seu trabalho por conta própria.
Em vez do código da solução, fornecemos um pacote de testes como parte do download do app. Você executará esses testes no Android Studio (mostraremos como fazer isso mais adiante neste codelab) e vai testar se o código é aprovado. Isso pode levar algumas tentativas. Até mesmo desenvolvedores profissionais raramente passam em todos os testes na primeira vez. Depois que seu código passar em todos os testes, considere o projeto como concluído.
Entendemos que talvez você queira apenas uma solução para conferir seu trabalho. Não fornecemos o código da solução deliberadamente, porque queremos que você pratique como é ser um desenvolvedor profissional. Isso pode exigir o uso de diferentes habilidades que você ainda não praticou muito, como:
- pesquisar no Google os termos, mensagens de erro e códigos do app que você não reconhece;
- testar o código, ler erros e fazer mudanças no código para testá-lo novamente;
- voltar ao conteúdo anterior da Unidade 1 de noções básicas do Android para conferir o que você aprendeu;
- Comparar um código conhecido (ou seja, o código fornecido no projeto ou o código anterior da solução em outros apps da Unidade 1) com o código que você está criando.
Isso pode parecer complicado no início, mas temos 100% de certeza de que, se você concluiu a Unidade 1, já pode começar o projeto. Leve o tempo que precisar e não desista. Você consegue.
Pré-requisitos
- Este projeto é destinado para usuários que concluíram a Unidade 1 do curso Princípios básicos do Android em Kotlin.
O que você vai criar
- Você criará um app Lemonade simples usando as habilidades que aprendeu na Unidade 1.
Pré-requisitos
- Um computador com o Android Studio instalado.
2. Visão geral do app
Este é o projeto do app Lemonade.
Nossa equipe precisa de você para nos ajudar a realizar nosso sonho de criar uma limonada digital. O objetivo é criar um app para dispositivos móveis simples e interativo que permita espremer limões até ter um copo de limonada. Considere isso uma metáfora ou apenas uma forma divertida de passar o tempo.
O app Lemonade concluído terá uma única tela. Quando os usuários iniciarem o app pela primeira vez, eles receberão uma solicitação para escolher um limão tocando na imagem de um limoeiro.
Ao tocar no limoeiro, o usuário verá um limão e poderá tocar nele para o "espremer" um número não especificado de vezes (o número exato necessário é gerado aleatoriamente) antes de passar para a próxima tela.
Depois que o usuário tocar para espremer o limão o número certo de vezes, ele verá a imagem de um copo para "tomar" a limonada.
Depois de clicar para beber a limonada, o copo ficará vazio, e o usuário poderá tocar na imagem novamente para retornar à primeira tela e selecionar outro limão na árvore.
O app foi criado com foco em simplicidade e organizado em uma única atividade. Os diferentes estados do app (se o usuário está selecionando um limão, o espremendo, bebendo limonada e, finalmente, o copo vazio) são representados por algo conhecido como máquina de estado. Parece um termo teórico sofisticado, mas significa que o estado do app, ou seja, qual texto e imagem serão mostrados ao usuário, é determinado por uma variável que contém o estado do app (select
, squeeze
etc.). O estado do app é atualizado, com outras variáveis necessárias, e a IU é configurada (exibindo a imagem e o texto) separadamente, assim que todas as atualizações são feitas.
Todas as variáveis para o estado do app foram definidas para você. Sua tarefa é criar o layout do app e implementar a lógica para que a IU faça a transição entre cada estado conforme o esperado.
Testar o código
Para o app Lemonade (e projetos futuros), são fornecidos alguns testes automatizados que podem ser usados para verificar se o código funciona como esperado.
O que são testes automatizados? Em termos de desenvolvimento de software, pense em um "teste" como um código que verifica se outro código está funcionando. Isso é feito verificando as saídas, por exemplo, o conteúdo dos elementos da IU na tela, para ver se elas fazem sentido com base nas entradas, conhecidas como "casos de teste". O projeto inicial do app Lemonade inclui alguns testes que você poderá executar para garantir que a lógica foi implementada corretamente. Discutiremos os testes em mais detalhes posteriormente. Por enquanto, faça o download do código inicial e comece a criar o app Lemonade.
3. Começar
Fazer o download do código do projeto
O nome da pasta é android-basics-kotlin-lemonade-app
. Selecione essa pasta ao abrir o projeto no Android Studio.
Para encontrar o código deste codelab e abrir no Android Studio, faça o seguinte.
Acessar o código
- Clique no URL fornecido. Isso vai abrir a página do GitHub referente ao projeto em um navegador.
- Verifique e confirme se o nome da ramificação mostrado corresponde ao nome da ramificação especificado no codelab. Por exemplo, na captura de tela a seguir, o nome da ramificação é main.
- Na página do GitHub do projeto, clique no botão Code, que vai mostrar uma janela pop-up.
- Na janela pop-up, clique no botão Download ZIP para salvar o projeto no seu computador. Aguarde a conclusão do download.
- Localize o arquivo no computador. Geralmente ele é salvo na pasta Downloads.
- Clique duas vezes para descompactar o arquivo ZIP. Isso cria uma nova pasta com os arquivos do projeto.
Abrir o projeto no Android Studio
- Inicie o Android Studio.
- Na janela Welcome to Android Studio, clique em Open.
Observação: caso o Android Studio já esteja aberto, selecione a opção File > Open.
- No navegador de arquivos, vá até a pasta descompactada do projeto, que provavelmente está na pasta Downloads.
- Clique duas vezes nessa pasta do projeto.
- Aguarde o Android Studio abrir o projeto.
- Clique no botão Run
para criar e executar o app. Confira se ele é compilado da forma esperada.
Reserve um momento para se familiarizar com o projeto inicial. Preste atenção especial ao arquivo MainActivity.kt
.
No MainActivity.kt
, você encontrará diversas variáveis usadas para representar o estado atual do app. Elas serão usadas em uma etapa posterior para tornar o app interativo. Embora a quantidade de código aqui possa parecer complexa, não é necessário modificar nenhum código que não esteja marcado com TODO. Instruções específicas são fornecidas nas páginas a seguir.
Observe que o projeto também inclui outro pacote, com.example.lemonade (androidTest).
Esse pacote inclui os testes automatizados que você vai usar para verificar se a funcionalidade que implementou em MainActivity.kt
está correta. Mais detalhes serão explicados posteriormente. Por enquanto, está tudo pronto para você começar a criar o app, começando com a interface do usuário.
4. Criar a interface do usuário
O app Lemonade precisa de um layout básico. Você só precisa de duas visualizações para implementar todas as funcionalidades.
- Uma
TextView
que fornece instruções ao usuário. - Uma
ImageView
que mostra um gráfico com base no estado atual do app (por exemplo: um limão para ser espremido).
Você criará esse layout em activity_main.xml
.
Usando seus conhecimentos sobre o Layout Editor, o objetivo é criar um layout semelhante ao exemplo abaixo, com as visualizações centralizadas na tela e a TextView
acima da ImageView
.
5. Tornar o app interativo
Quando o layout estiver concluído, abra MainActivity.kt
. É neste arquivo em que você implementará toda a lógica do app. Você perceberá que ele já tem bastante código. Há também muitos comentários marcados com // TODO:
, como no exemplo abaixo. Esses comentários marcam as tarefas que você irá concluir.
Existem três coisas básicas que você precisa implementar para que o app Lemonade funcione.
- Configurar a
lemonImage
daImageView
para responder à entrada do usuário. - Implementar o método
clickLemonImage()
para atualizar o estado do app. - Implementar o método
setViewElements()
para atualizar a IU com base no estado atual do app.
Vamos analisar uma tarefa por vez.
Etapa 1: configurar a ImageView
Tocar na visualização da imagem precisa mover o app de um estado para outro. No final do método onCreate()
, observe que há dois listeners que precisam ser definidos.
setOnClickListener()
precisa atualizar o estado do app. O método para fazer isso éclickLemonImage()
.setOnLongClickListener()
responde a eventos em que o usuário toca em uma imagem e a mantém pressionada, por exemplo, toca na imagem e não solta o dedo imediatamente. Para eventos de "tocar e manter pressionado", um widget, chamado de "snackbar", é exibido na parte inferior da tela. Nela, o usuário saberá quantas vezes ele espremeu o limão. Isso é feito usando o métodoshowSnackbar()
.
Na próxima etapa, você implementará a lógica para alterar o estado do app.
Etapa 2: implementar clickLemonImage()
Depois de concluir a etapa anterior, o método clickLemonImage()
será chamado sempre que o usuário tocar na imagem. Esse método é responsável por passar o app do estado atual para o próximo e atualizar as variáveis conforme necessário. Há quatro estados possíveis: SELECT
, SQUEEZE
, DRINK
e RESTART
. O estado atual é representado pela variável lemonadeState
. Esse método precisa fazer algo diferente para cada estado.
SELECT
: muda para o estadoSQUEEZE
, definelemonSize
(o número de espremidas necessárias) chamando o métodopick()
e definindosqueezeCount
(o número de vezes que o usuário espremeu o limão) como 0.SQUEEZE
: incrementa asqueezeCount
em 1 e reduz olemonSize
em 1. Não esqueça que um limão precisa de um número variável de espremidas antes que o app faça a transição do estado. Mude para o estadoDRINK
apenas se o novolemonSize
for igual a 0. Caso contrário, o app permanecerá no estadoSQUEEZE
.DRINK
: muda para o estadoRESTART
e definelemonSize
como -1.RESTART
: volta para o estadoSELECT
.
Depois de processar todas as atualizações e transições entre estados, chame setViewElements()
para atualizar a IU com base no novo estado.
Etapa 3: implementar setViewElements()
O método setViewElements()
é responsável por atualizar a IU com base no estado do app. O texto e a imagem precisam ser atualizados com os valores mostrados abaixo para corresponder a lemonadeState
.
SELECT
:
- Texto: Click to select a lemon!
- Imagem:
R.drawable.lemon_tree
SQUEEZE
:
- Texto: Click to juice the lemon!
- Imagem:
R.drawable.lemon_squeeze
DRINK
:
- Texto: Click to drink your lemonade!
- Imagem:
R.drawable.lemon_drink
RESTART
:
- Texto: Click to start again!
- Imagem:
R.drawable.lemon_restart
Como usar recursos de string
No Android, quase tudo é um recurso. Definir recursos que você pode acessar no app é uma parte essencial do desenvolvimento para Android.
Os recursos são usados para qualquer ação, desde a definição de cores, imagens, layouts, menus e valores de strings. A vantagem disso é que nada é fixado no código. Todos os elementos são definidos nesses arquivos de recursos e, em seguida, podem ser referenciados no código do aplicativo. O mais simples dos recursos, e o mais comum, é usar recursos de string para permitir um texto flexível e localizado.
Strings ou texto estático podem ser armazenados em um arquivo separado, chamado "strings.xml", na subpasta de valores da pasta "res".
Para cada trecho do texto que você quer mostrar no aplicativo (por exemplo, o rótulo de um botão ou o texto de uma TextView
), primeiro defina o texto no arquivo res/values/strings.xml
. Cada entrada é uma chave (que representa o código do texto) e um valor (o texto em si). Por exemplo, se você quiser que um botão exiba "Submit" (Enviar), adicione o recurso de string abaixo em res/values/strings.xml
:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="hello">Hello!</string>
<string name="submit_label">Submit</string>
</resources>
Para acessar o recurso diretamente no código, use os métodos getResources.getString()
ou getString()
para acessar o valor considerando o ID do recurso, R.string.submit_label
:
val submitText = getResources().getString(R.string.submit_label)
Para definir diretamente o texto do recurso de string para a TextView, chame o método setText()
no objeto da TextView e transmita o ID do recurso.
val infoTextView: TextView = findViewById(R.id.info_textview)
infoTextView.setText(R.string.info_text)
Os recursos de string também podem conter caracteres especiais para formatar o texto. Por exemplo, você pode ter um recurso de string que permite inserir outro trecho de texto na string:
<string name="ingredient_tablespoon">%1$d tbsp of %2$s</string>
No código, você acessaria e formataria o recurso da string transmitindo argumentos:
getResources().getString(R.string.ingredient_tablespoon, 2, "cocoa powder")
Ao declarar o recurso da string, cada argumento é numerado na ordem em que aparece (1
, 2
etc.) e tem uma letra para identificar o tipo (d
para números decimais, s
para string etc.). Argumentos do tipo correto podem ser transmitidos para a chamada do método getString()
:
2 tbsp of cocoa powder
Para saber mais, consulte a documentação sobre recursos de string.
6. Executar o app
Depois de criar a IU do app e implementar a atividade principal, é hora de ver seu trabalho em ação. Execute o app usando o menu Run > Run 'app', para iniciar o emulador.
Agora, o app deve estar totalmente interativo, e você pode tocar na visualização da imagem para mudar os estados.
Enquanto o limão estiver na tela, você também vai poder tentar tocar na ImageView
e a manter pressionada para conferir a snackbar na parte de baixo, revelando o número total de vezes que o limão foi espremido. Passe um tempo para percorrendo o app em todos os estados algumas vezes. Em seguida, passe um tempo comemorando os resultados do seu esforço.
7. Instruções sobre testes
Testar o app
Você terminou de implementar o app Lemonade, mas, no desenvolvimento de software profissional, criar o código raramente é a última etapa. Além do código do aplicativo, apps de qualidade profissional também incluem códigos de teste que são executados para verificar se o código funciona conforme o esperado e se alterações nele não introduzem novos bugs, um processo chamado de "teste automatizado". Embora o ensino de testes automatizados esteja além do escopo deste projeto, o app Lemonade vem com alguns testes que ajudam a verificar se você o implementou corretamente. Use-os como uma autoavaliação para ver se atendeu a todos os requisitos do projeto e se é necessário fazer mudanças no app.
O que é um "teste" exatamente? Os testes são partes do código incluído no projeto do Android Studio que executam parte do código do app e podem ser "aprovados" ou "reprovados", dependendo do código do app ter o comportamento esperado ou não.
Onde você encontra e executa os testes do app? Os testes do app Lemonade estão disponíveis no destino de teste. Um destino é um termo de desenvolvimento de software para uma coleção de classes agrupadas. Por exemplo, o app Lemonade existe em um destino chamado "app", enquanto os testes existem em um destino chamado "LemonadeTests". Embora o destino LemonadeTests possa acessar o código do destino do app, eles são completamente separados, e o código do app não contém nenhum código de teste.
Ao visualizar os arquivos na visualização "Android", o destino do teste será exibido com o mesmo nome de pacote do app, mas com (androidTest) entre parênteses.
Também há alguns termos importantes que você precisa conhecer ao se referir ao código de teste.
- Pacote de testes: o destino que inclui todos os casos de teste.
- Caso de teste: uma classe que consiste em testes individuais de funcionalidades relacionadas. O app Lemonade tinha apenas um único caso, mas os apps maiores muitas vezes têm muito mais.
- Teste: uma função que testa algo específico.
Um caso de teste pode ter vários testes e o conjunto de testes do projeto pode ter vários casos de teste.
Como executar os testes
Para executar os testes, escolha uma das opções a seguir.
Para um único caso de teste, abra uma classe de caso de teste e clique na seta verde à esquerda da declaração da classe. Em seguida, selecione a opção "Run" no menu. Isso executará todos os testes do caso.
Na maioria das vezes, convém executar apenas um teste, por exemplo, se apenas um teste for reprovado e os outros forem aprovados. Você pode executar um único teste da mesma forma que faria com todo o caso de teste. Use a seta verde e selecione a opção Run.
Se você tiver vários casos de teste, também poderá executar todo o conjunto de testes. Assim como na execução do app, você encontra essa opção no menu Run.
O Android Studio usa como padrão o último destino que você executou (app, destinos de teste etc.). Portanto, se o menu ainda mostrar Run > Run 'app', você pode executar o destino de teste selecionando Run > Run.
Em seguida, escolha o destino do teste no menu pop-up.
Os resultados da execução dos testes serão exibidos na guia Run. No painel à esquerda, aparece uma lista de testes reprovados, se houver algum. Os testes reprovados são marcados com um ponto de exclamação vermelho ao lado do nome da função. Os testes aprovados são marcados com uma marca de seleção verde.
Se um teste for reprovado, o texto do resultado fornecerá informações para ajudar você a corrigir o problema.
Por exemplo, na mensagem de erro acima, o teste verifica se um TextView
está usando um recurso de string específico. No entanto, o teste é reprovado. O texto após "Expected" (esperado) e "Got" (recebido) não coincide, ou seja, o valor esperado para o teste não corresponde ao valor do app em execução. Nesse exemplo, a string usada na TextView
não é squeeze_count
, como esperado pelo teste.
8. Opcional: compartilhe seu app!
Quando terminar de tomar vários copos de limonada, faça uma captura da sua tela favorita e a compartilhe no Twitter para mostrar o que você aprendeu. Marque @AndroidDev e adicione a hashtag #AndroidBasics.