Buscar

Aula 06

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 6 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Prof. Ricardo Rodrigues Lecheta 
 
 
 
CONVERSA INICIAL 
Olá, seja bem-vindo a mais uma aula! 
Nós já aprendemos como criar telas com formulários e estudamos o ciclo 
de vida de uma activity. Nesta aula, vamos estudar sobre listas, que com certeza 
é o componente mais utilizado em aplicativos. 
Imagine que você precisa organizar suas tarefas do que fazer durante a 
semana e decidiu criar um aplicativo para ajudá-lo. Nesta aula, vamos criar um 
esboço deste aplicativo para salvar tarefas e mostrá-las em uma lista. 
Não vamos usar banco de dados para simplificar o exemplo, até porque o 
objetivo da aula é estudar listas. Todas as tarefas serão salvas em memória com 
uma HashTable, e os dados serão perdidos ao reiniciar o aplicativo. 
Aproveitando: web services e banco de dados vamos estudar em aulas práticas. 
TEMA 1 – LISTAS: CONFIGURAÇÃO 
Para iniciar, crie um novo projeto chamado HelloTarefas da mesma forma 
que fizemos nos outros exemplos. Lembre-se de selecionar o template Empty 
Activity. 
Logo depois de criar o projeto, adicione as seguintes dependências no 
arquivo app/build.gradle. No final do arquivo, você vai encontrar uma tag 
dependencies, na qual vão existir outras dependências previamente 
configuradas. Basta adicionar essas duas linhas. A lib 'material' contém classes 
do Material Design que vamos utilizar e a lib 'recyclerview' é para adicionar a 
classe RecyclerView que representa a view de uma lista. 
● app/build.gradle 
dependencies { 
 . . . 
 implementation 'com.google.android.material:material:1.2.1' 
 implementation 'androidx.recyclerview:recyclerview:1.1.0' 
} 
Na figura a seguir, podemos ver o arquivo app/build.gradle aberto no 
editor e o local onde as dependências foram adicionadas. Observe que no canto 
direito superior da figura, existe um botão Sync now, o qual vai fazer o download 
e instalação dessas dependências (libs). 
 
 
Observação: caso não esteja acostumado com o termo dependência, é 
um sinônimo utilizado para biblioteca. Na prática, uma dependência é uma 
biblioteca com vários arquivos que é baixada e instalada no projeto. 
Figura 1 – Dependência 
 
Feita essa configuração, podemos abrir o arquivo activity_main.xml e 
adicionar a view RecyclerView no layout. Observe que deixamos a tag 
LinearLayout como raiz do layout. 
Algo importante que você precisa se acostumar é que as views 
LinearLayout, FrameLayout, TextView, EditText, Button etc. são nativas do 
Android e, no nome da tag XML, precisamos colocar apenas o nome da classe 
dessa view. Como a classe/view RecyclerView foi adicionada pela dependência 
que colocamos no arquivo app/build.gradle, ao declarar a tag XML, precisamos 
colocar o nome completo da classe, incluindo o seu pacote. Observe também 
que foi dado o id @+id/recyclerView para o RecyclerView. 
● activity_main.xml 
<?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"> 
 
 <androidx.recyclerview.widget.RecyclerView 
 android:id="@+id/recyclerView" 
 android:layout_width="match_parent" 
 android:layout_height="wrap_content" /> 
</LinearLayout> 
 
 
Pronto, feito isso execute o projeto novamente para validar se as 
configurações foram feitas com sucesso. Se tudo funcionar, você verá uma tela 
vazia, pois o RecyclerView é uma lista e, por enquanto, está vazia. 
Figura 2 – Lista de tarefas vazia 
 
Crédito: Brostock/Shutterstock. 
TEMA 2 – LISTAS: EXEMPLO BÁSICO 
Para que você consiga visualizar o nosso objetivo, vamos criar uma lista 
com três views, conforme mostra a próxima figura. 
Figura 3 – Lista de tarefas 
 
Crédito: Brostock/Shutterstock. 
 
 
Seguindo o mesmo raciocínio, para facilitar o seu entendimento de quais 
arquivos vamos criar neste exercício e do local que você precisa criar os 
arquivos, veja a figura a seguir. 
Figura 4 – Arquivos que vamos criar no projeto 
 
Para começar, vamos criar a classe Tarefa, que vai representar a 
entidade que vamos querer salvar. Sempre que for criar uma classe, utilize o 
wizard > New > Kotlin File/Class. A classe Tarefa contém apenas dois atributos 
(id e título) e também implementa a interface Serializable. 
package com.example.hellotarefas 
 
import java.io.Serializable 
 
data class Tarefa( 
 var id: Int = 0, 
 var titulo: String = "" 
 
) : Serializable 
Nota: é comum utilizarmos o termo entidade para referenciar uma classe 
de domínio que é mapeada para uma tabela do banco de dados, ou seja, ela 
será salva em uma tabela. Geralmente, essas classes contêm atributos com os 
mesmos nomes da tabela do banco de dados. Mais uma vez, em nosso exemplo, 
não usaremos banco de dados, pois o objetivo desta aula é aprendermos a 
utilizar o RecyclerView, que é a view que cria uma lista. 
 
 
Com a classe Tarefa criada, precisamos de uma classe que vai 
encapsular a lógica para buscar as tarefas e retornar uma lista do tipo 
List<Tarefa>. Portanto, crie a classe TarefaService. 
package com.example.hellotarefas 
 
object TarefaService { 
 
 private val tarefas = mutableListOf<Tarefa>() 
 
 init { 
 for (i in 1..3) { 
 tarefas.add(Tarefa(i,"Tarefa $i")) 
 } 
 } 
 
