Como fazer um aplicativo quiz para Android

Um dos aplicativos mais lucrativos que já fiz foi um que fiz para a Renault. Falar assim soa bem imponente né? A história é um pouco menos glamurosa que isso, mas basta saber que o app em questão era um quiz (jogo de perguntas e respostas) para o evento Renault Experience do ano de 2013, visando testar os conhecimentos dos visitantes do evento que aconteceu na UFPR.

Obviamente eu não posso fornecer os fontes do app aqui, uma vez que eu vendi o projeto e os direitos intelectuais, mas posso ensinar vocês a fazer uma versão mais simples que depois vocês podem incrementar!

Veremos neste post:

  1. Criando uma splash screen
  2. Criando o quiz
  3. Criando a tela de resposta certa/errada
  4. Deixando tudo mais dinâmico
  5. Adicionando mais perguntas ao quiz
  6. Finalizando o app

Vamos lá?

Atenção: se esse é seu primeiro app Android, sugiro dar uma olhada neste outro post aqui que é mais básico: Tutorial Android Studio.

#1 – Criando uma splash screen

A splash screen é a tela inicial de qualquer jogo, onde temos o logo/título do mesmo e um botão de jogar que inicia o jogo em si, bem fácil de criar.

Crie um novo projeto no Android Studio com o nome de LuizQuiz (ok, pode criar com outro nome se quiser…) e com uma Empty Activity dentro. Nossa MainActivity será a Splash Screen, e no layout dela, vamos adicionar uma ImageView e um Button com a propriedade text=Jogar e id=btnJogar. A propriedade src da ImageView deve apontar para uma imagem na sua pasta res/drawable, sendo que aqui eu criei uma usando o Canva.com, o mesmo software online que uso para criar as capas de meus livros.

A imagem abaixo mostra como deve se parecer essa tela depois de pronta (apenas posicione os elementos e depois clique no botão de Infer Constraints como explicado no Tutorial de Constraint Layout). Quando você arrastar uma ImageView para seu layout é bem provável que o Android Studio já abra uma tela para procurar pela sua imagem:

LuizQuiz
LuizQuiz

A cor laranja de fundo eu coloquei colocando a propriedade:

na tag de ConstraintLayout que fica na raiz do XML de layout. Se quiser um botão mais bonito do que o que usei, basta criar uma imagem de botão e usar um ImageButton com essa imagem ao invés do Button normal.

Caso esteja com problemas para criar essa tela, segue abaixo o código XML completo:

Agora clique com o botão direito do mouse sobre a pasta do projeto e mande adicionar uma nova Activity do tipo EmptyActivity à ele, que vamos chamar de QuizActivity. Programaremos esta Activity mais tarde, por enquanto apenas deixe ela lá, com seu layout XML em branco mesmo.

Para finalizar nossa Splash Screen, temos de permitir que quando o usuário tocar no botão Jogar, que o app troque de tela, para a QuizActivity que acabamos de criar. Para fazer isso, primeiro sinalizei no XML do Button a propriedade onClick=btnJogarOnClick (o código XML anterior já inclui essa alteração). Esse é o nome do método que deve existir na MainActivity que vai ser disparado quando o botão for clicado.

O método em questão deve ser como abaixo, invocando a tela seguinte através de um Android Intent. Coloque-o na sua MainActivity, logo após o método onCreate que já vem por padrão.

Com isso, a sua splash screen já deve estar funcionando. Agora vamos à tela do quiz em si.

#2 – Criando o quiz

Vamos ter uma única Activity para exibir as perguntas, sendo que cada pergunta será exibida uma por vez. Para começar, vamos estruturar o layout XML da QuizActivity para que mostre uma pergunta falsa, apenas para deixarmos tudo pronto para as verdadeiras que vamos adicionar depois.

Vamos adicionar um TextView para a pergunta (coloque uma qualquer no text dele e defina o appearance como algo maior que o padrão Small), um RadioGroup para as opções (cada opção deve ser um RadioButton diferente dentro do RadioGroup) e um botão com text=Responder. A ideia é que sua interface se pareça com a abaixo:

LuizQuiz
LuizQuiz

