15/03/2022 18:34 UNINTER https://univirtus.uninter.com/ava/web/roa/ 1/37 PROGRAMAÇÃO IV AULA 4 Prof. Ricardo Rodrigues Lecheta 15/03/2022 18:34 UNINTER https://univirtus.uninter.com/ava/web/roa/ 2/37 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. 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. 15/03/2022 18:34 UNINTER https://univirtus.uninter.com/ava/web/roa/ 3/37 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 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: 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: 15/03/2022 18:34 UNINTER https://univirtus.uninter.com/ava/web/roa/ 4/37 O método setOnClickListener recebe como parâmetro um objeto que implementa a interface OnClickListener. O único método desta interface é o onClick(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?). 15/03/2022 18:34 UNINTER https://univirtus.uninter.com/ava/web/roa/ 5/37 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. 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 https://kotlinlang.org/docs/reference/control-flow.html#when-expression 15/03/2022 18:34 UNINTER https://univirtus.uninter.com/ava/web/roa/ 6/37 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. 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: 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. 15/03/2022 18:34 UNINTER https://univirtus.uninter.com/ava/web/roa/ 7/37 Para concluir, algo que gosto de fazer para deixar o código ainda mais organizado é criar um mé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. 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. 15/03/2022 18:34 UNINTER https://univirtus.uninter.com/ava/web/roa/ 8/37 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: Feito isso, basta adicionar o método desejado na classe da activity. 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. 15/03/2022 18:34 UNINTER https://univirtus.uninter.com/ava/web/roa/ 9/37 Portanto, a solução que vamos adotar é o uso de lambdas.