 fun getTarefas(): List<Tarefa> { 
 return tarefas 
 } 
} 
Mais uma vez, explicando um pouco sobre arquitetura de código, é uma 
boa prática criar esse tipo de classe para encapsular essa lógica. Atualmente, 
como você pode ver, estamos criando uma lista fixa com três tarefas apenas 
para brincar e estudar como criar listas com o RecyclerView. Mas, futuramente, 
essa classe poderia conter uma lógica para ler essas tarefas do banco de dados 
do celular Android, ou até mesmo buscar as tarefas na internet usando um web 
service (API). Mas, por enquanto, essa classe já vai criar uma lista com três 
tarefas e é suficiente para nossos estudos. Se quiser, altere o loop for, para criar 
quantas tarefas achar necessário. 
Uma vez que já temos as classes Tarefa e TarefaService criadas, 
precisamos ter uma maneira de pegar a lista de tarefas e preencher lá naquele 
RecyclerView que está no arquivo activity_main.xml. Para fazer essa ponte 
entre a lista de tarefas List<Tarefa> e o RecyclerView, precisamos criar uma 
classe chamada de Adapter, que assim como a activity, é uma dupla de uma 
classe + layout XML. 
Essa parte, aliás, já adianto que é meio chatinha e difícil de entender no 
início, portanto, recomendo que depois que fizer o exemplo funcionar, leia e 
releia tudo novamente para conseguir encaixar todos os pedaços do quebra-
cabeça. 
Uma dica é você imaginar que o RecyclerView é apenas o componente 
da lista, mas ele não sabe qual o layout que cada célula da lista vai ter. Lembra 
 
 
que na figura anterior tinha três tarefas na lista? Cada linha da lista é uma 'célula' 
que possui seu próprio layout XML, a qual o Android chama de Adapter. 
Para você ir visualizando na prática, podemos dizer que uma prévia do 
código da activity que vai preencher a lista de tarefas no RecyclerView é assim: 
package com.example.hellotarefas 
 
import androidx.appcompat.app.AppCompatActivity 
import android.os.Bundle 
import androidx.recyclerview.widget.LinearLayoutManager 
import kotlinx.android.synthetic.main.activity_main.* 
 
class MainActivity : AppCompatActivity() { 
 override fun onCreate(savedInstanceState: Bundle?) { 
 super.onCreate(savedInstanceState) 
 setContentView(R.layout.activity_main) 
 } 
 
 override fun onResume() { 
 super.onResume() 
 
 // (1) Busca a lista de tarefas 
 val tarefas = TarefaService.getTarefas() 
 
 // (2) Configura o layout do RecyclerView para Vertical 
 recyclerView.layoutManager = LinearLayoutManager(this) 
 
 // (3) Configura o adapter 
 recyclerView.adapter = TarefaAdapter(tarefas)} 
} 
A parte vermelha onde está a classe TarefaAdapter é o código que está 
faltando para o exemplo compilar, mas logo vamos ver isso. Por enquanto, segue 
explicações de cada parte do código: 
1. É uma boa prática deixar a lógica de inicialização da tela no método 
onResume() da activity. Nele, é feita a busca da lista de tarefas que 
retorna um objeto do tipo List<Tarefa>. 
2. O RecyclerView pode ter um layout de listas ou grid (várias colunas). Essa 
linha configura o template padrão de listas na vertical. 
3. O RecyclerView possui uma propriedade adapter que deve receber uma 
classe filha de RecyclerView.Adapter. É essa parte do código que está 
faltando para compilar. 
Agora, vamos falar da classe Adapter. Essa classe contém a lógica para 
preencher o conteúdo de cada célula, ou seja, preencher o conteúdo de cada 
 
 
linha da lista. O adapter também é uma dupla formada pela classe Kotlin ou Java, 
e o layout XML que será utilizado na célula. 
Lembra da figura na qual mostramos os arquivos que vamos criar neste 
exemplo? Veja-a novamente e perceba o local da classe TarefaAdapter e seu 
layout XML adapter_tarefa.xml. 
Dito isso, vamos criar o arquivo XML de layout para o adapter. Para isso, 
utilize o wizard > New > File e digite '.xml' na extensão ao criar o arquivo. Como 
padrão, os arquivos utilizados como Adapter (célula de uma lista) começam com 
a palavra 'adapter_', portanto, o nome do arquivo é adapter_tarefa.xml. 
● /res/layout/adapter_tarefa.xml 
<?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="wrap_content" 
 android:orientation="vertical" 
 android:padding="16dp"> 
 
 <TextView 
 android:id="@+id/tId" 
 android:layout_width="wrap_content" 
 android:layout_height="wrap_content" 
 android:textSize="20sp" /> 
 
 <TextView 
 android:id="@+id/tTitulo" 
 android:layout_width="wrap_content" 
 android:layout_height="wrap_content" 
 android:textSize="20sp" /> 
</LinearLayout> 
O layout do nosso exemplo é bem simples e contém um TextView onde 
vamos mostrar o ID (identificador) da tarefa, que no nosso caso será o número 
dela, como 1, 2, ou 3. O outro TextView é para mostrar o título da tarefa. Como 
podemos ver, o LinearLayout raiz foi configurado como vertical, assim, os textos 
vão ficar um embaixo do outro, conforme a figura com o layout da lista que 
mostramos anteriormente. 
Essa parte foi fácil, agora vamos para o código da classe do adapter. Para 
facilitar a explicação, o código está comentado com algumas cores. A classe 
TarefaAdapter recebe como parâmetro no construtor a lista de tarefas 
(List<Tarefa>) e é filha de RecyclerView.Adapter<TarefasViewHolder>. A classe 
TarefasViewHolder está declarada lá em baixo no mesmo arquivo. Precisamos 
 
 
criá-la apenas para fechar o contrato com o adapter, e dentro dela ficará 
armazenado a view da célula, que é o layout XML do adapter. 
package br.com.livroandroid.tarefas.adapter 
 
import android.view.LayoutInflater 
import android.view.View 
import android.view.ViewGroup 
import androidx.recyclerview.widget.RecyclerView 
import com.example.hellotarefas.Tarefa 
import com.example.hellotarefas.R 
import kotlinx.android.synthetic.main.adapter_tarefa.view.* 
 
// Define o construtor que recebe a lista de tarefas 
class TarefaAdapter(val tarefas: List<Tarefa>) : 
 RecyclerView.Adapter<TarefasViewHolder>() { 
 
 // (1) Retorna a quantidade de tarefas na lista 
 override fun getItemCount(): Int { 
 return this.tarefas.size 
 } 
 // (2) Infla o layout do adapter e retorna o ViewHolder 
 override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): 
