Conceitos básicos do Kotlin para Android 01.3: recursos e compatibilidade de imagens

Este codelab faz parte do curso Conceitos básicos do Kotlin para Android. Você aproveitará mais o curso se fizer os codelabs em sequência. Todos os codelabs do curso estão listados na página de destino dos codelabs do curso Conceitos básicos do Kotlin para Android.

Introdução

Neste codelab, você vai melhorar o app DiceRoller do último codelab e aprender a adicionar e usar recursos de imagem no seu app. Você também aprenderá sobre a compatibilidade com diferentes versões do Android e como o Android Jetpack pode ajudar.

O que você já precisa saber

  • Como criar um novo projeto de app e executar um app em um emulador ou dispositivo físico.
  • Os componentes básicos de um projeto de app, incluindo o diretório de recursos (res) e arquivos de compilação do Gradle.
  • Como editar o arquivo de layout do app.
  • Como encontrar e modificar objetos de visualização no código do app.

O que você aprenderá

  • Como adicionar arquivos aos recursos do seu app.
  • Como usar imagens no layout do seu app.
  • Como encontrar visualizações com mais eficiência no código do app.
  • Como usar imagens de marcador no design do seu app com namespaces XML.
  • Sobre os níveis da API do Android para seu app e como entender os níveis de API mínimos, segmentados e compilados.
  • Como usar as bibliotecas do Jetpack no seu app para oferecer compatibilidade com versões mais antigas do Android.

Atividades do laboratório

  • Modifique o app DiceRoller do último codelab para incluir imagens do valor "die", em vez de um número.
  • Adicione arquivos de imagem aos recursos do app.
  • Atualize o layout e o código do app para usar imagens no valor do dado, em vez de um número.
  • Atualize seu código para encontrar visualizações com mais eficiência.
  • Atualize seu código para usar uma imagem vazia quando o app for iniciado.
  • Atualize seu app para usar as bibliotecas do Android Jetpack e oferecer compatibilidade com versões anteriores do Android.

Neste codelab, você usará o app DiceRoller iniciado no codelab anterior e adicionará imagens de dados que mudam quando o dado é jogado. O app DiceRoller ficará assim:

Se você não tiver concluído o último codelab, faça o download do app inicial aqui: DiceRoller.

Ao final do último codelab, você tinha um app que atualiza uma visualização de texto com um número entre 1 e 6 cada vez que o usuário toca em um botão. No entanto, o app se chama DiceRoller, e não o Gerador de número de 1 a 6. Por isso, seria ótimo se o dado fosse parecido com um dado. Nesta tarefa, você adicionará algumas imagens ao app. Em vez de atualizar o texto quando o botão for pressionado, troque a imagem de cada resultado.

Etapa 1: adicione as imagens

  1. Abra o projeto do app DiceRoller no Android Studio, se ele ainda não estiver aberto. Se você não tiver concluído o último codelab, faça o download do app aqui: DiceRoller.
  2. Na visualização Project > Android, expanda a pasta res e depois drawable.



    Seu app usa muitos recursos diferentes, incluindo imagens e ícones, cores, strings e layouts XML. Todos esses recursos são armazenados na pasta res. Coloque todos os recursos de imagem do app na pasta drawable. Já na pasta drawable, você encontra os recursos dos ícones na tela de início do app.
  3. Clique duas vezes em ic_launcher_background.xml. Observe que esses são arquivos XML que descrevem o ícone como uma imagem vetorial. Os vetores permitem que suas imagens sejam desenhadas em diferentes tamanhos e resoluções. As imagens de bitmap, como PNG ou GIF, talvez precisem ser dimensionadas para diferentes dispositivos, o que pode resultar em perda de qualidade.
  4. Clique em Visualizar na coluna à direita do editor de XML para ver o drawable vetorial em formato visual.


  5. Faça o download das imagens de dados do app em DiceImages.zip. Descompacte o arquivo. Você terá uma pasta de arquivos XML semelhante a esta:

  1. No Android Studio, clique no menu suspenso na parte superior da visualização do projeto que indica Android e escolha Project. A captura de tela abaixo mostra como é a estrutura do app no sistema de arquivos.


  2. Expanda DiceRoller > app > src > main > res > drawable.
  3. Arraste todos os arquivos XML individuais da pasta DiceImages para o Android Studio e para a pasta drawable. Clique em OK.
  1. Volte para a visualização Android e observe que os arquivos XML da imagem do dado estão na pasta de drawable.
  2. Clique duas vezes em dice_1.xml e observe o código XML da imagem. Clique no botão Visualizar para ver como ficará o drawable vetorial.

