Kotlin Conceitos básicos do Android 10.3: design para todos

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

Para tornar um app utilizável para a maioria dos usuários, independentemente de você estar desenvolvendo-o para o prazer ou para fins comerciais, Existem várias dimensões para fazer isso.

  • Compatibilidade com idiomas RTL. A Europa e muitos outros idiomas são lidos da esquerda para a direita, e os apps originários dessas localidades costumam ser projetados para caber nesses idiomas. Muitos outros idiomas têm um grande número de falantes lidos da direita para a esquerda, como o árabe. Fazer com que o app funcione com idiomas da direita para a esquerda (RTL) para aumentar o público-alvo em potencial
  • Verifique a acessibilidade. Adivinhar como outra pessoa pode experimentar seu app é uma opção com armadilhas. O app Scanner de acessibilidade elimina a imprevisibilidade da análise e identifica seu app, identificando onde você poderia melhorar a acessibilidade.
  • Crie designs para o TalkBack com descrições de conteúdo. As deficiências visuais são mais comuns do que se imagina, e muitos usuários, não apenas os cegos, usam um leitor de tela. Descrições de conteúdo são frases para um leitor de tela dizer quando um usuário interage com um elemento da tela.
  • Ofereça suporte ao modo noturno. Para muitos usuários com deficiência visual, alterar as cores da tela melhora o contraste e os ajuda a trabalhar visualmente com seu app. O Android facilita o suporte ao modo noturno, e você deve sempre oferecer suporte ao modo noturno para oferecer aos usuários uma alternativa simples às cores da tela padrão.

Neste codelab, você explorará cada uma dessas opções e adicionará compatibilidade com o app GDG Finder.

Você também aprenderá a usar os chips com seu app Android. Você pode usar chips para tornar seu app mais interessante, mantendo-o acessível.

O que você já precisa saber

Você precisa:

  • Como criar apps que têm atividades e fragmentos e navegar entre fragmentos que transmitem dados.
  • Uso de visualizações e grupos de visualizações para definir a interface do usuário, principalmente o RecyclerView.
  • Como usar os Componentes de arquitetura, incluindo o ViewModel, com a arquitetura recomendada para criar um app estruturado e eficiente.
  • Vinculação de dados, corrotinas e como processar cliques do mouse.
  • Como se conectar à Internet e armazenar dados em cache localmente usando um banco de dados do Room.
  • Como definir as propriedades de visualização e como extrair e usar recursos de arquivos de recurso XML.
  • Como usar estilos e temas para personalizar a aparência do seu app.
  • Como usar componentes do Material Design, recursos de dimensão e coloração personalizada.

O que você vai aprender

  • Como permitir que o app seja usado pelo maior número de usuários.
  • Como fazer o app funcionar para idiomas da direita para a esquerda (RTL).
  • Como avaliar a acessibilidade do seu app.
  • Como usar descrições de conteúdo para que seu app funcione melhor com leitores de tela.
  • Como usar chips.
  • Como fazer o app funcionar com o modo escuro.

Atividades do laboratório

  • Avalie e estenda um determinado app para melhorar a acessibilidade fazendo com que ele funcione para idiomas RTL.
  • Verifique seu app para determinar onde a acessibilidade pode ser melhorada.
  • Use descrições de conteúdo para imagens.
  • Aprenda a usar drawables.
  • Adicionar o recurso de usar o modo noturno ao app.

O app inicial do GDG-finder se baseia em tudo o que você aprendeu até agora neste curso.

O app usa ConstraintLayout para dispor três telas. Duas das telas são apenas arquivos de layout que serão usados para explorar cores e textos no Android.

A terceira tela é um localizador de GDGs. Os GDGs (Grupos de desenvolvedores do Google) são comunidades de desenvolvedores focadas em tecnologias do Google, incluindo o Android. Os GDGs no mundo todo realizam encontros, conferências, grupos de estudo e outros eventos.

Ao desenvolver este app, você trabalha na lista real de GDGs. A tela do localizador usa a localização do dispositivo para classificar os GDGs por distância.

Se você estiver com sorte e houver um GDG na sua região, consulte o site e inscreva-se nos eventos deles. Os eventos GDG são uma ótima forma de conhecer outros desenvolvedores Android e conhecer as práticas recomendadas do setor que não se encaixaram neste curso.

As capturas de tela abaixo mostram as mudanças do app desde o início até o fim deste codelab.

A principal diferença entre os idiomas escritos da esquerda para a direita (LTR) e da direita para a esquerda (RTL) é a direção do conteúdo exibido. Quando a direção da IU é alterada de LTR para RTL (ou vice-versa), ela geralmente é chamada de espelhamento. O espelhamento afeta a maior parte da tela, incluindo o texto, ícones de campo de texto, layouts e ícones com rotas, como setas. Outros itens não são espelhados, como números (relógio, números de telefone), ícones que não têm direção (modo avião, Wi-Fi), controles de reprodução e a maioria dos gráficos.