TarefasViewHolder { 
 // Infla a view do adapter 
 val inflater = LayoutInflater.from(parent.context) 
 val view = inflater.inflate(R.layout.adapter_tarefa, parent, 
false) 
 val holder = TarefasViewHolder(view) 
 return holder 
 } 
 // (3) Faz o bind para atualizar o valor das views com os dados do 
Tarefa 
 override fun onBindViewHolder(holder: TarefasViewHolder, position: 
Int) { 
 // Recupera o objeto 
 val tarefa = tarefas[position] 
 // Recupera a view da linha 
 val view = holder.itemView 
 // Atualiza os dados nas views 
 view.tId.text = tarefa.id.toString() 
 view.tTitulo.text = tarefa.titulo 
 } 
} 
 
// Subclasse obrigatória de RecyclerView.ViewHolder 
// Ela é usada como tipo genérico ao criar a classe de adapter 
class TarefasViewHolder(view: View) : RecyclerView.ViewHolder(view) 
 
No código, você pode ver três métodos marcados em laranja. Esses 
métodos são obrigatórios e temos a explicação deles a seguir: 
1. getItemCount(): este método deve retornar a quantidade de linhas da 
lista, ou seja, do RecyclerView. A implementação desse método é simples 
e, geralmente, ele apenas retorna a quantidade de elementos contidos no 
array, ou lista de objetos, que foi passado como parâmetro para o 
 
 
construtor da classe do Adapter. No nosso caso, a lista contém três 
elementos. 
override fun getItemCount(): Int { 
 return this.tarefas.size 
} 
2. onCreateViewHolder(): este método deve inflar o layout XML do adapter, 
que é aquele adapter_tarefa.xml. No Android, o termo inflar um XML 
significa converter este XML para um objeto View. No código, esta linha 
faz justamente isso: 
val view = inflater.inflate(R.layout.adapter_tarefa, parent, false) 
Logo depois de inflar o XML da célula, é criado o objeto ViewHolder. 
Holder, em inglês, significa segurar, manter ou conter. Se traduzirmos, 
ViewHolder significa o objeto que "contém a view" desta célula. Veja, então, que 
ao criar o TarefasViewHolder, é passado no seu construtor o objeto view, que 
é o adapter_tarefa.xml convertido para objeto View. 
val holder = TarefasViewHolder(view) 
3. onBindViewHolder(): este é o último método que temos que implementar. 
A ideia é que o Android chame os dois primeiros métodos apenas uma 
vez, mas vai chamar o método onBindViewHolder() para o total de 
elementos na lista, que no nosso exemplo são três tarefas. 
Seguindo o raciocínio de traduzir o inglês para facilitar a explicação, a 
palavra bind significa ligação, no sentido de interligar alguma coisa a outra. 
Então, esse método onBindViewHolder() é usado para fazer a ligação entre o 
objeto Tarefa e o layout XML desta célula, lembrando que o ViewHolder é o 
objeto que “contém” este layout XML. Complicado, não é? Na prática, esse 
método vai recuperar o objeto Tarefa e vai configurar no XML da célula os 
valores desta tarefa: 
override fun onBindViewHolder(holder: TarefasViewHolder, position: 
Int) { 
 // Recupera o objeto 
 val tarefa = tarefas[position] 
 // Recupera a view da linha 
 val view = holder.itemView 
 // Atualiza os dados nas views 
 view.tId.text = tarefa.id.toString() 
 
 
 view.tTitulo.text = tarefa.titulo 
} 
Pronto! Com a classe de adapter criada, vamos atualizar o código da 
MainActivity. Veja que a lista de tarefas é passada para o construtor do adapter, 
pois ele saberá retornar aquele XML para cada célula da lista. 
package com.example.hellotarefas 
 
import androidx.appcompat.app.AppCompatActivity 
import android.os.Bundle 
import androidx.recyclerview.widget.LinearLayoutManager 
import br.com.livroandroid.tarefas.adapter.TarefaAdapter 
import kotlinx.android.synthetic.main.activity_main.* 
 
class MainActivity : AppCompatActivity() { 
 override fun onCreate(savedInstanceState: Bundle?) { 
 super.onCreate(savedInstanceState) 
 setContentView(R.layout.activity_main) 
 } 
 
 override fun onResume() { 
 super.onResume() 
 
 val tarefas = TarefaService.getTarefas() 
 recyclerView.layoutManager = LinearLayoutManager(this) 
 recyclerView.adapter = TarefaAdapter(tarefas) 
 } 
} 
Após fazer todas essas configurações,execute o projeto novamente no 
emulador e o resultado será a lista com as três tarefas, conforme mostramos 
anteriormente. 
Bom, essa foi a parte mais difícil. Os próximos exercícios serão mais 
fáceis. Até recomendamos que você prossega com todo o conteúdo da aula e 
depois fazça uma boa revisão sobre a classe do Adapter. 
Caso tenha achado difícil fazer a classe adapter, saiba que mesmo 
desenvolvedores experientes em Android utilizam a técnica do Ctrl+C + Ctrl+V 
para criar adapters, ou seja, depois que você faz um, simplesmente copia e, 
assim, para os próximos, vai apenas trocando os nomes. O adapter é aquele 
template que não muda, e logo você se acostuma. 
 
 
 
 
 
TEMA 3 – CARDVIEW + EVENTOS 
Para deixarmos o layout da lista de notas mais bonito, vamos envolver o 
layout do adapter com a classe CardView que faz parte da biblioteca do Material 
Design. 
Altere o código do do layout do adapter conforme mostrado a seguir: 
● /res/layout/adapter_tarefa.xml 
<?xml version="1.0" encoding="utf-8"?> 
<androidx.cardview.widget.CardView 
xmlns:android="http://schemas.android.com/apk/res/android" 
 android:layout_width="match_parent" 
 android:layout_height="wrap_content" 
 android:layout_margin="8dp" 
 android:foreground="?attr/selectableItemBackground"> 
 
 <LinearLayout 
 android:layout_width="match_parent" 
 android:layout_height="wrap_content" 
 android:orientation="vertical" 
 android:padding="16dp"> 
 <TextView 
 android:id="@+id/tId" 
 android:layout_width="wrap_content" 
 android:layout_height="wrap_content" 
 android:textSize="20sp" /> 
 <TextView 
 android:id="@+id/tTitulo" 
 android:layout_width="wrap_content" 
 android:layout_height="wrap_content" 
 android:textSize="20sp" /> 
 </LinearLayout> 