Etapa 2: atualizar o layout para usar imagens

Agora que você tem os arquivos de imagem de dados na pasta res/drawables, é possível acessá-los no layout e código do app. Nesta etapa, você substituirá o TextView que exibe os números por uma ImageView para exibir as imagens.

  1. Abra o arquivo de layout activity_main.xml se ele ainda não estiver aberto. Clique na guia Text para ver o código XML do layout.
  2. Exclua o elemento <TextView>.
  3. Adicione um elemento <ImageView> com estes atributos:
<ImageView
   android:id="@+id/dice_image"
   android:layout_width="wrap_content"
   android:layout_height="wrap_content"
   android:layout_gravity="center_horizontal"
   android:src="@drawable/dice_1" />

Use uma ImageView para exibir uma imagem no layout. O único novo atributo desse elemento é android:src, que indica o recurso de origem da imagem. Nesse caso, uma origem de imagem @drawable/dice_1 significa que o Android precisa procurar a imagem chamada dice_1 nos recursos drawable.

  1. Clique no botão Visualizar para ver o layout. Ele ficará assim:

Etapa 3: atualizar o código

  1. Abra o MainActivity Veja a função rollDice() até agora:
private fun rollDice() {
   val randomInt = Random().nextInt(6) + 1

   val resultText: TextView = findViewById(R.id.result_text)
   resultText.text = randomInt.toString()
}

Observe que a referência à R.id.result_text pode ser destacada em vermelho porque isso excluiu o TextView do layout, e esse ID não existe mais.

  1. Exclua as duas linhas no final da função que definem a variável resultText e a propriedade de texto dela. Como você não usa mais um TextView no layout, nenhuma linha é necessária.
  2. Use findViewByID() para conseguir uma referência ao novo ImageView no layout por ID (R.id.dice_image) e atribua essa visualização a uma nova variável diceImage:
val diceImage: ImageView = findViewById(R.id.dice_image)
  1. Adicione um bloco when para escolher uma imagem específica com base no valor de randomInteger:
val drawableResource = when (randomInt) {
   1 -> R.drawable.dice_1
   2 -> R.drawable.dice_2
   3 -> R.drawable.dice_3
   4 -> R.drawable.dice_4
   5 -> R.drawable.dice_5
   else -> R.drawable.dice_6
}

Assim como nos IDs, é possível referenciar as imagens de dados na pasta de drawable com os valores da classe R. Aqui, R.drawable refere-se à pasta de drawables do app, e dice_1 é um recurso de imagem de dado específico dentro dessa pasta.

  1. Atualize a origem do ImageView com o método setImageResource() e a referência à imagem de dados que você acabou de encontrar.
diceImage.setImageResource(drawableResource)
  1. Compile e execute o app. Agora, quando você clicar no botão Jogar, a imagem deverá ser atualizada com a imagem apropriada.

Tudo no seu app funciona, mas não se resume apenas ao desenvolvimento de apps. Você também precisa entender como criar apps com bom desempenho e bom comportamento. Isso significa que seus apps devem funcionar bem, mesmo que o usuário não tenha o dispositivo Android mais caro ou a melhor conectividade de rede. Os apps também continuarão sendo executados sem problemas à medida que adicionar mais recursos. Além disso, o código precisa ser legível e bem organizado.

Nesta tarefa, você aprenderá como tornar seu app mais eficiente.

  1. Abra o MainActivity, caso ainda não esteja aberto. No método rollDice(), observe a declaração da variável diceImage:
val diceImage : ImageView = findViewById(R.id.dice_image)

