Buscar

Tratamento de Eventos em Activities

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 3, do total de 31 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 6, do total de 31 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 9, do total de 31 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Prévia do material em texto

PROGRAMAÇÃO IV 
AULA 4 
 
 
 
 
 
 
 
 
 
 
 
 
 
Prof. Ricardo Rodrigues Lecheta 
 
 
CONVERSA INICIAL 
Olá, seja bem-vindo(a) a esta aula. 
Anteriormente, estudamos como criar layouts em XML, e, nesta aula, 
vamos “colocar a mão na massa” no código da activity. 
CONTEXTUALIZANDO 
A classe Activity representa uma tela do aplicativo e é responsável por 
controlar os eventos e a lógica desta tela. Vamos estudar em mais detalhes o 
que é uma activity, revisar como fazer o tratamento de eventos e como fazer a 
navegação entre telas. 
TEMA 1 – ACTIVITY 
A classe Activity representa uma tela do aplicativo e é responsável por 
controlar os eventos e a lógica dessa tela. Para criar uma activity, devemos ter 
uma classe filha de Activity ou AppCompatActivity. A diferença entre as duas 
é que a classe Activity é embarcada no sistema operacional e vai ter uma versão 
diferente do código dela em um Android 5.0 e um Android 10. Para evitar esses 
problemas de compatibilidade com diferentes versões do Android, o Google criou 
um pacote que é chamado de biblioteca de compatibilidade e recomenda que as 
classes desse pacote sejam utilizadas no lugar das nativas. Por isso, ao criarmos 
o projeto, o Android Studio fez a nossa MainActivity ser filha de 
AppCompatActivity. 
class MainActivity : AppCompatActivity() { 
Lembra do arquivo styles.xml? Nele, também usamos o tema de 
compatibilidade, que traz o Material Design e a mesma interface para todas as 
versões do Android. 
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> 
A vantagem de utilizar a biblioteca de compatibilidade é que ela é 
adicionada no arquivo app/build.gradle e pode ser atualizada sempre que o 
Google lançar versões mais novas. Caso você utilize a classe Activity padrão, 
o código dela só é atualizado quando atualizar todo o sistema operacional do 
seu celular, entende? 
 
 
● app/build.gradle 
implementation 'androidx.appcompat:appcompat:1.2.0' 
Bom, o tema é um pouco complicado, mas na prática você não precisa se 
preocupar muito com isso, basta sempre que criar uma activity, herdar da classe 
AppCompatActivity, conforme fizemos até agora. Nós também estudamos que 
uma activity possui o método onCreate(bundle), que é chamado ao inicializar 
essa tela. E que o método setContentView(layout) é usado para configurar o XML 
que será usado como layout desta tela. Portanto, um template básico de uma 
activity é sempre assim: 
class MainActivity : AppCompatActivity() { 
 override fun onCreate(savedInstanceState: Bundle?) { 
 super.onCreate(savedInstanceState) 
 setContentView(R.layout.activity_main) 
 } 
} 
Feita essa revisão básica, vamos estudar em mais detalhes o tratamento 
de eventos dentro de uma activity. 
1.1 Tratamento de eventos e o método setOnClickListener 
Anteriormente, fizemos o seguinte código para tratar os eventos dos 
botões: 
package com.example.helloandroid 
 
. . . 
 
class MainActivity : AppCompatActivity() { 
 override fun onCreate(savedInstanceState: Bundle?) { 
 super.onCreate(savedInstanceState) 
 setContentView(R.layout.activity_main) 
 
 findViewById<Button>(R.id.btLogin).setOnClickListener { 
 startActivity(Intent(this,HomeActivity::class.java)) 
 } 
 
 findViewById<TextView>(R.id.btEsqueciSenha).setOnClickListener { 
 startActivity(Intent(this,EsqueciSenhaActivity::class.java)) 
 } 
 
 findViewById<TextView>(R.id.btCadastrar).setOnClickListener { 
 startActivity(Intent(this,CadastroActivity::class.java)) 
 } 
 } 
} 
 
 
O método setOnClickListener recebe como parâmetro um objeto que 
implementa a interface OnClickListener. O único método desta interface é o 
onClick(View). 
public interface OnClickListener { 
 void onClick(View view); 
} 
Talvez você já deve ter deduzido que usamos lambdas para implementar 
a interface OnClickListener de uma forma simples. Mas como existem várias 
maneiras de implementar uma interface, vamos estudá-los agora. 
1.2 Tratando eventos com o “this” 
Para implementar uma interface, usamos uma vírgula logo seguida da 
definição da classe mãe e colocamos o nome da interface que queremos 
implementar, nesse caso a View.OnClickListener. Se tivesse mais de uma 
interface, podemos adicionar várias separadas por vírgula. Quando uma classe 
implementa uma interface, ela é obrigada a implementar todos os métodos da 
classe, que neste caso é apenas o onClick(view: View?). 
. . . 
 
class MainActivity : AppCompatActivity(), View.OnClickListener { 
 
 override fun onCreate(savedInstanceState: Bundle?) { 
 super.onCreate(savedInstanceState) 
 setContentView(R.layout.activity_main) 
 
 findViewById<Button>(R.id.btLogin).setOnClickListener(this) 
 findViewById<TextView>(R.id.btEsqueciSenha).setOnClickListener(this) 
 findViewById<TextView>(R.id.btCadastrar).setOnClickListener(this) 
 } 
 