Os idiomas com a direção de texto RTL são usados por mais de um bilhão de pessoas no mundo todo. Os desenvolvedores Android estão no mundo todo, então os apps GDG Finder precisam ser compatíveis com idiomas RTL.

Etapa 1: adicionar compatibilidade com RTL

Nesta etapa, você fará o app GDG Finder funcionar com idiomas RTL.

  1. Faça o download e execute o app GDGFinderMaterial, que é o app inicial para este codelab, ou continue a partir do código final do codelab anterior.
  2. Abra o manifesto do Android.
  3. Na seção <application>, adicione o seguinte código para especificar que o app é compatível com RTL.
<application
        ...
        android:supportsRtl="true">
  1. Abra activity_main.xml na guia Design.
  2. No menu suspenso Locale para visualização, escolha Visualizar da direita para a esquerda. Se você não encontrar esse menu, amplie o painel ou feche o painel Atributos para vê-lo.

  1. Em Visualização, observe que o cabeçalho "GDG Finder" foi movido para a direita e o restante da tela permanece praticamente o mesmo. Em geral, essa tela é passível. Mas o alinhamento na visualização de texto agora está errado, porque ele está alinhado à esquerda, não à direita.

  1. Para que esse recurso funcione no seu dispositivo ou emulador Configurações, em Opções do desenvolvedor, selecione Forçar layout RTL. Se você precisar ativar as Opções do desenvolvedor, localize o Número da versão e clique nele até receber um aviso indicando que você é um desenvolvedor. Isso varia de acordo com o dispositivo e a versão do sistema Android.

  1. Execute o app e verifique se a tela principal aparece da mesma forma que a Visualização no dispositivo. O FAB agora está alternado à esquerda, e o menu hambúrguer à direita.
  2. No app, abra a gaveta de navegação e acesse a tela Pesquisa. Como mostrado abaixo, os ícones ainda estão à esquerda, e nenhum texto está visível. O texto fica fora da tela, à esquerda do ícone. Isso ocorre porque o código usa referências de tela esquerda/direita nas propriedades de visualização e restrições de layout.

Etapa 2: use o início e o fim em vez de usar a esquerda e a direita

"Esquerda" e "direita" na tela (quando você está olhando para a tela) não mudam, mesmo que a direção do texto mude. Por exemplo, layout_constraintLeft_toLeftOf sempre restringe o lado esquerdo do elemento ao lado esquerdo da tela. No caso do app, o texto está fora da tela em idiomas RTL, conforme mostrado na captura de tela acima.

Para corrigir o problema, em vez de "quot;left" e "quot", use a terminologia de Start e End. Essa terminologia define o início e o fim do texto corretamente na direção do texto no idioma atual, de forma que as margens e os layouts estejam nas áreas corretas das telas.

  1. Open list_item.xml (link em inglês).
  2. Substitua todas as referências a Left e Right por referências a Start e End.
app:layout_constraintStart_toStartOf="parent"

app:layout_constraintStart_toEndOf="@+id/gdg_image"
app:layout_constraintEnd_toEndOf="parent"
  1. Substitua o layout_marginLeft da ImageView por layout_marginStart. Isso move a margem para o local correto para afastar o ícone da borda da tela.
<ImageView
android:layout_marginStart="
?
  1. Abra o fragment_gdg_list.xml Verifique a lista de GDGs no painel Visualização. O ícone ainda está apontando para a direção errada porque está espelhado. Se o ícone não estiver espelhado, mantenha a visualização da direita para a esquerda. De acordo com as diretrizes do Material Design, os ícones não podem ser espelhados.
  2. Abra res/drawable/ic_gdg.xml.
  3. Na primeira linha do código XML, localize e exclua android:autoMirrored="true" para desativar o espelhamento.
  4. Verifique a Visualização ou execute o app novamente e abra a tela "Pesquisar GDG". O layout será corrigido agora.

Etapa 3: deixar o Android Studio fazer o trabalho por você

No exercício anterior, você deu os primeiros passos para oferecer compatibilidade com os idiomas RTL. A boa notícia é que o Android Studio pode analisar seu app e configurar várias configurações básicas para você.

  1. Em list_item.xml, em TextView, mude layout_marginStart de volta para layout_marginLeft. Assim, o scanner terá algo para encontrar.