Como rollDice() é o gerenciador de cliques do botão Jogar, sempre que o usuário tocar nesse botão, seu app chamará findViewById() e receberá outra referência para esse ImageView. O ideal é minimizar o número de chamadas para findViewById(), porque o sistema Android pesquisa a hierarquia de visualização toda vez, e essa é uma operação cara.

Em um app pequeno como esse, isso não é um grande problema. Se você estiver executando um app mais complicado em um smartphone mais lento, chamar findViewById() continuamente poderá causar lentidão no app. Uma prática recomendada é chamar findViewById() apenas uma vez e armazenar o objeto View em um campo. Manter a referência à ImageView em um campo permite que o sistema acesse a View diretamente a qualquer momento, o que melhora o desempenho.

  1. Na parte superior da classe, antes de onCreate(), crie um campo para armazenar o ImageView.
var diceImage : ImageView? = null

O ideal é inicializar essa variável aqui quando ela for declarada ou em um construtor, mas as atividades do Android não usam construtores. Na verdade, as visualizações do layout não são objetos acessíveis na memória até serem infladas no método onCreate(), pela chamada para setContentView(). Não é possível inicializar a variável diceImage até que isso aconteça.

Uma opção é definir a variável diceImage como anulável, como neste exemplo. Defina-o como null quando ele for declarado e atribua-o ao ImageView real em onCreate() com findViewById(). No entanto, isso complicará seu código, porque agora você precisa verificar o valor null sempre que quiser usar diceImage. Há uma alternativa melhor.

  1. Mude a declaração diceImage para usar a palavra-chave lateinit e remova a atribuição null:
lateinit var diceImage : ImageView

A palavra-chave lateinit promete ao compilador Kotlin que a variável será inicializada antes que o código chame qualquer operação nela. Portanto, não é necessário inicializar a variável aqui null e podemos tratá-la como uma variável não anulável quando a usarmos. É uma prática recomendada usar lateinit com campos que contenham visualizações desse modo.

  1. No onCreate(), após o método setContentView(), use findViewById() para conseguir o ImageView.
diceImage = findViewById(R.id.dice_image)
  1. Exclua a linha antiga no rollDice() que declara e recebe o ImageView. Você substituiu esta linha pela declaração do campo.
val diceImage : ImageView = findViewById(R.id.dice_image)
  1. Execute o app novamente para ver se ele ainda funciona conforme o esperado.

No momento, você está usando a dice_1 como a imagem inicial do dado. Digamos que você não queira exibir nenhuma imagem até que o dado seja jogado pela primeira vez. Existem algumas maneiras de fazer isso.

  1. Abra activity_layout.xml na guia Text.
  2. No elemento <ImageView>, defina o atributo android:src como "@drawable/empty_dice":
android:src="@drawable/empty_dice" 

A imagem empty_dice era uma das que você baixou e adicionou à pasta drawable. Ele tem o mesmo tamanho das outras imagens de dados, somente ele está vazio. Essa imagem é a que será exibida quando o app for iniciado pela primeira vez.

  1. Clique na guia Design. A imagem mordida está vazia agora, mas também não está visível na visualização.



    É bem comum que o conteúdo de um design seja definido dinamicamente no tempo de execução. Por exemplo, qualquer app que extrai dados da Internet provavelmente precisa começar com uma tela vazia ou vazia. Mas é útil criar um app para ter algum tipo de dado marcador no layout para que você saiba o que quer incluir.
  2. No activity_layout.xml, copie a linha android:src e cole uma segunda cópia. Mude a palavra "android" para "tools" de modo que os dois atributos fiquem assim:
android:src="@drawable/empty_dice" 
tools:src="@drawable/empty_dice" />

Aqui você alterou o namespace XML desse atributo do namespace android padrão para o namespace tools. O namespace tools é usado quando você quer definir o conteúdo do marcador que é usado apenas na visualização ou no editor de design do Android Studio. Os atributos que usam o namespace tools são removidos ao compilar o app.

Os namespaces são usados para resolver ambiguidade ao se referir a atributos com o mesmo nome. Por exemplo, os dois atributos na tag <ImageView> têm o mesmo nome (src), mas o namespace é diferente.

  1. Analise o elemento <LinearLayout> na raiz do arquivo de layout e observe os dois namespaces definidos aqui.