Se estiver tendo problemas para posicionar os elementos na tela com o ConstraintLayout, você pode usar outro como Relative Layout ou mesmo Linear Layout, que são mais fáceis (e menos poderosos). Eu faço rapidamente jogando os widgets na tela, e quando o Infer Constraints (o botão com ícone de estrela amarela que fica logo acima do Layout Editor) não resolve tudo sozinho, eu crio as constraints horizontais de cada widget para fixá-lo à tela e depois seleciono todos widgets segurando Ctrl e uso a opção Center Vertically que aparece clicando com o botão direito do mouse, o que cria as constraints verticais automaticamente.

Se achar que é muito trabalho, apenas copie o layout XML abaixo que representa a tela acima:

O fluxo que quero fazer é o seguinte: você clica em responder, vai para uma tela que te diz se você acertou ou não, e depois volta para essa tela com uma nova pergunta para responder. Para fazer esse fluxo, precisamos adicionar uma nova activity ao projeto (do tipo Empty) que chamarei de RespostaActivity. Não vamos mexer nela agora, apenas crie a mesma vazia.

Volte ao XML da QuizActivity e mude os ids de alguns componentes para:

  • TextView: pergunta;
  • RadioGroup: rgRespostas;
  • RadioButton das respostas: rbResposta1 até rbResposta4;
  • Button: btnResponder;

E no Button, adicione na propriedade onClick=btnResponderOnClick, que é o nome do método que vamos criar na classe QuizActivity para fazer a troca de tela. Mas desta vez não será uma troca de tela simples, pois passaremos a informação se o usuário acertou ou não a pergunta, para que o app avise ele. Para fazer isso, usaremos os Extras.

Note que carreguei o widget RadioGroup para uma variável local para poder pegar o Id do RadioButton interno que foi selecionado. Já fiz isso em outros tutoriais aqui no blog, nada de novo por aqui. Também comparei fixamente qual é a resposta certa, comparando com o id do RadioButton da primeira resposta (mudaremos isso mais tarde).

Com isso encerramos essa etapa da sua tela de quiz. Voltaremos à ela mais tarde.

Atenção: sugiro executar o emulator Android (ou testar de alguma outra maneira) a cada uma das etapas deste tutorial para se certificar que está tudo funcionando como deveria. São etapas simples de troca de tela, mas que se não estiverem funcionando agora, vão te gerar problemas depois.

#3 – Criando a tela de resposta certa/errada

Agora vamos terminar a nossa RespostaActivity. Ela vai ser bem simples, vai mostrar uma imagem de sucesso ou de fracasso, conforme a resposta que chegar da tela anterior. Neste momento, essa avaliação é falsa, porque a pergunta da tela anterior também o é. Estou apenas estruturando toda aplicação contigo para depois colocarmos a “inteligência” nela.

Nesta tela, além do fundo laranja que você pode copiar dos outros layouts (propriedade background, lembra?) nós vamos adicionar um ImageView com uma de duas imagens que você pode obter facilmente na Internet, designando sucesso ou fracasso. Também vou adicionar um TextView logo abaixo com a mensagem em texto, caso a imagem não seja óbvia. Não, não vou colocar um botão de voltar aqui, vamos fazer algo mais interessante logo mais à frente.

A sua interface de resposta falsa deve se parecer com essa:

LuizQuiz
LuizQuiz

Caso esteja com alguma dificuldade, segue o layout XML completo abaixo. Note como coloquei ids para o TextView (resposta) e a ImageView (imgResposta), visando manipulá-las mais tarde via código Java:

A dinâmica que vamos fazer com essa tela é a seguinte: o usuário vai responder a pergunta, vai ver esta tela pra saber se acertou ou errou, e depois o próprio app vai sair desta tela e mostrar a próxima pergunta. Para fazer isso automaticamente (e não deixar o usuário descansar), usaremos uma Thread que vai esperar 5s para finalizar a Thread atual, exibindo novamente a tela anterior.

O código abaixo mostra como fazer isso, dentro do onCreate da própria Activity de resposta.

Aqui dois pontos merecem atenção: primeiro, o uso de um thread que ao executar ficará 2000ms (ou 2s) esperando até finalizar a Activity atual. Segundo, se você estava se perguntando como que meu app estava sem a ActionBar do Android no topo (aquele barra azul), eu faço isso chamando getSupportActionBar().hide() como exibido acima.