<TextView
android:layout_marginLeft="@dimen/spacing_normal"
  1. No Android Studio, escolha Refactor > Add RTL support where possible e marque as caixas para atualizar o manifesto e os arquivos de layout para usar as propriedades inicial e final.

  1. No painel Refactoring Preview, localize a pasta app e expanda até que ela esteja aberta para todos os detalhes.
  2. Na pasta do app, observe que o layout_marginLeft que você acabou de alterar aparece como listado para refatorar.

  1. Observe que a visualização também lista os arquivos do sistema e da biblioteca. Clique com o botão direito do mouse em layout e em layout-watch-v20 e em outras pastas que não fazem parte do app. Em seguida, escolha Exclude no menu de contexto.

  1. Faça a refatoração agora. Se você receber um pop-up sobre arquivos do sistema, verifique se excluiu todas as pastas que não fazem parte do código do app.
  1. layout_marginLeft foi alterado novamente para layout_marginStart.

Etapa 3: explorar pastas para localidades

Até agora, você alterou a direção do idioma padrão usado do app. Para um app de produção, você enviaria o arquivo strings.xml para um tradutor para que ele fosse traduzido para um novo idioma. Para este codelab, o app fornece um arquivo strings.xml em espanhol. Usamos o Google Tradutor para gerar as traduções, o que as torna incompletas.

  1. No Android Studio, mude a visualização do projeto para Project Files.
  2. Expanda a pasta res e observe as pastas res/values e res/values-es. O ""es" no nome da pasta é o código do idioma para espanhol. As pastas values-"código do idioma" contêm valores para cada idioma compatível. A pasta values sem uma extensão contém os recursos padrão que se aplicam de outra forma.

  1. Em values-es, abra strings.xml e observe que todas as strings estão em espanhol.
  2. No Android Studio, abra o activity_main.xml na guia Design.
  3. Na lista suspensa Locale de visualização, escolha Espanhol. Agora seu texto estará em espanhol.

  1. [Opcional] Se você tem proficiência em um idioma RTL, crie uma pasta values e um strings.xml nesse idioma e teste a forma como ela aparece no dispositivo.
  2. [Opcional] Mude as configurações de idioma no seu dispositivo e execute o app. Evite mudar o dispositivo para um que você não leia, porque isso pode ser um pouco desafiador.

Na tarefa anterior, você alterou o app manualmente e depois usou o Android Studio para fazer outras melhorias no RTL.

O app Scanner de acessibilidade é seu melhor aliado para tornar seu app acessível. Ele verifica o app no dispositivo de destino e sugere melhorias, como aumentar a área de toque, aumentar o contraste e fornecer descrições de imagens para tornar o app mais acessível. O Scanner de acessibilidade é fabricado pelo Google, e você pode instalá-lo pela Play Store.

Etapa 1: instalar e executar o Accessibility Scanner

  1. Abra a Play Store e faça login, se necessário. Você pode fazer isso no dispositivo físico ou no emulador. Este codelab usa o emulador.
  1. Na Play Store, pesquise Scanner de acessibilidade da Google LLC. Faça o download do app correto, emitido pelo Google, porque qualquer verificação requer muitas permissões.

  1. Instale o scanner no emulador.
  2. Após a instalação, clique em Abrir.
  3. Clique em Primeiros passos.
  4. Clique em OK para iniciar a configuração do Scanner de acessibilidade nas configurações.

  1. Clique no Scanner de acessibilidade para acessar as configurações de Acessibilidade do dispositivo.

  1. Clique em Usar serviço para ativá-lo.

  1. Siga as instruções exibidas na tela e conceda todas as permissões.
  2. Em seguida, clique em OK e volte para a tela inicial. Talvez você veja um botão azul com uma marca de seleção na tela. Clicar nesse botão aciona o teste do app em primeiro plano. Você pode reposicionar o botão arrastando-o. Esse botão fica acima de todos os apps para que você possa acionar testes a qualquer momento.

  1. Abra ou execute o app.
  2. Clique no botão azul e aceite outros avisos e permissões de segurança.

Na primeira vez que você clicar no ícone do Scanner de acessibilidade, o app pedirá permissão para exibir tudo na tela. Parece uma permissão muito assustadora.