<LinearLayout
   xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:tools="http://schemas.android.com/tools"
   ...
  1. Mude o atributo tools:src na tag ImageView para dice_1 em vez de empty_dice:
android:src="@drawable/empty_dice" 
tools:src="@drawable/dice_1" />

Observe que a imagem dice_1 está no lugar como a imagem de marcador na visualização.

  1. Compile e execute o app. A imagem ficará vazia no app até você clicar ou tocar em Jogar.

Uma das melhores coisas de desenvolver para Android é o grande número de dispositivos em que seu código pode ser executado, desde o Nexus One até o Pixel, para formar fatores como tablets, Pixelbooks, Pixelbooks, relógios, TVs e carros.

No Android, não é possível criar apps totalmente separados para cada um desses dispositivos, mesmo os que são executados em formatos muito diferentes, como relógios e TVs, podem compartilhar códigos. No entanto, ainda há restrições e estratégias de compatibilidade que você precisa conhecer para oferecer compatibilidade com tudo isso.

Nesta tarefa, você aprenderá a direcionar seu app a níveis específicos da API Android (versões) e a usar as bibliotecas do Android Jetpack para oferecer compatibilidade com dispositivos mais antigos.

Etapa 1: descobrir os níveis de API

No codelab anterior, quando você criou seu projeto, você indicou o nível específico da API Android a que o app precisa ser compatível. O sistema operacional Android tem diferentes números de versão que recebem o nome de deliciosos nomes de ordem alfabética. Cada versão do SO recebe novos recursos e funcionalidades. Por exemplo, o Android Oreo é compatível com apps picture-in-picture, enquanto o Android Pie introduziu Slices. Os níveis da API correspondem às versões do Android. Por exemplo, a API 19 corresponde ao Android 4.4 (KitKat).

Devido a uma série de fatores, como suporte ao hardware, possibilidade de atualizar os dispositivos e compatibilidade entre fabricantes com diferentes níveis de SO, eles inevitavelmente acabam com dispositivos que executam diferentes versões do SO.

Ao criar um projeto de app, você especifica o nível mínimo da API compatível com o app. Ou seja, você especifica a versão mais antiga do Android compatível com o app. O app também tem um nível para o qual é compilado e um nível a que se destina. Cada um desses níveis é um parâmetro de configuração nos arquivos de compilação do Gradle.

  1. Expanda a pasta Gradle Scripts e abra o arquivo build.gradle (Module: app).

    Este arquivo define parâmetros de compilação e dependências específicos do módulo do app. O arquivo build.gradle (Project: DiceRoller) define os parâmetros de compilação do projeto como um todo. Em muitos casos, o módulo do app é o único no projeto. Portanto, essa divisão pode parecer arbitrária. No entanto, se o app se tornar mais complexo e você dividir em várias partes ou se ele for compatível com plataformas como o Android Watch, você poderá encontrar módulos diferentes no mesmo projeto.
  2. Analise a seção android na parte superior do arquivo build.gradle. O exemplo abaixo não é toda a seção, mas contém os tópicos de seu interesse para este codelab.