</androidx.cardview.widget.CardView> 
O CardView é um gerenciador de layout muito simples que cria o efeito de 
um cartão (card), deixando aquelas bordas no layout, algo que é muito comum 
hoje em dia nos aplicativos. 
 
 
 
 
 
 
 
Figura 5 – Lista de tarefas com card 
 
Crédito: Brostock/Shutterstock. 
3.1 Tratamento de eventos na lista 
Logo depois de criar a lista, com certeza o próximo passo é tratar os 
eventos de clique em cada célula. Para isso, temos que adicionar esta linha lá 
na view que é inflada do layout XML. 
view.setOnClickListener { } 
Esta linha podemos inserir lá no método onBindViewHolder() da classe 
do Adapter, conforme demonstrado abaixo: 
● TarefaAdapter.kt 
class TarefaAdapter(val tarefas: List<Tarefa>) . . . { 
 . . . 
 override fun onBindViewHolder(holder: TarefasViewHolder, position: Int) { 
 . . . 
 view.tId.text = tarefa.id.toString() 
 view.tTitulo.text = tarefa.titulo 
 . . . 
 view.setOnClickListener { } 
 } 
} 
 
 
Conforme já explicamos algumas vezes, o código que fica entre as chaves 
{ } é uma lambda, e por enquanto vamos deixar vazio. Ao executar o projeto 
novamente no emulador, você vai reparar que ao clicar em alguma célula, ela 
ficará selecionada, conforme mostra a próxima figura. 
Figura 6 – Célula selecionada ao clicar no item da lista 
 
Crédito: Brostock/Shutterstock. 
Com o evento de clique devidamente configurado na célula, vamos 
adicionar uma função de callback chamada onClick no construtor da classe do 
Adapter. Essa função vai receber como parâmetro o objeto Tarefa que foi clicado 
e não vai retornar nada, portanto, é Unit (void). 
val onClick: (Tarefa) -> Unit 
Faça a seguinte alteração no código. TarefaAdapter.kt 
class TarefaAdapter(val tarefas: List<Tarefa>, 
 val onClick: (Tarefa) -> Unit) : 
 RecyclerView.Adapter<TarefasViewHolder>() { 
 . . . 
 override fun onBindViewHolder(holder: TarefasViewHolder, position: Int) { 
 . . . 
 view.tId.text = tarefa.id.toString() 
 view.tTitulo.text = tarefa.titulo 
 . . . 
 
 
 view.setOnClickListener { onClick(tarefa) } 
 } 
} 
Pronto! Dentro do view.setOnClickListener { }, a função de callback será 
chamada passando como parâmetro a Tarefa. Isso que acabamos de fazer 
mostra como passar como parâmetro uma função, que é uma característica de 
linguagens de programação funcionais, paradigma que o Kotlin também 
implementa. 
Para finalizar o exemplo do tratamento de eventos, vamos passar como 
parâmetro uma função lambda para a classe TarefaAdapter. 
● MainActivity 
package com.example.hellotarefas 
 
import androidx.appcompat.app.AppCompatActivity 
import android.os.Bundle 
import android.widget.Toast 
import androidx.recyclerview.widget.LinearLayoutManager 
import br.com.livroandroid.tarefas.adapter.TarefaAdapter 
import kotlinx.android.synthetic.main.activity_main.* 
 
class MainActivity : AppCompatActivity() { 
 override fun onCreate(savedInstanceState: Bundle?) { 
 super.onCreate(savedInstanceState) 
 setContentView(R.layout.activity_main) 
 } 
 
 override fun onResume() { 
 super.onResume() 
 
 val tarefas = TarefaService.getTarefas() 
 recyclerView.layoutManager = LinearLayoutManager(this) 
 recyclerView.adapter = TarefaAdapter(tarefas) { 
 onClickTarefa(it) 
 } 
 } 
 
 private fun onClickTarefa(t: Tarefa) { 
 Toast.makeText(this,"Tarefa: ${t.titulo}", 
Toast.LENGTH_SHORT).show() 
 } 
} 
Pronto. Feito isso, ao clicar em uma célula da lista, o método 
onClickTarefa(tarefa) será chamado. No entanto, observe que há uma 
novidade: o Toast. 
Utilizar o Toast não requer prática nem habilidade, pois ele apenas mostra 
um breve alerta para o usuário. No Android, o Toast é aquele alerta rápido com 
um formato de balão, e que fica visível por poucos segundos. Ao criar o Toast, 
 
 
você pode informar o tempo com as constantes LENGTH_SHORT (2 segundos) 
ou LENGTH_LONG (5 segundos) 
Figura 7 – Alerta com Toast 
 
Crédito: Brostock/Shutterstock. 
Apesar de já termos estudado lambdas, vamos revisar rapidamente como 
passar funções como parâmetros. Como a classe TarefaAdapter recebe uma 
lista de objetos do tipo Tarefa e a função, podemos passar diretamente a função 
como parâmetro com a seguinte sintaxe: 
recyclerView.adapter = TarefaAdapter(tarefas, ::onClickTarefa) 
Naturalmente, a função onClickTarefa(tarefa) precisa existir e ter os 
mesmos parâmetros esperados, que neste caso é o objeto Tarefa. 
Outra maneira é usando a sintaxe da lambda, abrindo e fechando chaves 
{}. 
recyclerView.adapter = TarefaAdapter(tarefas, { 
 tarefa -> onClickTarefa(tarefa) 
}) 
 
 
 