Você quase nunca deve conceder uma permissão como essa, porque ela permite que os apps leiam seu e-mail ou até mesmo vejam informações da sua conta bancária. No entanto, para que o Scanner de acessibilidade faça o trabalho, ele precisa examinar o app da mesma forma que um usuário faria, e é por isso que ele precisa dessa permissão.

  1. Clique no botão azul e aguarde a conclusão da análise. Você verá algo como a captura de tela abaixo, com o título e o FAB em vermelho. Isso indica duas sugestões de melhoria de acessibilidade nessa tela.

  1. Clique na caixa ao redor do GDG Finder. Isso abre um painel com informações adicionais, como mostrado abaixo, indicando problemas com o contraste da imagem.
  2. Expanda as informações em Contraste da imagem para que a ferramenta sugira soluções.
  3. Clique nas setas à direita para acessar as informações do próximo item.

  1. No app, navegue até a tela Inscrever-se no GDG e faça a digitalização com o aplicativo Scanner de acessibilidade. Isso fornece algumas sugestões, conforme mostrado abaixo. 12, para ser exato. Para ser justo, alguns deles são duplicados para itens semelhantes.
  2. Clique no ícone "stack" na barra de ferramentas inferior para ver uma lista de todas as sugestões, conforme mostrado na captura de tela à direita. Todos esses problemas são abordados neste codelab.

O Pacote de Acessibilidade do Android, um conjunto de apps do Google, inclui ferramentas para ajudar você a tornar os apps mais acessíveis. Ele inclui ferramentas como o TalkBack. O TalkBack é um leitor de tela que oferece feedback auditivo, tátil e de fala, permitindo que os usuários naveguem e consumam conteúdo nos dispositivos sem usar os olhos.

O TalkBack não é só usado por cegos, mas também por muitas pessoas com deficiência visual. Ou até mesmo quem quer descansar os olhos!

A acessibilidade é para todos! Nesta tarefa, você testará o TalkBack e atualizará o app para que funcione bem.

Etapa 1: instalar e executar o Acessibilidade

O TalkBack vem pré-instalado em vários dispositivos físicos, mas, em um emulador, você precisa instalá-lo.

  1. Abra a Play Store.
  2. Encontre o Pacote de acessibilidade. Confira se ele é o app correto do Google.
  3. Se ele não estiver instalado, instale o Acessibilidade.
  4. Para ativar o TalkBack no dispositivo, acesse Configurações > Acessibilidade e ative-o selecionando Usar serviço. Assim como o leitor de acessibilidade, o TalkBack precisa de permissões para ler o conteúdo na tela. Depois de aceitar as solicitações de permissão, o TalkBack exibirá uma lista de tutoriais para ensinar como usar o recurso com eficiência.
  5. Pare aqui e faça os tutoriais para aprender a desativar o TalkBack quando terminar.
  6. Para sair do tutorial, clique no botão "Voltar" para selecioná-lo e toque duas vezes em qualquer lugar da tela.
  1. Explore usando o aplicativo GDG Finder com TalkBack. Observe os lugares onde o TalkBack não apresenta informações úteis sobre a tela ou um controle. Isso será corrigido no próximo exercício.

Etapa 2: adicionar uma descrição de conteúdo

Os descritores de conteúdo são rótulos descritivos que explicam o significado das visualizações. A maioria das suas visualizações precisa ter descrições de conteúdo.

  1. Com o app GDG Finder em execução e o Talback ativado, navegue até a tela Apply to run GDG.
  2. Na imagem principal, nada acontece.
  3. Abra add_gdg_fragment.xml.
  4. No ImageView, adicione um atributo de descritor de conteúdo, conforme mostrado abaixo. A string stage_image_description é fornecida em strings.xml.
android:contentDescription="@string/stage_image_description"
  1. Execute o app.
  2. Navegue até Aplicar para executar o GDG e clique na imagem. Agora você ouvirá uma breve descrição da imagem.
  3. [Opcional] Adicione descrições de conteúdo para as outras imagens neste app. Em um app de produção, todas as imagens precisam ter descrições de conteúdo.

Etapa 3: adicionar dicas aos campos de texto editáveis

Para elementos editáveis, como um EditText, você pode usar android:hint no XML para ajudar os usuários a descobrir o que digitar. Uma dica sempre aparece na IU, já que é o texto padrão em um campo de entrada.

  1. Ainda no add_gdg_fragment.xml.
  2. Adicione descrições e dicas de conteúdo usando o código abaixo como orientação.

Adicionar a textViewIntro:

android:contentDescription="@string/add_gdg"

Adicione textos de edição, respectivamente:

android:hint="@string/your_name_label"

android:hint="@string/email_label"

android:hint="@string/city_label"

android:hint="@string/country_label"

android:hint="@string/region_label"
  1. Adicione uma descrição de conteúdo ao labelTextWhy.
android:contentDescription="@string/motivation" 
  1. Adicione uma dica a EditTextWhy. Após marcar as caixas de edição, adicione uma descrição do conteúdo e uma dica.
android:hint="@string/enter_motivation"
  1. Adicione uma descrição do conteúdo para o botão. Todos os botões precisam ter uma descrição do que acontece se forem pressionados.
android:contentDescription="@string/submit_button_description"
  1. Execute seu app com o Talback ativado e preencha o formulário para se inscrever.