Se você testar agora o app, você vai ver que após responder a sua única pergunta estática, a tela de resposta vai aparecer e depois voltará para a tela da pergunta. Você pode inclusive testar isso diversas vezes.

Curso React Native

#4 – Deixando tudo mais dinâmico

Para esta tela ficar um pouco mais inteligente, mesmo que provisoriamente, vamos verificar se o usuário acertou ou errou a pergunta da tela anterior para exibir a imagem correspondente. Primeiro, certifique-se de ter as duas imagens na sua pasta drawables (tem vários sites na Internet que você pode baixá-las gratuitamente). Eu chamei uma de acertou e outra de errou.

Através do código abaixo estou verificando se a pergunta anterior foi respondida corretamente ou não e mostra a imagem certa na tela, usando a mesma ImageView, bem como mudando o texto da TextView. Esse código vai no onCreate da RespostaActivity, antes do trecho com a thread que programei antes.

Caso esse código não esteja claro o suficiente, segue uma explicação:

  • nas duas primeiras linhas, carrego em variáveis locais os widgets que irei manipular.
  • na sequência, pego o Intent que foi usado para chegar nessa Activity, visando obter o Extra “acertou” que foi passado junto ao Intent na QuizActivity. Essa informação tem um booleano indicando true ou false.
  • com isso, faço um if para ver se a pessoa marcou a resposta certa e defino a imagem e texto correspondentes.

Outro comportamento que precisamos deixar nosso app preparado é o de quando voltamos à tela de Quiz ele deve exibir outra pergunta, já que hoje ele mostra sempre a mesma. Por ora, vamos apenas trocar aquela pergunta por outra nesta ocasião, que deve ser programada no onRestart da QuizActivity (evento disparado quando esta tela volta a ficar visível).

Para que esse onRestart funcione corretamente, temos de fazer algumas outras alterações nesta QuizActivity. Bem no topo da classe, antes do onCreate, vamos declarar algumas variáveis:

Basicamente estamos declarando variáveis que vamos usar mais tarde, mas uma merece mais atenção aqui: respostaCerta. Nela definiremos qual dos RadioButtons da tela contém a resposta certa para a pergunta atual. Por ora vamos deixar fixo, mas mais tarde esse valor será dinâmico.

Agora, dentro do onCreate desta QuizActivity, vamos carregar os widgets:

E por fim, o método de clique do botão Responder deve ser ajustado para usar a nossa variável respostaCerta, como mostra o bloco completo abaixo, que inclui algumas outras alterações menores como a “desmarcação” da resposta (para não ficar vindo marcado depois).

Opa, mas que variável ‘pontos’ é aquela ali? É um contador de respostas certas. Apenas declare ele como uma variável normal no corpo da classe que deve funcionar. Note que estou passando essa variável para a tela de resposta, para que seja possível personalizar a mensagem da mesma, informando os pontos, etc (use sua criatividade aqui).

Com isso, você consegue testar novamente. A primeira pergunta será a default do descobrimento do Brasil, cuja resposta certa é 1. Independente se você acertar ou errar (o que será apresentando na tela de resposta), você voltará à tela do Quiz com a nova pergunta do site, que nesse caso a resposta correta é 2. Teste no AVD antes de seguir adiante.

#5 – Adicionando mais perguntas ao quiz

Agora que já estruturamos toda nossa aplicação, é hora de adicionarmos as perguntas à ela. Para que este tutorial não fique muito extenso não vou usar banco de dados aqui, mas apenas perguntas salvas na memória do app mesmo, evitando conceitos que podem ser complexos para os iniciantes.

Quem quiser salvar e retornar perguntas de um banco local no app, pode dar uma olhada neste tutorial de SQLite aqui. Já se suas perguntas vão estar em um banco remoto, veja este outro tutorial aqui sobre acesso remoto à banco de dados.

Para armazenar as questões em memória, vamos criar uma nova classe Java em nosso projeto chamada Questao, contendo variáveis para as alternativas e para a resposta certa.