Neste caso, aquela variável tarefa seguida da seta pode ser omitida, pois 
no Kotlin podemos usar o parâmetro it, que é implícito. Naturalmente, a variável 
it só pode ser usado se a função possui apenas um único parâmetro, que é este 
caso. 
recyclerView.adapter = TarefaAdapter(tarefas, { 
 onClickTarefa(it) 
}) 
Por fim, veja no código anterior que a lambda ficou dentro dos parênteses, 
pois ela é um argumento como outro qualquer que é enviado no construtor da 
classe TarefaAdapter. Mas, como também já estudamos, sempre que a lambda 
for o último argumento, podemos abrir e fechar as chaves depois dos parênteses 
com esta sintaxe: 
recyclerView.adapter = TarefaAdapter(tarefas) { 
 onClickTarefa(it) 
} 
Concluindo a explicação, esta última sintaxe é a mais adotada nos 
aplicativos e também é muito comum em outras linguagens. 
3.2 Criando uma extensão para o Toast 
Ao explicarmos, gostamos muito de passar nossa linha de raciocínio para 
você e algo que sempre temos em mente é não digitar códigos chatos e que são 
muito repetitivos. Aquele código para criar um Toast é um que com certeza 
merece ser abreviado. 
Lembra-se de quando criamos uma extensão para a activity para mostrar 
um alerta? Copie o arquivo Activity-Extensions.kt que fizemos naquele outro 
exemplo e adicione o método toast(). O método vai receber a mensagem que 
deveser exibida no alerta e o parâmetro 'duration' opcional, que por padrão 
possui o valor da constante Toast.LENGTH_SHORT. 
● Activity-Extensions.kt 
package com.example.hellotarefas.extensions 
 
import android.widget.Toast 
import androidx.appcompat.app.AlertDialog 
import androidx.appcompat.app.AppCompatActivity 
 
fun AppCompatActivity.alert(msg: String, callback: () -> Unit 
 
 
= {}) { 
 . . . 
} 
 
fun AppCompatActivity.toast(msg: String, duration: Int = 
Toast.LENGTH_SHORT) { 
 Toast.makeText(this,msg, duration).show() 
} 
Pronto! Agora, para fazer um toast, fica bem simples. Lembre-se que para 
utilizar extensões, precisamos fazer o import, mas isso o Android Studio sempre 
vai nos ajudar. 
package com.example.hellotarefas 
 
import com.example.hellotarefas.extensions.toast 
 
class MainActivity : AppCompatActivity() { 
 . . . 
 private fun onClickTarefa(t: Tarefa) { 
 toast("Tarefa: ${t.titulo}") 
 } 
} 
TEMA 4 – TELA DE DETALHES DA TAREFA 
Já aprendemos como criar a lista de tarefas, e agora vamos partir para a 
segunda parte do nosso exercício, que será implementar as seguintes 
funcionalidades: 
1. Ao clicar em uma tarefa, vamos abrir a tela de detalhes da tarefa; 
2. A tela da tarefa poderá ser utilizada para criar uma nova tarefa ou editar 
uma que já existe; 
3. Vamos adicionar um botão para criar uma nova tarefa na lista. Esse botão 
é aquele (+) na parte inferior direita da lista. 
4. Na tela de detalhes da tarefa, vamos adicionar um botão para remover a 
tarefa. Esse botão é aquele (X) na AppBar. 
Esta figura mostra o exercício completo para você já ir visualizando o nosso 
objetivo. 
 
 
 
Figura 8 – Cadastro de tarefas 
 
Crédito: Brostock/Shutterstock. 
4.1 Tela da tarefa 
O primeiro passo para criar o cadastro de tarefas é criar a tela que possui 
o formulário para inserir ou editar uma tarefa. Essa tela, como você já sabe, será 
uma nova activity, que vamos chamar de TarefaActivity. 
Crie essa activity com o wizard > New > Activity > Empty Activity. Ao 
utilizar o wizard, a activity será configurada automaticamente no arquivo de 
manifesto: 
<activity android:name=".TarefaActivity" /> 
Feito isso, vamos criar o formulário que vai conter o título da tarefa. No 
formulário, não vamos mostrar o id da tarefa, ele ficará escondido para simular 
o id do banco de dados. 
● /res/layout/activity_tarefa.xml 
<LinearLayout android:layout_width="match_parent" 
 android:layout_height="match_parent" 
 android:orientation="vertical" 
 android:padding="16dp" 
 xmlns:android="http://schemas.android.com/apk/res/android"> 
 <TextView 
 android:layout_width="wrap_content" 
 
 
 android:layout_height="wrap_content" 
 android:text="Título" /> 
 <EditText 
 android:id="@+id/tTitulo" 
 android:layout_width="match_parent" 
 android:layout_height="wrap_content" 
 /> 
 <Button 
 android:id="@+id/btSalvar" 
 android:layout_width="wrap_content" 
 android:layout_height="wrap_content" 
 android:layout_gravity="center" 
 android:text="Salvar" /> 
</LinearLayout> 
Por fim, vamos criar o código da classe TarefaActivity. Por enquanto, o 
botão Salvar ainda não fará nada. Neste momento, no método onCreate(), 
vamos ler o objeto Tarefa que será passado como parâmetro e estamos 
chamando o método setTarefa(t) para atualizar o formulário com os dados deste 
objeto. 
● TarefaActivity 
package com.example.hellotarefas 
 
import android.os.Bundle 
import androidx.appcompat.app.AppCompatActivity 
import kotlinx.android.synthetic.main.activity_tarefa.* 
 
class TarefaActivity : AppCompatActivity() { 
 override fun onCreate(savedInstanceState: Bundle?) { 
 super.onCreate(savedInstanceState) 
 setContentView(R.layout.activity_tarefa) 
 
 // Configura botão voltar e o título 
 supportActionBar?.setDisplayHomeAsUpEnabled(true) 
 supportActionBar?.title = "Tarefa" 
 
 // Recebe o objeto passado como parâmetro 
 val tarefa = intent.getSerializableExtra("tarefa") as 
Tarefa? 
 
 // Atualiza a tela com os dados da tarefa 
 setTarefa(tarefa) 
 } 
 