Etapa 4: criar um grupo de conteúdo

Para os controles de IU que o TalkBack deve tratar como um grupo, você pode usar o agrupamento de conteúdo. O conteúdo relacionado, que é agrupado, é anunciado em conjunto. Assim, os usuários de tecnologia adaptativa não precisarão deslizar, digitalizar ou esperar com tanta frequência para descobrir todas as informações na tela. Isso não afeta como os controles aparecem na tela.

Para agrupar componentes da IU, envolva-os em um ViewGroup, como um LinearLayout. No app GDG Finder, os elementos labelTextWhy e editTextWhy são excelentes candidatos para agrupamento, já que pertencem semanticamente.

  1. Abra add_gdg_fragment.xml.
  2. Una um LinearLayout ao redor de LabelTextWhy e EditTextWhy para criar um grupo de conteúdo. Copie e cole o código abaixo. Esse LinearLayout já contém alguns dos estilos de que você precisa. Verifique se o button está fora do LinearLayout.
<LinearLayout android:id="@+id/contentGroup" android:layout_width="match_parent"
            android:layout_height="wrap_content" android:focusable="true"
            app:layout_constraintTop_toBottomOf="@id/EditTextRegion"
            android:orientation="vertical" app:layout_constraintStart_toStartOf="@+id/EditTextRegion"
            app:layout_constraintEnd_toEndOf="@+id/EditTextRegion"
            android:layout_marginTop="16dp" app:layout_constraintBottom_toTopOf="@+id/button"
            android:layout_marginBottom="8dp">

     <!-- label and edit text here –>

<LinearLayout/>
  1. Escolha Code > Reformat code para recuar corretamente todo o código.
  2. Remova todas as margens do layout de labelTextWhy e editTextWhy.
  3. Em labelTextWhy, mude a restrição layout_constraintTop_toTopOf para contentGroup.
app:layout_constraintTop_toTopOf="@+id/contentGroup" />
  1. No editTextWhy, mude a restrição layout_constraintBottom_toBottomOf para contentGroup.
app:layout_constraintBottom_toBottomOf="@+id/contentGroup"
  1. Restrinja EditTextRegion e Button a contentGroup para eliminar os erros.
app:layout_constraintBottom_toTopOf="@+id/contentGroup"
  1. Adicione margens à LinearLayout. Se quiser, extraia essa margem como uma dimensão.
android:layout_marginStart="32dp"
android:layout_marginEnd="32dp"

Se você precisar de ajuda, compare seu código com o add_gdg_fragment.xml no código da solução.

  1. Execute seu app e explore a tela Aplicar para executar o GDG com o TalkBack.

Etapa 5: adicionar uma região ativa

No momento, o rótulo no botão de envio é OK. Seria melhor se o botão tivesse um rótulo e uma descrição antes do envio do formulário e fosse alterado dinamicamente para um rótulo e uma descrição de conteúdo diferentes depois que o usuário clicar e o formulário for enviado. É possível fazer isso usando uma região ativa.

Uma região ativa indica aos serviços de acessibilidade se o usuário precisa ser notificado quando uma visualização muda. Por exemplo, informar o usuário sobre uma senha incorreta ou um erro de rede é uma ótima maneira de tornar o app mais acessível. Neste exemplo, para simplificar, você informa o usuário quando o botão "Enviar" muda de estado.

  1. Abra add_gdg_fragment.xml.
  2. Mude a atribuição de texto do botão para Enviar usando o recurso de string submit fornecido.
android:text="@string/submit"
  1. Adicione uma região ativa ao botão definindo o atributo android:accessibilityLiveRegion. Ao digitar, você tem várias opções para o valor. Dependendo da importância da mudança, você pode interromper o usuário. Com o valor "assertive", os serviços de acessibilidade interrompem a fala em andamento para anunciar imediatamente as mudanças nessa visualização. Se você definir o valor como "none", nenhuma alteração será anunciada. Os serviços de acessibilidade são definidos como "quocientes" para que as mudanças sejam anunciadas, mas é preciso esperar. Defina o valor como "educar".

android:accessibilityLiveRegion="polite"
  1. No pacote add, abra AddGdgFragment.kt.
  2. No Observer do showSnackBarEvent, depois de terminar de mostrar o SnackBar, defina uma nova descrição de conteúdo e um novo texto para o botão.
binding.button.contentDescription=getString(R.string.submitted)
binding.button.text=getString(R.string.done)
  1. Execute o app e clique no botão. Infelizmente, o botão e a fonte são muito pequenos.

Etapa 6: corrigir o estilo do botão

  1. Em add_gdg_fragment.xml, mude os width e height do botão para wrap_content, para que o rótulo completo fique visível, e o botão fique com um tamanho bom.