 override fun onClick(view: View?) { 
 when(view?.id) { 
 R.id.btLogin -> { 
 startActivity(Intent(this,HomeActivity::class.java)) 
 } 
 R.id.btEsqueciSenha -> { 
 startActivity(Intent(this,EsqueciSenhaActivity::class.java)) 
 } 
 R.id.btCadastrar -> { 
 startActivity(Intent(this,CadastroActivity::class.java)) 
 } 
 } 
 } 
} 
A vantagem de fazer desta forma é que o método setOnClickListener 
pode ser configurado apenas passando a referência da própria classe com a 
 
 
palavra reservada 'this', pois sabemos que a classe é compatível com a interface 
desejada. 
findViewById<Button>(R.id.btLogin).setOnClickListener(this) 
A desvantagem dessa implementação é que todos os botões vão chamar 
o método onClick(view), e lá dentro temos que fazer um if ou switch para 
verificar qual botão foi clicado. No Kotlin, não existe o controle de fluxo com o 
switch, e no lugar temos o when, mas como podemos ver no código, é bem 
simples de se utilizar. Para maiores detalhes, leia a documentação oficial no link 
a seguir: <https://kotlinlang.org/docs/reference/control-flow.html#when-
expression>. 
1.3 Tratando eventos com classes anônimas 
Outra maneira de implementar uma interface é criar uma classe anônima, 
que é um trecho de código que pode ser passado como argumento para uma 
função e automaticamente implementar a interface. No Kotlin, para criar uma 
interface anônima, é utilizada a palavra reservada 'object:', seguida da 
declaração da interface e de todos os métodos que ela possui. Na prática, um 
objeto é criado nessa parte do código e possui todos os métodos da interface 
desejada. 
findViewById<Button>(R.id.btLogin).setOnClickListener(object: 
View.OnClickListener{ 
 override fun onClick(view: View?) { 
 startActivity(Intent(this@MainActivity,HomeActivity::class.java)) 
 } 
}) 
Principalmente para quem está iniciando, essa sintaxe é uma das mais 
complicadas. Mas sempre que a interface possui apenas um método, que é o 
caso da OnClickListener, podemos simplificá-la usando as lambdas. 
1.4 Tratando eventos com Lambdas 
Conforme estudamos sobre Kotlin, a sintaxe de abre e fecha chaves { } é 
uma lambda, ou seja, é uma maneira mais simples de passar um código como 
parâmetro para funções e inclusive métodos que recebem uma interface. Neste 
caso, como a interface OnClickListener possui apenas um método, podemos 
implementá-lo diretamente com lambdas, assim: 
 
 
findViewById<Button>(R.id.btLogin).setOnClickListener { 
 startActivity(Intent(this,HomeActivity::class.java)) 
} 
Internamente, foi criado uma classe anônima que implementa a interface 
OnClickListener e seu método onClick(View). Simples, não é? 
1.5 Organizando em métodos 
Com certeza, a sintaxe das lambdas atualmente é a mais utilizada pelos 
desenvolvedores devido à sua simplicidade. 
Para concluir, algo que gosto de fazer para deixar o código ainda mais 
organizado é criar ummétodo separado para cada evento, como feito no próximo 
exemplo. Note que foi criado o método onClickLogin() específico para o evento 
de login. O mesmo foi feito para os outros botões. Isso torna o código muito 
simples de entender. A vantagem é que, dentro da lambda, sempre teremos 
apenas uma linha de código, que é a chamada do método que vai tratar o evento. 
package com.example.helloandroid 
. . . 
 
class MainActivity : AppCompatActivity() { 
 override fun onCreate(savedInstanceState: Bundle?) { 
 super.onCreate(savedInstanceState) 
 setContentView(R.layout.activity_main) 
 
 findViewById<Button>(R.id.btLogin).setOnClickListener { 
 // Delega o tratamento para o método correto 
 onClickLogin() 
 } 
 findViewById<TextView>(R.id.btEsqueciSenha).setOnClickListener { 
 onClickEsqueciSenha() 
 } 
 findViewById<TextView>(R.id.btCadastrar).setOnClickListener { 
 onClickCadastrar() 
 } 
 } 
 // Um método para cada evento aqui 
 private fun onClickLogin() { 
 startActivity(Intent(this,HomeActivity::class.java)) 
 } 
 private fun onClickEsqueciSenha() { 
 startActivity(Intent(this,EsqueciSenhaActivity::class.java)) 
 } 
 private fun onClickCadastrar() { 
 startActivity(Intent(this,CadastroActivity::class.java)) 
 } 
} 
Essa organização dos métodos é muito importante para dar manutenção 
no projeto. Imagine que precisamos mexer no código que trata o evento de um 
botão. Organizando o código dessa maneira, é possível achar rapidamente um 
método apenas utilizando a tecla de atalho Ctrl+F12 (Windows) ou 
 
 
Cmd+Fn+F12 (Mac). Esse atalho vai abrir a janela do assistente e depois basta 
digitar 'onClick' para filtrar os métodos que você deseja procurar. É possível usar 
as setas do teclado para navegar, pressionar <enter> e pronto. Conseguimos 
chegar no ponto do código que precisamos sem nem tocar no mouse. 
Figura 1 – Atalho 
 
1.6 Tratando eventos pelo XML 
Conforme explicado, a solução mais adotada no mercado é usar lambdas, 
mas ainda falta explicar uma maneira de adicionar eventos, que é utilizar a tag 
onClick diretamente no XML, configurando o nome do método que vai tratar o 
evento. Essa configuração é simples assim: 
<Button 
 android:id="@+id/btLogin" 
 android:layout_width="wrap_content" 
 android:layout_height="wrap_content" 
 android:text="Login" 
 android:onClick="onClickLogin"/> 
Feito isso, basta adicionar o método desejado na classe da activity. 
fun onClickLogin(view: View) { 
 // código aqui 
} 
Esse jeito de adicionar eventos pode parecer a melhor solução no início, 
mas na prática é pouco usado. O motivo é porque ao olhar o código da classe, 
não conseguimos detectar de maneira rápida de onde esse método está sendo 
chamado. Para descobrir, temos que olhar o XML. É claro que nesse exemplo 
simples é óbvio, mas em códigos maiores isso pode ser um problema. 
 
 
Portanto, a solução que vamos adotar é o uso de lambdas. 
TEMA 2 – TRATANDO EVENTO DE LOGIN 
Já fizemos o layout do formulário de login e aprendemos a tratar os 
eventos. Desta vez, vamos aprender a ler os textos que foram digitados pelo 
usuário. Para isso, precisamos criar um identificador, chamado apenas de 'id', 
para cada view que queremos ler o texto ou seu valor. Nós já estudamos sobre 
esse “id” quando adicionamos os eventos nos botões, mas sempre é bom revisar 
os conceitos. 
Abra o arquivo activity_main.xml e encontre os dois campos de texto 
(EditText) do login e da senha. Feito isso, adicione os ids em cada um deles. Eu 
costumo colocar a letra 't' antes do id sempre que é um EditText: 
<EditText 
 android:id="@+id/tLogin" 
 android:layout_width="match_parent" 
 android:layout_height="wrap_content" 
 /> 
. . . 
<EditText 
 android:id="@+id/tSenha" 
 android:layout_width="match_parent" 
 android:layout_height="wrap_content" 
 android:inputType="textPassword" 
 /> 
Para adicionar o id em uma view no XML, é utilizada a tag android:id. O 
id é sempre prefixado por '@+id/'. A sintaxe é estranha, mas logo você se 
acostuma :-). Com isso, já podemos encontrar essas views no código com o 
método findViewById(id). A implementação do método onClickLogin(), lendo 
os textos digitados, fica assim: 
private fun onClickLogin() { 
 // Encontra as views 
 val tLogin = findViewById<TextView>(R.id.tLogin) 
 val tSenha = findViewById<TextView>(R.id.tSenha) 
 // Lê os textos 
 val login = tLogin.text.toString() 
 val senha = tSenha.text.toString() 
 if(login == "ricardo" && senha == "123") { 
 // Login OK, vai para a Home 
 startActivity(Intent(this,HomeActivity::class.java)) 
 } else { 
 // Erro de Login 
 } 
} 
 
 
Faça essa alteração de código e execute o projeto novamente no 
emulador. Desta vez, o login só será bem-sucedido se digitarmos corretamente 
os dados. 
2.1 Criando alertas 
Até o momento, tratamos no código apenas o login feito com sucesso. 
Neste próximo exemplo, vamos mostrar um alerta caso o login esteja incorreto. 
Primeiramente, faça import da classe AlertDialog: 
import androidx.appcompat.app.AlertDialog 
E deixe o método onClickLogin() assim: 
private fun onClickLogin() { 
 . . . 
 if(login == "ricardo" && senha == "123") { 
 // OK 
 startActivity(Intent(this,HomeActivity::class.java)) 
 } else { 
 // Erro 
 val dialog = AlertDialog.Builder(this).create() 
 dialog.setTitle("Android") 
 dialog.setMessage("Login incorreto, digite os dados 
novamente") 
 dialog.setButton( 
 AlertDialog.BUTTON_NEUTRAL, "OK" 
 ) { _, which -> 
 dialog.dismiss() 
 } 
 dialog.show() 
 } 
} 
Feito isso, um alerta será mostrado quando tivermos um erro no login: 
Figura 2 – Alerta 
 
Créditos: khuruzero/Shutterstock. 
 
 
 
 
Você deve ter reparado que o código para mostrar o alerta é um tanto 
quanto grande, portanto, vamos criar uma extensão para facilitar a nossa vida. 
Conforme estudamos sobre Kotlin, uma extensão permite adicionar métodos em 
uma classe sem a necessidade de criar uma classe filha, portanto, nosso objetivo 
será adicionar um método chamado alert() na classe da Activity. 
Como estamos utilizando a biblioteca de compatibilidade do Google, 
vamos criar uma extensão para a classe AppCompatActivity. 
Crie um pacote “extensions” para armazenar as extensões do projeto e 
crie o arquivo Activity-Extensions.kt, conforme indicado na figura a seguir. 
Figura 3 – Arquivo Activity Extensions 
 
É um padrão de nomenclatura utilizarmos o nome da classe que 
queremos customizar no nome do arquivo, desta forma, quem bater o olho nesse 
arquivo, vai saber que se trata de uma extensão que vai adicionar métodos na 
classe Activity. 
● Activity-Extensions.kt 
package com.example.helloandroid.extensions 
 
import androidx.appcompat.app.AlertDialog 
import androidx.appcompat.app.AppCompatActivity 
 
fun AppCompatActivity.alert(msg: String) { 
 val dialog = AlertDialog.Builder(this).create() 
 dialog.setTitle("Android") 
 dialog.setMessage(msg) 
 dialog.setButton( 
 AlertDialog.BUTTON_NEUTRAL, "OK" 
 ) { _, which -> 
 dialog.dismiss() 
 } 
 dialog.show() 
} 
 
 
Pronto. Falando um português bem claro, essa extensão está dizendo que 
agora todas as activities (filhas de AppCompatActivity) possuem o método 
alert(msg). 
Para utilizar a extensão no código da classe MainActivity, precisamos 
fazer o import do método “alert”. Veja que o pacote dele foi definido no arquivo 
da extensão. 
import com.example.helloandroid.extensions.alert 
Por fim, o código da activity fica simples assim: 
private fun onClickLogin() { 
 . . . 
 if(login == "ricardo" && senha == "123") { 
 // OK 
 startActivity(Intent(this,HomeActivity::class.java)) 
 } else { 
 // Erro 
 alert("Login incorreto, digite os dados novamente") 
 } 
}Neste exemplo, vimos o quanto uma extensão deixa o código mais 
simples, facilitando a manutenção do aplicativo. 
TEMA 3 – LOGCAT E DEBUG 
Provavelmente, você está acostumado a utilizar aquelas funções print e 
println disponível em várias linguagens como Java e Kotlin, mas no Android, a 
maneira correta de imprimir mensagens no console é por meio da ferramenta 
LogCat. A vantagem do LogCat é que conseguimos categorizar os logs utilizando 
tags e também podemos logar mensagens por níveis de severidade, como info, 
debug, erro, etc. Para começar a brincar com o LogCat, faça o import da classe 
Log: 
import android.util.Log 
Para praticarmos, imagine que queremos debugar a função de login, e 
imprimir os textos que foram digitados pelo usuário do login e senha. Para isso, 
basta utilizar esta linha de código: 
Log.d("empresa","Login: $login, senha: $senha") 
A seguir, podemos ver o código atualizado da função de login. 
 
 
private fun onClickLogin() { 
 // Encontra as views 
 val tLogin = findViewById<TextView>(R.id.tLogin) 
 val tSenha = findViewById<TextView>(R.id.tSenha) 
 // Lê os textos 
 val login = tLogin.text.toString() 
 val senha = tSenha.text.toString() 
 Log.d("empresa","Login: $login, senha: $senha") 
 if(login == "ricardo" && senha == "123") { 
 // OK 
 startActivity(Intent(this,HomeActivity::class.java)) 
 } else { 
 // Erro 
 alert("Login incorreto, digite os dados novamente") 
 } 
} 
Para visualizar os logs, na parte inferior do Android Studio, encontre a 
janela 6: Logcat, ou pressione Alt+6 (Windows) ou Cmd+6 (Mac). Por padrão, o 
LogCat mostra todos os logs do sistema operacional do Android e o que 
precisamos é encontrar a mensagem que foi escrita com a tag empresa. Na 
janela do LogCat, clique no combo que filtra os logs (lá na direita), e selecione a 
opção Edit Filter Configuration. Preencha essa janela conforme indicado na 
figura e clique em OK para salvar. 
Figura 4 – Create new logcat filter 
 
No combo que filtra os logs (lá na direita), selecione a tag empresa, 
conforme indicado na figura. Assim, podemos ver apenas os logs que estamos 
interessados. Entendeu para que serve a tag nos logs? A tag basicamente é um 
filtro. 
 
 
 
Figura 5 – Tag 
 
Também podemos logar mensagens no LogCat com outros níveis de 
severidade, exemplo, Log.i (info), Log.w (warning), Log.d (debug), Log.v 
(verbose), Log.e (erro). No centro da janela do LogCat, você verá um combo que 
está escrito Verbose, e lá você pode filtrar apenas o nível de severidade que 
estamos interessados. 
Com o tempo, você vai se acostumar com esses logs e, com certeza, eles 
vão ser um grande aliado ao debugar o código dos aplicativos. 
3.1 Visualizando erros no LogCat 
Algo muito importante no desenvolvimento de qualquer código é aprender 
a ler as mensagens de erro e as famosas stack traces (pilha com os erros de 
uma exceção). No Android, sempre que o aplicativo travar e encerrar, significa 
que uma exceção não tratada foi lançada e podemos visualizar todos os detalhes 
desses logs usando o LogCat. 
Para brincarmos com isso, vamos simular um erro :-). Primeiramente, 
vamos comentar a configuração da HomeActivity do arquivo de manifesto, pois 
vamos adicionar um bug proposital apenas para aprendermos a visualizar os 
logs. Um comentário em XML começa com '<!--' e termina com '-->'. Você 
pode selecionar o trecho do XML que deseja comentar e utilizar a tecla de atalho 
Ctrl + Shift + / (WIndows) ou Cmd + Shift + / (Mac). 
<!-- <activity 
 android:name=".HomeActivity" 
 android:parentActivityName=".MainActivity" 
 android:label="Home"/> --> 
 