 private fun setTarefa(t: Tarefa?) { 
 if(t != null) { 
 tTitulo.setText(t.titulo) 
 } 
 } 
} 
 
 
 
Lembrando que nosso objetivo é que, ao clicar em alguma tarefa na lista, 
vamos abrir essa tela de detalhes e o objeto tarefa será passado como 
parâmetro. Por isso, quando criamos a classe Tarefa, fizemos ela implementar 
a interface Serializable. 
package com.example.hellotarefas 
 
import java.io.Serializable 
 
data class Tarefa( 
 var id: Int = 0, 
 var titulo: String = "" 
 
) : Serializable 
Observe que ao ler o parâmetro tarefa da intent, foi feito o casto para 
Tarefa? com a interrogação, o que indica que este objeto pode ser nulo. 
val tarefa = intent.getSerializableExtra("tarefa") as Tarefa? 
Pela regra deste aplicativo fictício, a tela com o formulário pode ser 
chamada em duas situações: 
1. Na tela inicial, o usuário clicou em alguma tarefa da lista. Neste caso, o 
app vai abrir a TarefaActivity passando como parâmetro o objeto tarefa. 
2. Na tela inicial, o usuário clicou no botão (+) para criar uma nova tarefa. 
Neste caso, o parâmetro tarefa estará nulo e por isso o objeto Tarefa? 
foi declarado com a interrogação. Na lógica da activity, no método 
setTarefa(t), precisamos verificar se a tarefa existe antes de mostrar os 
seus dados no formulário. 
Algo interessante deste exemplo e que ainda não tínhamos visto está lá 
no método onCreate() da activity: 
// Configura botão voltar e o título 
supportActionBar?.setDisplayHomeAsUpEnabled(true) 
supportActionBar?.title = "Tarefa" 
A primeira linha está habilitando o botão de voltar na App Bar (aquele do 
canto superior esquerdo), porém, o botão voltar ainda não vai funcionar, e vamos 
ver isso no próximo exemplo. A segunda linha está configurando o título na App 
Bar. 
 
 
Obsservação: você vai encontrar exemplos falando de Action Bar e 
outros de App Bar, mas podemos dizer que são sinônimos. 
4.1 Voltar para a tela anterior 
Até o momento, já podemos clicar em alguma tarefa na lista e abrir a tela 
de detalhes, mas o botão de voltar da App Bar ainda não funciona. Apenas para 
deixar bem claro, temos duas maneiras de mostrar o botão Voltar na App Bar: 
1. Adicionar o atributo parentActivityName no arquivo de manifesto, como 
fizemos no projeto em que criamos layouts para as telas de login, cadastro 
e esqueci senha. Neste caso, o Android implementa a ação de voltar 
automaticamente. 
2. Utilizar o método setDisplayHomeAsUpEnabled(true) da classe 
ActionBar. Neste caso, ainda temos que implementar o método 
onOptionsItemSelected(item) na activity (a fazer ainda). 
O primeiro jeito de fazer é mais simples, pois basta configurar o arquivo 
de manifesto, expliquei dessa maneira antes. Mas, ao fazer isso, o Android vai 
fechar todas as activities e vai dar um startActivity novamente na activity definida 
lá no atributo parentActivityName. Ou seja, a tela será recriada e pode perder 
o seu estado. 
Para manter o estado o desejado é que o botão Voltar da App Bar (lá de 
cima) tem o mesmo efeito do botão voltar nativo do Android (lá de baixo), que é 
apenas fechar a tela, desempilhando essa activity da pilha de atividades (activity 
stack). 
O código a seguir mostra como implementar o método 
onOptionsItemSelected(item), o qual é chamado sempre que um botão da App 
Bar é clicado, independentemente se é o botão de Voltar ou outra ação. 
class TarefaActivity : AppCompatActivity() { 
 . . . 
 
 override fun onOptionsItemSelected(item: MenuItem?): Boolean { 
 when (item?.itemId) { 
 android.R.id.home -> { 
 finish() 
 } 
 } 
 return super.onOptionsItemSelected(item) 
 } 
 
 
} 
 
Neste método, geralmente é feita uma comparação para ver o id do item 
de menu que foi clicado. Porpadrão, o id do botão voltar é android.R.id.home, 
conforme você viu no código. 
Observação: tenha atenção, pois no Android, temos duas ou mais 
classes R. Temos uma classe R que fica no nosso próprio projeto e contém 
acesso aos recursos que estão lá na pasta /res/, como imagens e strings com 
textos. Porém, veja que nesse caso usamos a classe android.R, isso significa 
que esta é a classe R nativa do Android. 
Para finalizar este tópico, veja novamente a figura que mostramos as telas 
do aplicativo de tarefas com o cadastro funcionando. Na tela da tarefa, vamos 
adicionar posteriormente o botão deletar (X) na App Bar. Apenas adiantando, a 
ação desse botão também será implementada dentro do método 
onOptionsItemSelected(item) que acabamos de fazer. Mas para excluir uma 
tarefa, antes precisamos criá-la, e isso vamos fazer no próximo tópico. 
4.2 FAB – Floating Action Button (+) 
Aquele botão (+) redondo que vamos colocar na lista de tarefas é 
conhecido como Floating Action Button (botão flutuante) e também faz parte dos 
padrões do Material Design. Como este é um botão flutuante, ele precisa ser 
adicionado dentro de um CoordinatorLayout, que é um layout especial do 
Material Design que consegue controlar a disposição dos elementos e inclusive 
fazer técnicas de scroll (rolagem) mais avançadas que um dia você vai estudar. 
Mas por enquanto, vamos criar o seguinte layout. 
<?xml version="1.0" encoding="utf-8"?> 
<androidx.coordinatorlayout.widget.CoordinatorLayout 
xmlns:android="http://schemas.android.com/apk/res/android" 
 android:layout_width="match_parent" 
 android:layout_height="match_parent" 
 xmlns:app="http://schemas.android.com/apk/res-auto"> 
 
 <androidx.recyclerview.widget.RecyclerView 
 android:id="@+id/recyclerView" 
 android:layout_width="match_parent" 
 android:layout_height="wrap_content" 
 /> 
 
 
 
 <com.google.android.material.floatingactionbutton.FloatingActionButton 
 android:id="@+id/fab" 
 android:layout_width="wrap_content" 
 android:layout_height="wrap_content" 
 android:layout_gravity="end|bottom" 
 app:tint="@android:color/white" 
 android:src="@android:drawable/ic_input_add" 
 android:layout_margin="16dp" /> 
 