android:layout_width="wrap_content"
android:layout_height="wrap_content"
  1. Exclua os atributos backgroundTint, textColor e textSize do botão para que o app use o melhor estilo de tema.
  2. Exclua o atributo textColor do textViewIntro. As cores do tema devem ter um bom contraste.
  3. Execute o app. Veja o botão Enviar, que é muito mais utilizável. Clique em Enviar e observe como ele muda para Concluído.

Os ícones são elementos compactos que representam um atributo, texto, entidade ou ação. Elas permitem que os usuários insiram informações, selecionem uma opção, filtrem o conteúdo ou iniciem uma ação.

O widget Chip é um wrapper de visualização fina em torno da ChipDrawable, que contém toda a lógica de layout e desenho. A lógica extra existe para oferecer suporte à navegação por toque, mouse, teclado e acessibilidade. O ícone principal e o ícone "Fechar" são considerados subvisualizações lógicas separadas e contêm o próprio comportamento e estado de navegação.

Os ícones usam drawables. Os drawables do Android permitem que você desenhe imagens, formas e animações na tela, e podem ter um tamanho fixo ou ser dinamicamente dimensionados. Você pode usar imagens como drawables, como as imagens no app GDG, e usar desenhos vetoriais para desenhar o que você quiser. Há também um drawable redimensionável chamado drawable de 9 patches, que não é abordado neste codelab. O logotipo do GDG, em drawable/ic_gdg.xml, é outro drawable.

Drawables não são visualizações. Portanto, não é possível colocá-lo diretamente em uma ConstraintLayout, é preciso colocá-lo em uma ImageView. Também é possível usar drawables para fornecer um plano de fundo para uma visualização de texto ou um botão, e o plano de fundo é desenhado atrás do texto.

Etapa 1: adicionar ícones à lista de GDGs

O ícone marcado abaixo usa três drawables. O plano de fundo e a marca de seleção são drawables. Tocar no ícone cria um efeito de ondulação, que é feito com um RippleDrawable especial que mostra um efeito de ondulação em resposta a mudanças de estado.

Nesta tarefa, você adicionará ícones à lista de GDGs e fará com que eles mudem o estado quando forem selecionados. Neste exercício, você adicionará uma linha de botões chamada chips à parte superior da tela Search. Cada botão filtra a lista de GDG para que o usuário receba apenas resultados da região selecionada. Quando um botão é selecionado, ele muda o plano de fundo e exibe uma marca de seleção.

  1. Abra fragment_gdg_list.xml.
  2. Crie um com.google.android.material.chip.ChipGroup dentro da HorizontalScrollView.. Defina a propriedade singleLine como true para que todos os ícones estejam alinhados em uma linha rolável horizontalmente. Defina a propriedade singleSelection como true para que apenas um ícone no grupo possa ser selecionado por vez. Veja o código:
<com.google.android.material.chip.ChipGroup
    android:id="@+id/region_list"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    app:singleSelection="true"
    android:padding="@dimen/spacing_normal"/>
  1. Na pasta layout, crie um novo arquivo de recurso de layout chamado region.xml para definir o layout de um Chip.
  2. Em region.xml, substitua todo o código pelo layout de um Chip, conforme mostrado abaixo. Observe que esse Chip é um componente do Material Design. A propriedade app:checkedIconVisible também é usada para marcar a marca de seleção. Você receberá um erro referente à cor selected_highlight ausente.
<?xml version="1.0" encoding="utf-8"?>

<com.google.android.material.chip.Chip
        xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        style="@style/Widget.MaterialComponents.Chip.Choice"
        app:chipBackgroundColor="@color/selected_highlight"
        app:checkedIconVisible="true"
        tools:checked="true"/>
  1. Para criar a cor selected_highlight ausente, coloque o cursor sobre selected_highlight, abra o menu de intents e crie um recurso de cor para o destaque selecionado. As opções padrão são adequadas, então clique em OK. O arquivo é criado na pasta res/color.
  2. Abra res/color/selected_highlight.xml. Nessa lista de estados de cores, codificada como <selector>, você pode fornecer cores diferentes para cada estado. Cada estado e cor associada são codificados como <item>. Consulte Temas de cores para mais informações sobre essas cores.
  1. Dentro da <selector>, adicione um item com uma cor padrão colorOnSurface à lista de estados. Nas listas de estados, é importante cobrir todos os estados. Uma maneira de fazer isso é usar uma cor padrão.