Depois de comentar a configuração da HomeActivity, execute 
novamente o projeto no emulador. Ao fazer o login, o aplicativo vai travar. Ok, 
isso já era esperado, mas como fazemos para descobrir o erro? 
 
 
É simples, basta abrir o LogCat e selecionar o nível de severidade Error. 
Outro detalhe importante é desmarcar todas as tags no combo que filtra as tags 
(lá na direita), pois agora queremos visualizar todos os erros. Deixe no combo a 
opção No Filters selecionada. 
Figura 6 – Error 
 
A figura acima mostra que foi lançada uma exceção, e inclusive a 
mensagem é bastante clara: "ActivityNotFoundException: Unable to find explicit 
activity class {HomeActivity}; have you declared this activity in your 
AndroidManifest.xml?". 
O mais interessante é que o Android nos ajuda, e depois de não encontrar 
a configuração da HomeActivity, ainda nos pergunta se fizemos a configuração 
dessa activity no arquivo de manifesto :-). 
Uma vez que já brincamos de visualizar o erro, volte à configuração da 
activity (desfaça aquele comentário) e vamos continuar os nossos estudos. Mas 
lembre-se, sempre que o aplicativo travar, a primeira tarefa a fazer é verificar os 
erros no LogCat. 
3.2 Debugando o código 
Para ativar um breakpoint no código, clique na parte esquerda do editor, 
na área cinza onde ficam indicadas as linhas do código. Na figura a seguir, o 
breakpoint é representado pela bolinha vermelha na linha 37. 
 
 
 