</androidx.coordinatorlayout.widget.CoordinatorLayout> 
Conforme vimos, para adicionar o botão FAB (Floating Action Button), 
existe um XML ligeiramente grande que pode assustar no início, mas leia cada 
linha com atenção que logo você se acostuma e verá que cada linha faz sentido. 
Veja que foi configurado o id android:id="@+id/fab" para o botão, e vale 
lembrar também que é comum desenvolvedores Android falaram apenas "botão 
FAB" no lugar de Floating Action Button, pois é uma forma mais abreviada, 
simples de falar. No Material Design, um botão FAB representa a ação mais 
importante da tela e geralmente possui apenas um no layout. Por isso, sempre 
utilizarmos o id android:id="@+id/fab". Dito isso, vamos para o código: 
package com.example.hellotarefas 
 
. . . 
import kotlinx.android.synthetic.main.activity_main.* 
 
class MainActivity : AppCompatActivity() { 
 override fun onCreate(savedInstanceState: Bundle?) { 
 super.onCreate(savedInstanceState) 
 setContentView(R.layout.activity_main) 
 
 fab.setOnClickListener { onClickAddTarefa() } 
 } 
 
 private fun onClickAddTarefa() { 
 startActivity(Intent(this, TarefaActivity::class.java)) 
 } 
} 
Ao executar o projeto novamente no emulador, você verá que 
adicionamos o evento de clique no botão FAB e que ele está abrindo a activity 
com o formulário da tarefa. Ao abrir o formulário, ele estará vazio e pronto para 
salvar uma nova tarefa. 
 
 
 
TEMA 5 – SALVANDO AS TAREFAS 
Para salvar as tarefas, teremos que adicionar um método salvar(tarefa) 
na classe TarefaService, mas antes precisamos ter uma maneira de salvar essa 
tarefa. Como explicado anteriormente, vamos salvar as tarefas em uma 
HashTable que ficará em memória no aplicativo, ou seja, se você fechar e abrir 
o aplicativo, as tarefas serão perdidas. Mas, no momento, isso vai cumprir nosso 
objetivo: estudar listas e outros detalhes do Android. 
Para prosseguir, altere a classe TarefaService para ficar assim: 
import com.example.hellotarefas.Tarefa 
 
object TarefaService { 
 
 private var count = 0 
 // HashTable 
 private val tarefas = mutableMapOf<Int, Tarefa>() 
 
 init { 
 for (i in 1..3) { 
 tarefas.put(i, Tarefa(i,"Tarefa $i")) 
 count = i 
 } 
 } 
 fun save(t: Tarefa) { 
 if(t.id == 0) { 
 // Gera um id 
 t.id = ++count 
 } 
 tarefas.put(t.id, t) 
 } 
 fun remove(tarefa: Tarefa) { 
 tarefas.remove(tarefa.id) 
 } 
 fun getTarefas(): List<Tarefa> { 
 return tarefas.values.toList() 
 } 
} 
Observe que agora as tarefas ficam salvas em um Map (HashTable), cuja 
chave é um Int (id da tarefa) e o conteúdo é o objeto Tarefa. 
O método getTarefas() retorna a lista que está contida dentro deste Map. 
O método saveTarefa(t) adiciona a tarefa no Map utilizando o id. Caso o 
id não exista, significa que é uma nova tarefa, e por isso estamos incrementando 
a variável count para simular o id do banco de dados. 
O método remove(t) vai remover a tarefa do Map utilizando o seu id. 
 
 
Com isso, temos métodos para fazer a famosa operação de cadastro, 
conhecida como CRUD (Create, Read, Update and Delete). Futuramente, 
podemos até alterar a implementação dessa classe para usar banco de dados, 
como por exemplo, o SQLite. Essa é a vantagem de separar a lógica em várias 
classes e cada uma ter sua responsabilidade. 
5.1 Salvando e excluindo uma tarefa 
Para finalizar nosso cadastro, vamos mostrar o código final do exemplo. 
Apenas para sua conferência, segue o código completo da MainActivity – caso 
você tenha seguido todos os passos, já fez esse código. 
● MainActivity 
package com.example.hellotarefas 
 
import android.content.Intent 
import android.os.Bundle 
import androidx.appcompat.app.AppCompatActivity 
import androidx.recyclerview.widget.LinearLayoutManager 
import br.com.livroandroid.tarefas.adapter.TarefaAdapter 
import kotlinx.android.synthetic.main.activity_main.* 
 
class MainActivity : AppCompatActivity() { 
 override fun onCreate(savedInstanceState: Bundle?) { 
 super.onCreate(savedInstanceState) 
 setContentView(R.layout.activity_main) 
 
 fab.setOnClickListener { onClickAddTarefa() } 
 } 
 override fun onResume() { 
 super.onResume() 
 
 val tarefas = TarefaService.getTarefas() 
 recyclerView.layoutManager = LinearLayoutManager(this) 
 recyclerView.adapter = TarefaAdapter(tarefas) { 
 onClickTarefa(it) 
 } 
 } 
 private fun onClickTarefa(t: Tarefa) { 
 val intent = Intent(this, TarefaActivity::class.java) 
 intent.putExtra("tarefa",t) 
 startActivity(intent) 
 } 
 private fun onClickAddTarefa() { 
 startActivity(Intent(this, TarefaActivity::class.java)) 
 } 
} 
E o código da classe TarefaActivity vai ficar conforme mostramos a seguir 
(as partes novas estão destacadas em amarelo). 
 
 
package com.example.hellotarefas 
 
import android.os.Bundle 
import android.view.Menu 
import android.view.MenuItem 
import androidx.appcompat.app.AppCompatActivity 
import kotlinx.android.synthetic.main.activity_tarefa.* 
 
