Server Driven UI com Android DynamicViews - "O Guerreiro Mestre de Armas"

Rodrigo Vianna Calixto de Oliveira
CodandoTV
Published in
6 min readFeb 18, 2022
http://rpgmassacre.blogspot.com/2013/02/dicas-de-interpretacao-parte-3-guerreiro.html

Esse é um dos personagens da D&D - Party Perfeita para sua Aplicação. Conhecido como o Guerreiro Mestre de Armas, com sua valentia de ficar a frente do usuário e ter todo tipo de recurso para usar com suas próprias forças junto com seus aliados(Mago, Clérigo e Ranger), ele é a representação de que em projetos Android é de costume muitas vezes fazer criações de telas simples de visualização com ações ou fluxos curtos, porém não é porque é "simples" que acaba sendo proporcionalmente rápido o desenvolvimento. Além disso, ultimamente eu tenho trabalhado em um projeto onde os times de desenvolvimento precisam criar várias telas parecidas com fluxos curtos e experimentos rápidos. Devido a isso, fiquei pensando em possibilidades que poderiam ajudar a otimizar o tempo do time e a partir disso eu fiz uma nova versão de uma solução baseada no conceito de Server Driven UI na qual já tinha trabalhado e desenvolvido junto com um amigo (Gustavo Santorio) que o mesmo escreveu um artigo sobre a parte inicial desta solução.

Introdução

Dando um contexto antes de irmos para o código, basicamente a base da solução é inspirada no repositório do vivchar que foi iniciado desde a solução inicial que é utilizar um RecyclerView com múltiplos tipos de itens, onde cada ViewType será um componente e para isso precisamos aproveitar um conceito chamado ViewRender que é uma forma de simplificar a entrada de dados para converter em um tipo legível para nosso adapter que posteriormente será mostrado na nossa tela. Porém como comentei acima faltava a parte de fazer o dinâmico estar preparado para receber outros fluxos dinâmicos de maneira fluida e não só se limitar em mostrar componentes na tela e que tudo isso ainda pudesse ser rastreável.

Antes de começarmos, vou dividir o dinâmico em duas partes:

  • Mecanismo do dinâmico que é responsável por fazer as Views aparecerem na tela com algumas ferramentas para poder facilitar o uso do mesmo.
  • Adaptação dos seus componentes para "plugar" no dinâmico, como criar seus componentes no item 4 da parte de "Implementação".

Para facilitar o uso criei a biblioteca do DynamicViews que é responsável pelo mecanismo do dinâmico e com 6(seis) passos você já consegue criar suas telas de maneira dinâmica com possibilidade de seguir com novos fluxos utilizando deeplink e ainda possibilitar ser feito o rastreamento.

Como o Dinâmico é um Server Driven UI, isto é, ele pode ser utilizado por qualquer tipo de fonte de dados e neste exemplo será utilizado um Json e com um campo chamado data que é um array de "componentes" e que dentro dele tem dois campos importantes o key que será utilizado no ViewType para conseguir distinguir o que é cada componente e o value que pode ser qualquer coisa que tenha sido mapeado no seu objeto, sim qualquer coisa mesmo!

Implementação:

1. Adicionar a lib do DynamicView

Adicione no build.gradle:

Adicione no seu modulo:

implementation 'com.github.rviannaoliveira:DynamicView:1.0.3'

2. Declare no XML

Na sua Activity/Fragment, adicione no seu xml o RecycleView e apenas isso partindo do princípio que todos os componentes são um item da sua lista.

3. Declarando a interface do DynamicView

Dentro da sua camada de apresentação (ViewModel/Presenter) adicione no construtor a interface do DynamicView. Ela é a abstração da classe DynamicViewAdapter que é onde está o mecanismo de interpretar os tipos de ViewRenders para cada ViewType, esta interface do DynamicView tem tudo que você precisa para estar trabalhando com o retorno da API, além disso você conseguiria fazer testes unitários de tudo que veio da sua camada de domain.

4. Associar ao Adapter da tela

Após ter sua referência de DynamicView em mãos você precisa associar ao Adapter do RecycleView dentro da sua Activity

5. Mapeamento dos objetos

Essa é a parte que precisa ser montado os componentes criando seus próprios ViewRenders e o mapeamento dos seus respectivos objetos para funcionar com o Dynamic, mas antes de montar sua classe ViewRender, que é responsável por "plugar" no dinâmico. Precisamos fazer o mapeamento do json do key e value.

Crie uma classe DynamicComponent, com o mapeamento de todos os key que estarão previstos no retorno do json.

Depois crie seu objeto onde deve ter os mesmos campos do json, isto é, os campos esperados no value que vem do seu json.

Após o mapeamento do json, agora sim está na hora de criar seus ViewRenders baseado no objeto mapeado que esta na linha 7, note que estamos recebendo qualquer coisa para em seguida ser transformado no objeto mapeado e popular nosso componente.

Nota: Foi colocado um exemplo simples de um Button, mas na linha 21 ele aceita uma View qualquer, isto quer dizer que pode ser tanto um xml como um componente customizado. E caso você siga para o caminho do componente customizado, você pode repassar o objeto para um método dentro do componente, populando os atributos internamente tornando o Render mais limpo.

Obs: Caso venha algum componente que não esteja mapeado, a biblioteca faz o tratamento ignorando esse componente mostrando um ViewRender vazio.

6. Popular seu Dynamic

Agora que temos nossos ViewRenders montados e mapeados precisamos registrar a nossa lista de itens que terá o Adapter conforme a linha 28. Após isso, notificar a RecycleView utilizando o dynamic.setViewObjectDiff(it). Além disso, todos os ViewRenders tem um callback que te permite ter acesso ao DynamicActionProperties que retorna três tipos de propriedades vindas do Json:

  • deeplink - retornar uma String sendo um deeplink interno ou externo(Colocar o link);
  • analytics - retorna um DynamicAnalyticsProperties que tem category/action/label para poder fazer a rastreabilidade do componente;
  • actionData - que pode ser qualquer coisa caso você tenha outra necessidade.

Segue um video de exemplo com o resultado:

Criando personagens Multiclasse:

Lembrando que o exemplo foi dado com um JSON vindo de uma API qualquer, porém vale reforçar que é necessário apenas de uma fonte de dados, isto é, podendo ser do RemoteConfig ou até localmente, e com isso você teria toda a flexibilidade da utilização do DynamicView.

E isso é tudo galera. Vale reforçar que a ideia do DynamicView não é ser uma bala de prata para todas as funcionalidades e telas, porém para casos mais simples e até alguns mais avançados vai com certeza suprir suas necessidades. E a proposta desse artigo é focar mais no mecanismo, pois os componentes criados podem e devem ser de criação de vocês para ter toda a flexibilidade que vocês precisam na sua aplicação!

Links relacionados:

Github do repositório com a nova versão:

Agradeço e se tiver qualquer feedback, deixa ai nos comentários ou entre em contato comigo no LinkedIn ou https://flow.page/rviannaoliveira.

--

--