android {
   compileSdkVersion 28
   defaultConfig {
       applicationId "com.example.android.diceroller"
       minSdkVersion 19
       targetSdkVersion 28
       versionCode 1
       versionName "1.0"
   }
  1. Analise o parâmetro compileSdkVersion.
compileSdkVersion 28

Este parâmetro especifica o nível da API do Android que o Gradle precisa usar para compilar o app. Essa é a versão mais recente do Android compatível com o app. Ou seja, seu app pode usar os recursos da API incluídos nesse nível da API e em níveis inferiores. Nesse caso, seu app é compatível com a API 28, que corresponde ao Android 9 (Pie).

  1. Analise o parâmetro targetSdkVersion, que está dentro da seção defaultConfig:
targetSdkVersion 28

Esse valor é a API mais recente em que você testou o app. Em muitos casos, esse valor é igual a compileSdkVersion.

  1. Analise o parâmetro minSdkVersion.
minSdkVersion 19

Esse parâmetro é o mais importante dos três, porque determina a versão mais antiga do Android em que o app será executado. Dispositivos com o SO Android mais antigo que esse nível de API não conseguem executar o app.

Pode ser difícil escolher o nível mínimo de API para o app. Defina o nível da API de modo muito baixo e perca os recursos mais recentes do SO Android. Defina-a como muito alta, e seu app poderá ser executado somente em dispositivos mais recentes.

Ao configurar o projeto e chegar ao local em que você define o nível mínimo de API do app, clique em Help me choose para ver a caixa de diálogo API Version Distribution. A caixa de diálogo mostra informações sobre quantos dispositivos usam níveis diferentes do SO e recursos que foram adicionados ou alterados. Você também pode consultar o painel e as notas da versão da documentação do Android, que trazem mais informações sobre as implicações de oferecer compatibilidade com diferentes níveis de API.

Etapa 2: descobrir a compatibilidade

Desenvolver conteúdo para diferentes níveis da API do Android é um desafio comum para os desenvolvedores de apps. Por isso, a equipe do framework do Android trabalhou muito para ajudar você.

Em 2011, a equipe lançou a primeira Biblioteca de Suporte, uma biblioteca desenvolvida pelo Google que oferece classes compatíveis e funções úteis. Em 2018, o Google anunciou o Android Jetpack, uma coleção de bibliotecas que inclui várias das classes e funções anteriores da Biblioteca de Suporte, além de expandir essa biblioteca.

  1. Abra o MainActivity
  2. A classe MainActivity se estende não da Activity, mas da AppCompatActivity.
class MainActivity : AppCompatActivity() { 
...

AppCompatActivity é uma classe de compatibilidade que garante que sua atividade tenha a mesma aparência em diferentes níveis do SO da plataforma.

  1. Clique no símbolo + ao lado da linha que começa com import para expandir as importações da classe. A classe AppCompatActivity é importada do pacote androidx.appcompat.app. O namespace das bibliotecas do Android Jetpack é androidx.
  2. Abra build.gradle (Module: app) e role para baixo até a seção de dependências.
dependencies {
   implementation fileTree(dir: 'libs', include: ['*.jar'])
   implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
   implementation 'androidx.appcompat:appcompat:1.0.0-beta01'
   implementation 'androidx.core:core-ktx:1.0.1'
   implementation 'androidx.constraintlayout:constraintlayout:1.1.2'
   testImplementation 'junit:junit:4.12'
   androidTestImplementation 'androidx.test:runner:1.1.0-alpha4'
   androidTestImplementation 
        'androidx.test.espresso:espresso-core:3.1.0-alpha4'
}

Observe a dependência da biblioteca appcompat, que faz parte da androidx e contém a classe AppCompatActivity.

Etapa 3: adicionar compatibilidade com drawables vetoriais

Você usará seu novo conhecimento sobre namespaces, Gradle e compatibilidade para fazer um último ajuste no app, que otimizará o tamanho dele em plataformas mais antigas.

  1. Expanda a pasta res e depois drawable. Clique duas vezes em uma das imagens de dados.

    Como você aprendeu anteriormente, todas as imagens de dados são arquivos XML que definem as cores e as formas do dado. Esses tipos de arquivo são chamados de drawables vetoriais. A vantagem dos drawables vetoriais em relação aos formatos de imagem de bitmap, como o PNG, é que os drawables vetoriais podem ser dimensionados sem perder a qualidade. Além disso, um drawable vetorial geralmente é um arquivo muito menor que a mesma imagem em um formato bitmap.

    É importante observar que os drawables vetoriais são importantes para a API 21 em diante. No entanto, o SDK mínimo do app está definido como a API 19. Se você tentou usar seu app em um dispositivo ou emulador de API 19, verá que o app parece ser criado e executado normalmente. Como isso funciona?

    Quando você cria o app, o processo de compilação do Gradle gera um arquivo PNG para cada um dos arquivos vetoriais, e esses arquivos PNG são usados em qualquer dispositivo Android anterior a 21. Esses arquivos PNG extras aumentam o tamanho do seu app. Apps desnecessariamente grandes não são excelentes. Eles tornam os downloads mais lentos para os usuários e ocupam mais espaço nos dispositivos. Os apps grandes também têm mais chances de serem desinstalados, e os usuários não conseguem fazer o download deles nem cancelam esses downloads.

    A boa notícia é que há uma biblioteca de compatibilidade do Android X para drawables vetoriais desde o nível 7.
  2. Abra build.gradle (Module: app). Adicione esta linha à seção defaultConfig:
vectorDrawables.useSupportLibrary = true
  1. Clique no botão Sync Now. Sempre que um arquivo build.gradle é modificado, você precisa sincronizar os arquivos de compilação com o projeto.
  2. Abra o arquivo de layout main_activity.xml. Adicione esse namespace à tag raiz <LinearLayout>, abaixo do namespace tools:
xmlns:app="http://schemas.android.com/apk/res-auto"

O namespace app é destinado a atributos vindos do seu código personalizado ou de bibliotecas, não do framework principal do Android.

  1. Mude o atributo android:src no elemento <ImageView> para app:srcCompat.
app:srcCompat="@drawable/empty_dice"


O atributo app:srcCompat usa a biblioteca Android X para oferecer compatibilidade com drawables vetoriais em versões mais antigas do Android, de nível de API 7.

  1. Crie e execute seu app. Você não verá nada diferente na tela, mas agora não precisará usar arquivos PNG gerados para as imagens de dados, onde quer que sejam executados, o que significa um arquivo de app menor.

Projeto do Android Studio: DiceRollerFinal

Desafio:modifique o app DiceRoller para ter dois dados. Quando o usuário toca no botão Jogar, cada dado deve ter um valor independente do outro.

Dica: crie uma nova função particular para receber uma imagem desenhável aleatória e retornar um número inteiro para o recurso drawable. Use essa função para cada uma das imagens de dados.

private fun getRandomDiceImage() : Int { ... }

Código da solução do desafio de programação

Projeto do Android Studio: DiceRollerFinal-challenge

Recursos do app:

  • Os recursos do app podem incluir imagens e ícones, cores padrão usadas no app, strings e layouts XML. Todos esses recursos são armazenados na pasta res.
  • Coloque todos os recursos de imagem que serão usados no seu app na pasta de recursos drawable.

Como usar drawables vetoriais em visualizações de imagem:

  • Drawables vetoriais são imagens descritas em formato XML. Os drawables vetoriais são mais flexíveis que as imagens em bitmap (como arquivos PNG), porque podem ser dimensionados para qualquer tamanho ou resolução.
  • Para adicionar um drawable ao layout do app, use um elemento <ImageView>. A origem da imagem está no atributo android:src. Para se referir à pasta de recursos drawable, use @drawable, por exemplo, "@drawable/image_name".
  • Use a visualização ImageView no código MainActivity da imagem. Você pode usar setImageResource() para alterar a imagem da visualização para um recurso diferente. Use R.drawable para se referir a drawables específicos, por exemplo, setImageResource(R.drawable.image_name).

A palavra-chave lateinit:

  • Minimize as chamadas para findViewById() no código declarando campos para manter essas visualizações e inicializando os campos em onCreate(). Use a palavra-chave lateinit para o campo para evitar a necessidade de declará-lo anulável.

O namespace tools para atributos de tempo de design:

  • Use o atributo tools:src no elemento <ImageView> do seu layout para exibir uma imagem apenas no editor ou no design do Android Studio. Em seguida, você pode usar uma imagem vazia para o android:src no app final.
  • Use o namespace tools no arquivo de layout do Android para criar conteúdo de marcadores ou dicas para layout no Android Studio. Os dados declarados por atributos tools não são usados no app final.

Níveis de API:

  • Cada sistema operacional Android tem um número e nome de versão oficial (por exemplo, Android 9.0, "Pie") e um nível de API (API 28). Use os níveis da API nos arquivos do Gradle do seu app para indicar as versões do Android compatíveis com seu app.
  • O parâmetro compileSdkVersion no arquivo build.gradle especifica o nível da API do Android que o Gradle precisa usar para compilar o app.
  • O parâmetro targetSdkVersion especifica o nível de API mais recente em que você testou o app. Em muitos casos, este parâmetro tem o mesmo valor de compileSdkVersion.
  • O parâmetro minSdkVersion especifica o nível de API mais antigo em que o app poderá ser executado.

Android Jetpack:

  • O Android Jetpack é uma coleção de bibliotecas desenvolvidas pelo Google que oferece classes compatíveis com versões anteriores e funções úteis para oferecer compatibilidade com versões anteriores do Android. O Jetpack substitui e expande o conjunto de bibliotecas anteriormente conhecidas como Biblioteca de Suporte do Android.
  • As classes importadas do pacote androidx se referem às bibliotecas do Jetpack. As dependências do Jetpack no arquivo build.gradle também começam com androidx.

Compatibilidade com versões anteriores de drawables vetoriais:

  • Drawables vetoriais só são nativamente compatíveis com versões do Android anteriores à API 21. Em versões mais antigas, o Gradle gera imagens PNG para esses drawables quando o app é criado.
  • Você pode especificar que a Biblioteca de Suporte do Android seja usada para drawables vetoriais em versões mais antigas da API com o parâmetro de configuração vectorDrawables.useSupportLibrary = true no arquivo build.gradle.
  • Depois de ativar a Biblioteca de Suporte para drawables vetoriais, use o atributo app:srcCompat no elemento <ImageView> (em vez de android:src) para especificar a origem do drawable vetorial para essa imagem.

O namespace app:

  • O namespace app no arquivo de layout XML é destinado a atributos que vêm do código personalizado ou de bibliotecas, não do framework principal do Android.

Curso da Udacity:

Documentação do desenvolvedor Android:

Outro:

Esta seção lista as possíveis atividades para os alunos que estão trabalhando neste codelab como parte de um curso ministrado por um instrutor. Cabe ao instrutor fazer o seguinte:

  • Se necessário, atribua o dever de casa.
  • Informe aos alunos como enviar o dever de casa.
  • Atribua nota aos trabalhos de casa.

Os professores podem usar essas sugestões o quanto quiserem, e eles devem se sentir à vontade para passar o dever de casa como achar adequado.

Se você estiver fazendo este codelab por conta própria, use essas atividades para testar seu conhecimento.

Mudar um app

Adicione um botão Clear ao app DiceRoller que defina a imagem de dados novamente para a imagem vazia.

Responda a estas perguntas

Pergunta 1

Qual atributo <ImageView> indica uma imagem de origem que será usada apenas no Android Studio?

  • android:srcCompat
  • app:src
  • tools:src
  • tools:sourceImage

Pergunta 2

Qual método altera o recurso de imagem de um ImageView no código Kotlin? xmx

  • setImageResource()
  • setImageURI()
  • setImage()
  • setImageRes()

Pergunta 3

O que a palavra-chave lateinit em uma declaração de variável indica no código Kotlin?

  • A variável nunca é inicializada.
  • A variável só é inicializada durante a execução do app.
  • A variável é inicializada automaticamente em null.
  • A variável será inicializada mais tarde. Eu prometo!

Pergunta 4

Qual configuração do Gradle indica com que nível da API mais recente o app foi testado?

  • minSdkVersion
  • compileSdkVersion
  • targetSdkVersion
  • testSdkVersion

Pergunta 5

Você verá uma linha de importação no código que começa com androidx. O que isso significa?

  • A classe faz parte das bibliotecas do Android Jetpack.
  • A classe está em uma biblioteca externa que será carregada dinamicamente quando o app for executado.
  • A classe é "extra" e opcional para sua classe.
  • A classe faz parte da compatibilidade do Android com XML.

Enviar o app para avaliação

Verifique se o app tem o seguinte:

  • O layout do app precisa incluir uma visualização de imagem e dois botões.
  • O código do aplicativo precisa definir dois gerenciadores de cliques, um para cada botão.
  • O gerenciador de cliques do botão Limpar deve definir a imagem do dado como R.drawable.empty_dice.

Comece a próxima lição: 1.4: Aprenda a se ajudar

Para ver links de outros codelabs neste curso, consulte a página de destino dos codelabs do curso Conceitos básicos do Kotlin para Android.