class TarefaActivity : AppCompatActivity() { 
 private var tarefa: Tarefa? = null 
 
 override fun onCreate(savedInstanceState: Bundle?) { 
 super.onCreate(savedInstanceState) 
 setContentView(R.layout.activity_tarefa) 
 
 // Configura botão voltar e o título 
 supportActionBar?.setDisplayHomeAsUpEnabled(true) 
 supportActionBar?.title = "Tarefa" 
 
 // Recebe o objeto passado como parâmetro 
 this.tarefa = intent.getSerializableExtra("tarefa") as Tarefa? 
 
 // Atualiza a tela com os dados da tarefa 
 setTarefa(tarefa)btSalvar.setOnClickListener { onClickSalvar() } 
 } 
 private fun setTarefa(tarefa: Tarefa?) { 
 if(tarefa != null) { 
 tTitulo.setText(tarefa.titulo) 
 } 
 } 
 // Cria os itens de menu na App Bar (ex: botão deletar) 
 override fun onCreateOptionsMenu(menu: Menu?): Boolean { 
 menuInflater.inflate(R.menu.menu_tarefa, menu) 
 val item = menu?.findItem(R.id.action_delete) 
 if(item != null) { 
 item.setVisible(tarefa != null) 
 } 
 return super.onCreateOptionsMenu(menu) 
 } 
 override fun onOptionsItemSelected(item: MenuItem?): Boolean { 
 when (item?.itemId) { 
 android.R.id.home -> { 
 finish() 
 } 
 R.id.action_delete -> { 
 onClickDeletar() 
 } 
 } 
 return super.onOptionsItemSelected(item) 
 } 
 private fun onClickSalvar() { 
 val tarefa = getTarefa() 
 
 
 
 TarefaService.save(tarefa) 
 
 finish() 
 } 
 private fun onClickDeletar() { 
 tarefa?.let { 
 TarefaService.remove(it) 
 finish() 
 } 
 } 
 private fun getTarefa(): Tarefa { 
 val n = this.tarefa?: Tarefa() 
 n.titulo = tTitulo.text.toString() 
 return n 
 } 
} 
Esperamos que a maior parte desse código seja tranquila para você, pois 
já fizemos um exemplo parecido de cadastro nas primeiras aulas. Então, vamos 
ao que é mais importante. 
Primeiramente, o método onCreateOptionsMenu(menu) é responsável 
por configurar os botões que vão aparecer na App Bar, e para isso, temos que 
criar outro arquivo XML, que vai conter essas ações. Crie uma pasta menu 
dentro da pasta res e crie o arquivo menu_tarefa.xml conforme indicado na 
figura a seguir: 
Figura 9 – Arquivo para criar um menu 
 
 
 
 
● menu_tarefa.xml 
<menu xmlns:android="http://schemas.android.com/apk/res/android" 
 xmlns:app="http://schemas.android.com/apk/res-auto"> 
 <item 
 android:id="@+id/action_delete" 
 app:showAsAction="always" 
 android:icon="@android:drawable/ic_delete" /> 
</menu> 
O XML de menu contém os itens de menu que vão aparecer na App Bar, 
que no nosso caso é apenas o botão de deletar. A figura do botão deixamos com 
aquele ícone de (X) padrão do Android e o id foi configurado como 
action_delete. Esse id é usado para tratar o evento de quando o usuário tocar 
neste item de menu lá no método onOptionsItemSelected(item). 
R.id.action_delete -> { 
 onClickDeletar() 
} 
Outro ponto importante de código: veja que o objeto Tarefa foi deixado 
como atributo da classe, pois precisamos acessar ele dentro dos métodos 
onClickSalvar() e onClickDeletar(), assim, esse objeto possui um escopo 
global dentro da classe. 
private var tarefa: Tarefa? = null 
Por isso, lá no método onCreate(bundle), estamos atribuindo o objeto 
tarefa para este atributo e não mais uma variável local, observe o 'this.tarefa': 
this.tarefa = intent.getSerializableExtra("tarefa") as Tarefa? 
Dito isso, existem duas lógicas pequenas dentro dos métodos de salvar e 
deletar. 
No método onClickSalvar(), é utilizado o operador Elvis explicado na aula 
de Kotlin para criar o objeto tarefa. O objetivo é utilizar o objeto tarefa se ele já 
existe para atualizar os dados, ou criar uma nova instância do objeto caso ele 
não exista. Isso é feito nesta linha: 
val n = this.tarefa?: Tarefa() 
 
 
No caso da atualização da tarefa, isso é importante, pois preservamos a 
mesma instância do objeto que foi passado como parâmetro para a activity e, 
portanto, é uma tarefa que já possui id. 
No método onClickDeletar(), estamos usando a palavra reservada let do 
Kotlin que ainda não tínhamos estudado. 
private fun onClickDeletar() { 
 tarefa?.let { 
 TarefaService.remove(it) 
 finish() 
 } 
} 
O let é utilizado porque o objeto Tarefa? foi declarado com a interrogação 
ao criar o atributo de classe e, portanto, pode ser nulo. A expressão entre chaves 
do let só vai executar caso esse objeto não seja nulo. 
Esse código faz o mesmo que este 'if', e podemos dizer que é uma sintaxe 
mais moderna e adotada pelos desenvolvedores Kotlin. O let também está 
presente em outras linguagens como o Swift utilizado no iOS, aliás, muito do que 
estudamos aqui funciona de forma similar no iOS. Um dia, você vai perceber que 
as linguagens são todas iguais e o que importa são os conceitos, técnicas de 
programação e design patterns que você conhece, ou seja, no final, código é só 
código. 
private fun onClickDeletar() { 
 val t = this.tarefa 
 if(t != null) { 
 TarefaService.remove(t) 
 finish() 
 } 
} 
FINALIZANDO 
Nesta aula, aprendemos a criar listas com os componentes RecyclerView 
e CardView, e fizermos um exercício de como criar um formulário de cadastro. 
 
 
 
REFERÊNCIAS 
LECHETA, R. Android Essencial com Kotlin. 2. ed. 2018.

Continue navegando