<item android:alpha="0.18" android:color="?attr/colorOnSurface"/>
  1. Acima da cor padrão, adicione um item com uma cor colorPrimaryVariant e restrinja o uso para quando o estado selecionado for true. As listas de estado funcionam de cima para baixo, como uma instrução de caso. Se nenhum dos estados for correspondente, o estado padrão será aplicado.
<item android:color="?attr/colorPrimaryVariant"
         android:state_selected="true" />

Etapa 2: exibir a linha de ícones

O app GDG cria uma lista de ícones mostrando regiões que têm GDGs. Quando um ícone é selecionado, o app filtra os resultados para exibir somente os resultados do GDG da região.

  1. No pacote search, abra GdgListFragment.kt.
  2. No onCreateView(), logo acima da instrução return, adicione um observador em viewModel.regionList e modifique onChanged(). Quando a lista de regiões fornecida pelo modelo de visualização muda, os ícones precisam ser recriados. Adicione uma instrução para retornar imediatamente se o data fornecido for null.
viewModel.regionList.observe(viewLifecycleOwner, object: Observer<List<String>> {
        override fun onChanged(data: List<String>?) {
             data ?: return
        }
})
  1. Dentro de onChanged(), abaixo do teste nulo, atribua binding.regionList a uma nova variável chamada chipGroup para armazenar em cache o regionList.
val chipGroup = binding.regionList
  1. Abaixo, crie um novo layoutInflator para inflar os chips do chipGroup.context.
val inflator = LayoutInflater.from(chipGroup.context)
  1. Limpe e recrie seu projeto para eliminar o erro de vinculação de dados.

Abaixo do inflador, é possível criar os ícones, um para cada região do regionList.

  1. Crie uma variável, children, para armazenar todos os ícones. Atribua a ele uma função de mapeamento no transmitida em data para criar e retornar cada ícone.
val children = data.map {} 
  1. Dentro do lambda do mapa, crie e infle um ícone para cada regionName. Veja a seguir o código completo.
val children = data.map {
   val children = data.map { regionName ->
       val chip = inflator.inflate(R.layout.region, chipGroup, false) as Chip
       chip.text = regionName
       chip.tag = regionName
       // TODO: Click listener goes here.
       chip
   }
}
  1. No lambda, antes de retornar o chip, adicione um listener de clique. Quando o chip for clicado, defina o estado dele como checked. Chame onFilterChanged() no viewModel, que aciona uma sequência de eventos que busca o resultado desse filtro.
chip.setOnCheckedChangeListener { button, isChecked ->
   viewModel.onFilterChanged(button.tag as String, isChecked)
}
  1. No final da linguagem, remova todas as visualizações atuais do chipGroup e adicione todos os ícones de children à chipGroup. Não é possível atualizar os ícones, então você precisa remover e recriar o conteúdo da chipGroup.
chipGroup.removeAllViews()

for (chip in children) {
   chipGroup.addView(chip)
}

O observador completo será o seguinte:

   override fun onChanged(data: List<String>?) {
       data ?: return

       val chipGroup = binding.regionList
       val inflator = LayoutInflater.from(chipGroup.context)

       val children = data.map { regionName ->
           val chip = inflator.inflate(R.layout.region, chipGroup, false) as Chip
           chip.text = regionName
           chip.tag = regionName
           chip.setOnCheckedChangeListener { button, isChecked ->
               viewModel.onFilterChanged(button.tag as String, isChecked)
           }
           chip
       }
       chipGroup.removeAllViews()

       for (chip in children) {
           chipGroup.addView(chip)
       }
   }
})
  1. Execute o app e pesquise pelo GDGS para abrir a tela Pesquisar para usar os novos ícones. Quando você clicar em cada ícone, o app exibirá os grupos de filtros abaixo dele.

O Modo noturno permite que o app mude as cores para um tema escuro, por exemplo, quando as configurações do dispositivo são definidas para ativar o modo noturno. No modo noturno, os apps mudam o plano de fundo claro padrão para ficar escuro e mudam todos os outros elementos da tela.

Etapa 1: ativar o modo noturno

Para fornecer o tema escuro do app, mude o tema do tema Light para um tema chamado DayNight. O tema DayNight aparece claro ou escuro, dependendo do modo.

  1. Em styles.xml,, mude o tema pai de AppTheme de Light para DayNight.
<style name="AppTheme" parent="Theme.MaterialComponents.DayNight.NoActionBar">
  1. No método onCreate() do MainActivity, chame AppCompatDelegate.setDefaultNightMode() para ativar o tema escuro de forma programática.
AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES)
  1. Execute o app e verifique se ele mudou para o tema escuro.

Etapa 2: gerar sua própria paleta de cores do tema escuro