Figura 7 – Breakpoint do código 
 
Créditos: khuruzero/Shutterstock. 
 
Com o breakpoint devidamente adicionado, execute o código com o botão 
Debug em vez do Run que automaticamente o breakpoint será acionado quando 
esse trecho de código for chamado. 
Observe na figura que no canto inferior esquerdo fica a pilha com as 
chamadas do código, e no lado direito, podemos ver o valor das variáveis e 
depurar o código passo a passo. Enfim, debug de código é um assunto básico e 
provavelmente você já deve ter feito em outra ferramenta. 
TEMA 4 - ORGANIZANDO O CÓDIGO DO PROJETO 
Já aprendemos a utilizar os logs e o debug no Android Studio, e agora 
vamos estudar um pouco sobre organização de código, o que vai ser bom para 
praticarmos um pouco mais sobre como criar classes e a sintaxe do Kotlin. 
4.1 Login 
Até o momento, a lógica de login está fixa apenas para ilustrar a ideia: 
if(login == "ricardo" && senha == "123") { 
Mas na prática, o aplicativo provavelmente vai fazer uma consulta na 
internet para validar este login. Essa consulta geralmente é feita com um web 
service, que é chamado popularmente de API. Nós ainda vamos estudar como 
utilizar web services, mas, por enquanto, o importante é já deixar a estrutura de 
código preparada. 
 
 
Nosso objetivo agora é criar as classes Usuario e LoginService para 
encapsular a lógica de login. Isso é importante, pois a medida que o código do 
aplicativo ficar mais complexo, não é recomendado deixar toda a lógica na classe 
da activity, pois isso iria poluir muito o código e deixar ele difícil de dar 
manutenção. Na prática, a activity deve atuar como um Controller do padrão 
MVC, ou seja, ela deve ser um intermediador entre a view/layout e a lógica de 
negócios. Ou seja, a activity recebe os eventos da tela e delega o trabalho para 
classes especializadas. 
Dito isso, vamos criar a classe Usuario que vai armazenar os dados do 
usuário do nosso aplicativo. Também vamos criar a classe LoginService, que 
vai conter a lógica para fazer o login. Resumindo, podemos dizer que teremos 
este fluxo para fazer um login: 
> Activity > Service > API (web service) 
Muito bem, vamos para o código que vai ficar mais fácil de entender. Crie 
um pacote “domain” conforme demonstrado na próxima figura e crie as classes 
LoginService e Usuario. 
Figura 8 – Domain 
 
A seguir, podemos ver o código da classe Usuário. Ela possui apenas 
dois atributos, o nome e email. 
package com.example.helloandroid.domain 
 
data class Usuario( 
 val nome: String, 
 val email: String 
) 
 
 
A lógica do login vamos deixar na classe LoginService. Por enquanto, 
continuamos com os dados fixos, mas o importante é que já estamos 
organizando o código e futuramente só vamos alterar esta classe. 
package com.example.helloandroid.domain 
 
class LoginService { 
 fun login(login:String,senha: String): Usuario? { 
 if(login == "ricardo" && senha == "123") { 
 return Usuario("Ricardo","a@a.com") 
 } else if(login == "teste" && senha == "123") { 
 return Usuario("Teste","b@b.com") 
 } 
 return null 
 } 
} 
Observe que o método de login retorna um Usuario? com a interrogação, 
e conforme estudamos sobre Kotlin, isso indica que o retorno pode ser nulo. Para 
usar esta classe, basta criar uma nova instância de um objeto e chamar o método 
login(login,senha) da classe LoginService, conforme indicado a seguir: 
 
private fun onClickLogin() { 
 // Encontra as views 
 val tLogin = findViewById<TextView>(R.id.tLogin) 
 val tSenha = findViewById<TextView>(R.id.tSenha) 
 // Lê os textos digitados 
 val login = tLogin.text.toString() 
 val senha = tSenha.text.toString() 
 // Valida o login 
 val service = LoginService() 
 val user = service.login(login,senha) 
 if(user != null) { 
 // OK 
 startActivity(Intent(this,HomeActivity::class.java)) 
 } else { 
 // Erro 
 alert("Login incorreto, digite os dados novamente") 
 } 
} 
Pronto! Acabamos de organizar nosso código e toda a lógica de login ficou 
na classe LoginService. E para validar se o login foi bem-sucedido, basta 
verificar se o usuário que retornou do login não é nulo. 
Quebrar o código em pequenas classes é um dos conceitos mais 
importantes da Orientação a Objetos, pois é melhor cada classe ser 
especializada em um assunto específico e fazer poucas coisas, do que ter uma 
classe que faz tudo, como era antes com a MainActivity. 
 
 
Como estudo complementar, recomendo que você leia sobre o princípio 
de Baixo Acoplamento e Alta Coesão, que é um dos pilares da Orientação a 
Objetos. 
4.2 O método finish 
Quando fizemos o login, navegamos para a tela da HomeActivity, e ao 
clicar no botão de voltar, o aplicativo volta para a tela de login. Esse é o 
comportamento padrão do Android, pois ele vai empilhando as activities sempre 
que o aplicativo vai abrindo as telas. Internamente, essa pilha é chamada de 
activity stack. E se fosse um requisito encerrar a tela de login depois do login 
com sucesso? Neste caso, podemos chamar o método finish(), conforme 
demonstrado a seguir. 
val service = LoginService() 
val user = service.login(login,senha) 
if(user != null) { 
 // OK 
 startActivity(Intent(this,HomeActivity::class.java)) 
 finish() 
} 
No arquivo de manifesto, encontre a HomeActivity e remova a tag 
parentActivityName. Desta maneira, o botão de voltar na tela da Home não vai 
aparecer: 
<activity 
 android:name=".HomeActivity" 
 android:parentActivityName=".MainActivity" 
 android:label="Home"/> 
Faça esta alteração e execute o aplicativo novamente. Desta vez, depois 
de fazer o login e abrir a tela da Home, não vai existir nenhum botão de voltar na 
AppBar (lá em cima na esquerda). Ao clicar no botão voltar nativo do Android, o 
aplicativo será fechado, pois não existe nenhuma activity atrás desta. 
O que fizemos foi: 
1. Chamamos o método finish() logo depois do login. Isso encerrou a tela 
da LoginActivity; 
2. Removemos o botão de voltar da AppBar. 
 
 
 
4.3 Esqueci a Senha 
Vamos continuar praticando o desenvolvimento do nosso aplicativo e 
vamos simular a funcionalidade do esqueci a senha. Vou ser bem prático desta 
vez, porque acredito que é uma funcionalidade bem simples, mas é muito 
importante para revisarmos e consolidar os conceitos que aprendemos. 
A lógica da recuperação de senha ficará na classe 
EsqueciSenhaService, portanto, crie essa classe da mesma maneira que 
fizemos com a LoginService. Ela também poderá ficar no pacote “domain”. 
O método recuperarSenha(login) recebe o login do usuário e vai 
devolver um booleano (true/false) para informar se a senha foi recuperada com 
sucesso. Claro que estamos apenas simulando a lógica, mas já estamos 
estruturando o código, ok? 
package com.example.helloandroid.domain 
 
import android.util.Log 
 
class EsqueciSenhaService { 
 fun recuperarSenha(login:String): Boolean { 
 Log.d("empresa", "Simulando o recuperar a senha: 
$login") 
 return true 
 } 
} 
Feito isso, abra o arquivo activity_esqueci_senha.xml e adicione um id 
para o campo de texto (EditText) e no botão de enviar (Button): 
<?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"> 
 <TextView 
 android:layout_width="wrap_content" 
 android:layout_height="wrap_content" 
 android:text="Digite seu login" /> 
 <EditText 
 android:id="@+id/tLogin" 
 android:layout_width="match_parent" 
 android:layout_height="wrap_content" /> 
 <Button 
 android:id="@+id/btEnviar" 
 android:layout_width="wrap_content" 
 android:layout_height="wrap_content" 
 android:layout_gravity="center" 
 android:text="Enviar" /> 
 
 
</LinearLayout> 
Com isso, podemos adicionar um evento neste botão, e chamar a lógica 
da classe de negócio (que chamamos apenas de service). Observe que foi 
utilizado o mesmo id '@+id/tLogin' que já tínhamos usado no layout de login. Isso 
não tem problema e inclusive é recomendado para evitar criar muitos ids. 
package com.example.helloandroid 
 
import androidx.appcompat.app.AppCompatActivity 
import android.os.Bundle 
import android.widget.Button 
import android.widget.TextView 
import com.example.helloandroid.domain.EsqueciSenhaService 
import com.example.helloandroid.extensions.alert 
 
class EsqueciSenhaActivity : AppCompatActivity() { 
 override fun onCreate(savedInstanceState: Bundle?) { 
 super.onCreate(savedInstanceState) 
 setContentView(R.layout.activity_esqueci_senha) 
 
 findViewById<Button>(R.id.btEnviar).setOnClickListener { 
 onClickEnviar() 
 } 
 } 
 
 private fun onClickEnviar() { 
 val tLogin = findViewById<TextView>(R.id.tLogin) 
 val login = tLogin.text.toString() 
 val service = EsqueciSenhaService() 
 val ok = service.recuperarSenha(login) 
 if(ok) { 
 alert("Sua nova senha foi enviada para o seu-email.") 
 } else { 
 alert("Ocorreu um erro ao recuperar a senha.") 
 } 
 } 
} 
Depois de chamar o método de recuperar a senha, veja que estamos 
armazenando o resultado em uma variável booleana. Vale lembrar que o tipo da 
variável que destaquei abaixo em amarelo geralmente é omitido, portanto 
acostume-se com isso. 
val ok:Boolean = service.recuperarSenha(login) 
Ao executar esse exemplo e clicar no botão, você verá o alerta de 
sucesso, pois até o momento a classe de negócio sempre está retornando true 
(ok). 
 
 
 
Figura 9 – Recuperação de senha 
 
4.4 Executar ação ao clicar no OK do alerta 
Uma funcionalidade muito comum em aplicativos é a necessidade de 
executar alguma função logo depois de clicar no botão Ok de um alerta. Para dar 
um exemplo real, podemos dizer que se a recuperação de senha for bem-
sucedida, ao clicar no Ok, podemos fechar esta tela automaticamente. Mas como 
podemos fazer essa lógica? 
O que podemos fazer é passar como parâmetro uma função que 
popularmente chamamos de callback, que traduzindo significa “retorno”. Essa 
função não recebe parâmetros e não possui retorno, portanto é Unit (void). No 
código, veja que esta função é chamada ao criar o código do AlertDialog. 
package com.example.helloandroid.extensions 
 
import androidx.appcompat.app.AlertDialog 
import androidx.appcompat.app.AppCompatActivity 
 
fun AppCompatActivity.alert(msg: String, callback: () -> Unit = {}) { 
 val dialog = AlertDialog.Builder(this).create() 
 dialog.setTitle("Android") 
 dialog.setMessage(msg) 
 dialog.setButton( 
 AlertDialog.BUTTON_NEUTRAL, "OK" 
 ) { _, which -> 
 dialog.dismiss()callback() // Aqui chamamos a função callback 
 } 
 dialog.show() 
} 
 
 
Pronto, agora podemos passar essa função como parâmetro quando 
mostrarmos o alerta de sucesso. Como essa função de callback é o último 
parâmetro do método alert(), podemos usar a sintaxe das chaves e passar uma 
lambda como argumento. 
private fun onClickEnviar() { 
 val tLogin = findViewById<TextView>(R.id.tLogin) 
 val login = tLogin.text.toString() 
 val service = EsqueciSenhaService() 
 val ok:Boolean = service.recuperarSenha(login) 
 if(ok) { 
 alert("Sua nova senha foi enviada para o seu-email.") { 
 finish() 
 } 
 } else { 
 alert( 
 "Ocorreu um erro ao recuperar a senha.") 
 } 
} 
Pronto! Agora é só testar a tela de esqueci a senha novamente. Desta 
vez, depois de clicar no botão de Ok do alerta, a tela será fechada 
automaticamente e o aplicativo vai voltar para a tela de login, pois chamamos o 
método finish(). 
4.5 Kotlin Extensions 
O Kotlin Extensions é um plugin do gradle que cria automaticamente 
variáveis no código com os mesmos ids que foram definidos no XML. 
Atualmente, ao criar um projeto no Android Studio, o plugin já é configurado no 
arquivo app/build.gradle, mas se precisar fazer manualmente, é só adicionar 
esta linha. 
apply plugin: 'com.android.application' 
apply plugin: 'kotlin-android' 
apply plugin: 'kotlin-android-extensions' 
Dependendo da versão do Android Studio, a configuração pode ser assim. 
Caso a linha do Kotlin Extensions esteja faltando, favor adicionar. 
plugins { 
 id 'com.android.application' 
 id 'kotlin-android' 
 id 'kotlin-android-extensions' 
} 
O Kotlin Extensions cria automaticamente as variáveis pelo id que estão 
definidos no layout, e depois que você aprender a usá-lo, vai querer me matar 
 
 
por não ter explicado isso antes :-) Mas é que era necessário explicar a base 
para depois evoluir para os atalhos. Dando um exemplo prático, esta linha: 
findViewById<Button>(R.id.btEnviar).setOnClickListener { 
Pode ser substituída por: 
btEnviar.setOnClickListener { 
E esta linha pode ser removida, pois a variável tLogin é criada 
automaticamente pelo Kotlin Extensions :-) 
val tLogin = findViewById<TextView>(R.id.tLogin) 
Entendeu, né? O id que você definir no XML vira uma variável aqui no 
código. Mas para essa mágica funcionar, é necessário fazer um import na classe, 
referenciando o layout XML de onde vamos buscar os ids: 
import kotlinx.android.synthetic.main.activity_esqueci_senha.* 
O código final fica assim. Está destacado em amarelo as alterações. 
package com.example.helloandroid 
 
... 
import kotlinx.android.synthetic.main.activity_esqueci_senha.* 
 
class EsqueciSenhaActivity : AppCompatActivity() { 
 override fun onCreate(savedInstanceState: Bundle?) { 
 super.onCreate(savedInstanceState) 
 setContentView(R.layout.activity_esqueci_senha) 
 
 btEnviar.setOnClickListener { 
 onClickEnviar() 
 } 
 } 
 
 private fun onClickEnviar() { 
 val login = tLogin.text.toString() 
 val service = EsqueciSenhaService() 
 val ok:Boolean = service.recuperarSenha(login) 
 if(ok) { 
 alert("Sua nova senha foi enviada para o seu-email.") { 
 finish() 
 } 
 } else { 
 alert( 
 "Ocorreu um erro ao recuperar a senha.") 
 } 
 } 
} 
 
 
 
TEMA 5 – MELHORANDO O FORMULÁRIO DE CADASTRO 
Para finalizar esta aula, vamos concluir o formulário de cadastro e 
aprender a utilizar o ScrollView, e também a ler os valores digitados no 
RadioGroup e Checkbox. 
5.1 ScrollView 
No próximo exemplo, vamos adicionar o ScrollView no layout XML do 
formulário de cadastro. Essa view é utilizada para configurar a rolagem 
automática da tela, caso não exista espaço na vertical para mostrar todos os 
elementos. 
A estrutura básica do ScrollView podemos ver no código abaixo. Um 
ScrollView é um gerenciador de layout que pode ter apenas uma tag filha, e 
geralmente é um LinearLayout (vertical), o qual possui todas as views uma 
embaixo da outra. A combinação dessas duas tags cria um formulário com 
rolagem automática, simples assim. 
<?xml version="1.0" encoding="utf-8"?> 
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" 
 android:layout_width="match_parent" 
 android:layout_height="match_parent"> 
 <LinearLayout 
 android:layout_width="match_parent" 
 android:layout_height="wrap_content" 
 android:orientation="vertical" 
 android:padding="16dp"> 
 
 <!-- View 1 --> 
 <!-- View 2 --> 
 <!-- . . . --> 
 <!-- . . . --> 
 <!-- . . . --> 
 <!-- View 100 --> 
 
 </LinearLayout> 
</ScrollView> 
5.2 Cadastro e outras views de formulário 
Vamos praticar mais um pouco e concluir o formulário de cadastro. O 
objetivo será criar uma classe CadastroModel que conterá todos os dados 
digitados no formulário (nome, login, email, sexo) e chamar uma classe 
CadastroService que vai simular o cadastro. 
 
 
Existem três diferenças listadas a seguir para o layout mostrado 
anteriormente, mas é pouca coisa e a ideia é você praticar. 
1. Foi adicionado um campo de login no formulário. A ideia deste cadastro 
fictício é que você digite seu login e alguns dados cadastrais, e uma senha 
aleatória seja enviada para seu email. 
2. Foram adicionados ids para todas as views que queremos interagir, como 
por exemplo: os campos de texto, o checkbox de aceitar os termos de uso, 
o radio button do sexo e o botão de cadastrar. 
3. Foi adicionado um ScrollView como a tag raiz do layout. O LinearLayout 
vertical que contém todos os campos do formulário ficou dentro do 
ScrollView. Essa view é mágica e fará a rolagem (scroll) automaticamente 
caso a tela seja pequena e não consiga mostrar todos os campos do 
formulário. 
A seguir, podemos ver o código completo do arquivo 
activity_cadastro.xml, em amarelo estão destacadas as alterações feitas no 
arquivo. Faça tudo com calma e atenção e depois prossiga com a aula. 
<?xml version="1.0" encoding="utf-8"?> 
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android" 
 android:layout_width="match_parent" 
 android:layout_height="match_parent"> 
 
 <LinearLayout 
 android:layout_width="match_parent" 
 android:layout_height="wrap_content" 
 android:orientation="vertical" 
 android:padding="16dp"> 
 <TextView 
 android:layout_width="wrap_content" 
 android:layout_height="wrap_content" 
 android:text="Nome" /> 
 <EditText 
 android:id="@+id/tNome" 
 android:layout_width="match_parent" 
 android:layout_height="wrap_content" /> 
 
 <TextView 
 android:layout_width="wrap_content" 
 android:layout_height="wrap_content" 
 android:text="Login" /> 
 <EditText 
 android:id="@+id/tLogin" 
 android:layout_width="match_parent" 
 android:layout_height="wrap_content" /> 
 
 <TextView 
 android:layout_width="wrap_content" 
 android:layout_height="wrap_content" 
 android:text="Email" /> 
 <EditText 
 android:id="@+id/tEmail" 
 android:layout_width="match_parent" 
 android:layout_height="wrap_content" /> 
 
 
 
 <TextView 
 android:layout_width="wrap_content" 
 android:layout_height="wrap_content" 
 android:text="Sexo" /> 
 <RadioGroup 
 android:id="@+id/radioSexo" 
 android:layout_width="match_parent" 
 android:layout_height="wrap_content" 
 android:orientation="horizontal"> 
 <RadioButton 
 android:id="@+id/radioMasculino" 
 android:layout_width="wrap_content" 
 android:layout_height="wrap_content" 
 android:text="Masculino" /> 
 <RadioButtonandroid:id="@+id/radioFeminino" 
 android:layout_width="wrap_content" 
 android:layout_height="wrap_content" 
 android:text="Feminino" /> 
 </RadioGroup> 
 
 <View 
 android:layout_width="match_parent" 
 android:layout_height="2dp" 
 android:layout_marginVertical="16dp" 
 android:background="#eeeeee" /> 
 
 <CheckBox 
 android:id="@+id/checkTermos" 
 android:layout_width="wrap_content" 
 android:layout_height="wrap_content" 
 android:text="Aceito os termos de uso" /> 
 
 <Button 
 android:id="@+id/btCadastrar" 
 android:layout_width="wrap_content" 
 android:layout_height="wrap_content" 
 android:layout_gravity="center" 
 android:text="Cadastrar" /> 
 </LinearLayout> 
 
</ScrollView> 
Adicionar um evento no botão de cadastrar e ler os campos de texto do 
EditText nós já sabemos como fazer. Neste próximo exemplo, vamos aprender 
como ler os valores das views CheckBox e RadioGroup. 
Primeiramente, vamos criar uma classe de modelo que vai conter todos 
os dados necessários para cadastrar o usuário: 
package com.example.helloandroid.domain 
 
data class CadastroModel( 
 var nome: String = "", 
 var login: String = "", 
 var email: String = "", 
 var sexo: String = "" 
) 
A lógica de cadastrar ficará na classe CadastroService. Por enquanto, 
ela não faz nada, mas na prática, ela poderia chamar uma API do servidor para 
 
 
efetivar o cadastro. O importante é você entender como ir fazendo essa 
organização de código. 
package com.example.helloandroid.domain 
 
import android.util.Log 
 
class CadastroService { 
 fun cadastrar(model: CadastroModel): Boolean { 
 Log.d("empresa","Cadastro $model") 
 return true 
 } 
} 
O método cadastrar(model) da classe CadastroService recebe um 
objeto que chamamos de modelo (CadastroModel). Portanto, o que temos que 
fazer na activity é preencher esse objeto ao clicar no botão de cadastrar. 
O código completo da activity podemos ver a seguir: 
package com.example.helloandroid 
 
import android.os.Bundle 
import androidx.appcompat.app.AppCompatActivity 
import com.example.helloandroid.domain.CadastroModel 
import com.example.helloandroid.domain.CadastroService 
import com.example.helloandroid.extensions.alert 
import kotlinx.android.synthetic.main.activity_cadastro.* 
 
class CadastroActivity : AppCompatActivity() { 
 override fun onCreate(savedInstanceState: Bundle?) { 
 super.onCreate(savedInstanceState) 
 setContentView(R.layout.activity_cadastro) 
 
 btCadastrar.setOnClickListener { 
 onClickCadastrar() 
 } 
 } 
 private fun onClickCadastrar() { 
 val termosOk = checkTermos.isChecked 
 if (!termosOk) { 
 alert("Aceite os termos para continuar") 
 } else { 
 // Cria objeto de cadastro 
 val model = getCadastroModel() 
 val service = CadastroService() 
 val ok: Boolean = service.cadastrar(model) 
 if (ok) { 
 alert("Cadastro realizado com sucesso.\nSua 
senha foi enviada para o email.") { 
 finish() 
 } 
 } else { 
 alert("Ocorreu um erro ao cadastrar.") 
 } 
 
 
 } 
 } 
 // Cria o objeto de modelo copiando os dados do form 
 private fun getCadastroModel(): CadastroModel { 
 val model = CadastroModel() 
 model.nome = tNome.text.toString() 
 model.login = tLogin.text.toString() 
 model.email = tEmail.text.toString() 
 model.sexo = if (radioSexo.getCheckedRadioButtonId() == 
R.id.radioMasculino) "M" else "F" 
 return model 
 } 
} 
Veja a seguir algumas explicações sobre o código: 
Para descobrir se o CheckBox está selecionado, basta chamar o método 
isChecked() que retorna um boolean. 
val termosOk = checkTermos.isChecked 
 
Na brincadeira que estamos fazendo, caso o checkbox não seja 
selecionado, o aplicativo vai mostrar um alerta conforme mostrado na figura: 
Figura 10 – Cadastro 
 
Créditos: khuruzero/Shutterstock. 
Depois de aceitar os termos, precisamos copiar os dados do formulário 
para o objeto de modelo, portanto, veja que foi criado o método 
getCadastroModel() com esse objetivo. A única novidade lá é que estamos 
 
 
lendo qual sexo foi selecionado (M ou F). A lógica para ler o valor do 
RadioGroup (grupo) é chamar o método getCheckedRadioButtonId() que 
retorna um int referente ao id do RadioButton que está selecionado. Para 
descobrir qual item está selecionado (M o F), esse id pode ser comparado com 
as constantes da classe R, que nesse caso são R.id.radioMasculino e 
R.id.radioFeminino, ambas definidas como id do RadioButton lá no XML. Bom, 
resumindo, isso foi feito com esta linha de código, sendo assim a variável sexo 
dentro da classe de modelo vai conter os valores "M" ou "F" dependendo da 
opção selecionada. 
model.sexo = if (radioSexo.getCheckedRadioButtonId() == R.id.radioMasculino) "M" else "F" 
Depois de preencher o formulário com todos os dados, a classe 
CadastroService é chamada passando como parâmetro a classe de modelo. 
Neste momento, estamos logando o objeto de modelo: 
Log.d("empresa","Cadastro $model") 
Portanto, ao digitar os dados no formulário e clicar no botão cadastrar, 
você deverá visualizar o seguinte log no LogCat. Com isso, podemos validar se 
o objeto foi devidamente preenchido com os dados digitados. 
com.example.helloandroid D/empresa: Cadastro 
CadastroModel(nome=Ricardo, login=rlecheta, email=a@a.com, sexo=M) 
Para finalizar nosso exercício, a figura a seguir mostra a mensagem de 
sucesso de cadastro caso a classe de service retorne true: 
Figura 11 – Cadastro 
 
Créditos: khuruzero/Shutterstock. 
 
 
FINALIZANDO 
Nesta aula, aprendemos como tratar os eventos do botão e o método 
setOnClickListener. Aproveitamos para revisar o conceito de interfaces e de 
como podemos implementá-las utilizando o Kotlin. Mais uma vez, vimos que a 
utilização de lambdas simplifica o código e por isso vem se tornando um padrão 
de mercado. 
Também estudamos sobre o LogCat e aprendemos a debugar o código. 
E por último, fizemos exercícios práticos sobre como criar classes para organizar 
o código, e de certa forma, já deixamos formulários preparados. 
 
 
 
REFERÊNCIAS 
LECHETA, R. Android Essencial com Kotlin. 2. ed. 2018. 
GUIAS DO DESENVOLVEDOR ANDROID. Disponível em: 
<https://developer.android.com/guide/>.

Outros materiais