Agora vamos voltar à nossa QuizActivity e vamos criar uma estrutura de dados em memória com uma série de objetos do tipo Questao, incluindo suas alternativas, resposta certa, etc. Não vai ser um primor de arquitetura, mas vai funcionar para um exemplo didático. Coloque esse código no topo da QuizActivity.

Agora, ainda na QuizActivity, vamos criar um método genérico de carregar a próxima questão na tela, que podemos colocar em qualquer parte da Activity. Esse método remove a questão também, para que elas não se repitam a cada chamada.

Em todos os locais em que precisamos carregar uma questão, vamos chamá-lo, como por exemplo no onCreate da QuizActivity:

e o no evento onRestart:

Notem que o onRestart ficou bem mais simples, porque praticamente ele era esse nosso novo método carregarQuestao().

E antes de fazermos um novo teste, lembra que mudei o click do botão de responder para passar a informação dos pontos para a tela de resposta? Então vamos pegar essa informação lá para exibir na tela, informando o usuário de quantos pontos ele já tem. O código abaixo ilustra isso, no onCreate da RespostaActivity (ache-o no onCreate e faça as alterações para manipular os pontos):

Se testarmos agora, teremos muitas coisas novas e interessantes como múltiplas perguntas, contagem de pontos, etc. No entanto, após você responder à última pergunta, o app quebra, certo?

#6 – Finalizando o app

Após o usuário responder todas perguntas ele deve ser redirecionado para uma tela com o seu desempenho. Sabemos que ele respondeu todas perguntas quando o nosso List<Questao> está vazio, dentro do método carregarQuestao. Mas antes de mexer nele, vamos trabalhar na nossa tela de sucesso.

Pensei em uma tela de sucesso bem simples, onde vamos exibir uma imagem e uma mensagem, falando do resultado do usuário. Note que isso é exatamente o que já temos na tela de resposta. Que tal personalizarmos ela para exibir também esse desempenho final?

Primeiro, vamos no método carregarQuestao() para evitar que o app quebre novamente. O que temos de fazer é bem simples: se a lista de questões estiver vazia, devemos jogar o usuário para a activity de Resposta, sem o Extra informando se ele acertou ou não, apenas com os pontos. Também vamos derrubar esta Activity pois não temos mais questões pra ela.

Agora, antes de começarmos a editar o código Java da RespostaActivity para exibir o desempenho do usuário, pegue na Internet algumas imagens que possam ser usadas para enfatizar se o usuário foi bem ou mal no quiz. Eu baixei duas imagens, uma para quem acertou menos de 3 questões (ruim) e outra para quem acertou 3 ou mais (bom). Coloque suas imagens na pasta res/drawables, assim como as outras imagens.

Agora, adicione um Button no layout da tela de resposta com o text=Jogar Novamente e o id=btnJogarNovamente. Também adicione na propriedade onClick dele o nome do método btnJogarNovamenteOnClick que criaremos mais abaixo.

LuizQuiz
LuizQuiz

No onCreate da nossa RespostaActivity deveremos verificar se veio apenas o Extra de pontos, sem o Extra informando se acertou a questão anterior ou não. Nesse caso, devemos ver qual imagem exibir (feliz, triste, acerto ou erro) e se devemos exibir ou não o botão (deve ser exibido somente no caso de jogo finalizado).

O código do onCreate completo da RespostaActivity deve ficar dessa maneira:

Além disso, temos o botão de Jogar Novamente. O Clique dele deve reiniciar o jogo. Para isso, vamos iniciar novamente a QuizActivity que havíamos finalizado antes, para que tudo volte a ser como era novamente.

Claro, o ideal seria você pegar um conjunto novo de perguntas, aqui o jogador terá de responder novamente as mesmas 4 perguntas que já vem na memória do quiz. Também seria bem interessante trocar o ícone da aplicação, que fica na pasta mipmap e adicionar alguma forma de monetização (para ganhar uns trocados).

Mas estes e outros ajustes para deixar o app com a sua cara, eu deixo para você.

Até a próxima!

* OBS: curtiu o post? Então dá uma olhada no meu livro de Android clicando no banner abaixo pra aprender a criar outros tantos apps incríveis!

Criando apps para empresas com Android

Publicado por

Luiz Duarte

Pós-graduado em computação, professor, empreendedor, autor, Agile Coach e programador nas horas vagas.