Para personalizar o tema escuro, crie pastas com o qualificador -night para o tema escuro. Por exemplo, você pode ter cores específicas no Modo noturno criando uma pasta chamada values-night.

  1. Acesse a ferramenta seletora de cores do Material.io e crie uma paleta de cores para o tema noturno. Por exemplo, baseie-o em uma cor azul-escura.
  2. Gere e faça o download do arquivo colors.xml.
  3. Alterne para a visualização Project Files para listar todas as pastas do seu projeto.
  4. Encontre a pasta res e a expanda.
  5. Crie uma pasta de recursos res/values-night.
  6. Adicione o novo arquivo colors.xml à pasta de recursos res/values-night.
  7. Execute o app, ainda com o modo noturno ativado, e ele usará as novas cores definidas para res/values-night. Os chips usam a nova cor secundária.

Projeto do Android Studio: GDGFinderFinal.

Compatibilidade com idiomas RTL

  • No manifesto do Android, defina android:supportsRtl="true".
  • Você pode visualizar o RTL no emulador e pode usar seu próprio idioma para verificar layouts de tela. Em um dispositivo ou emulador, abra Configurações e, em Opções do desenvolvedor, selecione Forçar layout RTL.
  • Substitua as referências a Left e Right por referências a Start e End.
  • Desative o espelhamento de drawables excluindo android:autoMirrored="true".
  • Escolha Refactor > Add RTL support where possible para permitir que o Android Studio faça o trabalho por você.
  • Use as pastas values-"código do idioma" para armazenar recursos específicos de idioma.

Verificar a acessibilidade

Projetar para TalkBack com descrições de conteúdo

  • Instale o Pacote de Acessibilidade do Android do Google, que inclui o TalkBack.
  • Adicione descrições de conteúdo a todos os elementos da IU. Exemplo:
    android:contentDescription="@string/stage_image_description"
  • Para um elemento editável, como um EditText, use um atributo android:hint no XML para dar uma dica ao usuário sobre o que digitar.
  • Crie grupos de conteúdo agrupando elementos relacionados em um grupo de visualizações.
  • Crie uma região ativa para dar feedback adicional aos usuários com android:accessibilityLiveRegion.

Usar ícones para implementar um filtro

  • Os ícones são elementos compactos que representam um atributo, texto, entidade ou ação.
  • Para criar um grupo de ícones, use um com.google.android.material.chip.ChipGroup.
  • Definir o layout de uma com.google.android.material.chip.Chip.
  • Se você quiser que seus chips mudem de cor, forneça uma lista de estados de cor como um <selector> com cores com estado:
    <item android:color="?attr/colorPrimaryVariant"
    android:state_selected="true" />
    .
  • Vincule os ícones a dados ativos adicionando um observador aos dados no modelo de visualização.
  • Para exibir os ícones, crie um inflador para o grupo de ícones:
    LayoutInflater.from(chipGroup.context)
  • Crie os ícones, adicione um listener de clique que acione a ação e adicione-os ao grupo.

Oferecer compatibilidade com o modo escuro

  • Use o DayNight AppTheme para oferecer compatibilidade com o modo escuro.
  • Você pode definir o modo escuro de forma programática:
    AppCompatDelegate.setDefaultNightMode()
  • Crie uma pasta de recursos res/values-night para fornecer cores e valores personalizados para o modo escuro.

Documentação do desenvolvedor Android:

Outros recursos:

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.

Pergunta 1

Qual das opções a seguir é obrigatória para a compatibilidade com idiomas com direção de leitura RTL?

▢ Substitua Left e Right nas propriedades por Start e End.

▢ Mudar para um idioma RTL

▢ Verifique se todos os ícones usam android:autoMirrored="true".

▢ Fornecer descrições de conteúdo.

Pergunta 2

Quais das seguintes ferramentas de acessibilidade são integradas à maioria dos dispositivos Android?

▢ TalkBack

▢ Scanner de acessibilidade

▢ No Android Studio, refatore > adicione compatibilidade com RTL sempre que possível.

▢ Lint

Pergunta 3

Qual das alternativas a seguir não é verdadeira sobre os ícones?

▢ Você exibe ícones como parte da ChipGroup.

▢ Você pode fornecer uma lista de estados de cores para uma ChipGroup.

▢ Os ícones são elementos compactos que representam entradas, atributos ou ações.

▢ Você precisará ativar o DarkTheme se o app usar ícones.

Pergunta 4

Qual tema define o estilo dos modos escuro e claro?

DayNight

DarkTheme

DarkAndLightTheme

Light

Pergunta 5

O que é uma região ativa?

▢ Um nó contém informações importantes para o usuário

▢ Uma região da tela que muda de forma de acordo com as diretrizes do Material Design.

▢ Uma visualização que permite fazer streaming de vídeo

▢ Um drawable animado.