terça-feira, 3 de maio de 2016

Aplicando o padrão de projeto State para gerenciar fragments. - PARTE 2

           Vimos no post Aplicando o padrão de projeto State para gerznciar fragments. - PARTE 1 como criar uma estrutura de organização de fragments utilizando Enum.

           Agora vamos trabalhar na classe PageManager.java, nela que iremos ter a utilização do Enum e o resultado das regras implementadas no padrão State. A estrutura inicial dela é a seguinte:


Note que a classe implementa a interface chamada FragmentState e através do método onFragmentRemoved o PageManager saberá quando o fragment não estará mais sendo usado e o removerá do seu respectivo PageId.

Nela temos uma variável chamada currentPage que será responsável por guardar o id da página atual e também a activity.
Depois aplicamos o padrão Singleton para garantir sempre a mesmas instância da classe.
Logo em seguida temos o método da classe, goToPage. Nele que ocorrerá a mágica.
"Não é a linguagem de programação que define o programador, mas sim sua lógica."

Provavelmente você deve ter se perguntado: "Mas onde estamos verificando se o fluxo de tela está correto?", nesse momento tudo nos leva a usar o if/else ou um switch e criarmos essa regra, mas com muitos fragments isso ia ficar bem complicado de manter, então, antes de implementarmos o goToPage vamos fazer uma modificação no Enum PageId.java, para criamos de fato as regras de navegação baseado no padrão State. 
O que faremos é criamos o método getNextPage( PageId actualPage ), e todos os itens do meu enum terão que sobrescrever ele, caso contrário, ele lançará uma exceção.


Traduzindo esse trecho de código, estamos dizendo que a partir da tela SPLASH queremos ir para a próxima tela e pedimos para ela nós fornecer a classe uma instancia TransitionPageConfig.java. Essa classe é responsável por configurar a transição das telas, no caso as transições SPLASH -> LOGIN e SPLASH -> HOME.


os xmls usados nas animações podem ser baixados aqui.

Enum finalizado, iremos terminar o goToPage inserindo as seguintes regras:
1 - Verificar próximo fluxo, caso sejá válido, lançar uma exceção.
2 - Configurar a animação.
3 - Caso o fragment atual esteja no container_2 e a próxima tela irá estar no container 1, então :
    3.1 - Verificar se o fragment no container_1 precisa ser alterado.
        3.1.1 - Caso o próximo fragment já está no container_1, então, apenas remova o fragment do container_2.
        3.1.2 - Caso o próximo fragment não está no container_1, então, devemos mudar o fragment do container_1 e depois remover o fragment do conteiner_2.

Resultando com a classe PageManager.java :


OBS: Todo projeto pode ser encontrado no meu GitHub

segunda-feira, 2 de maio de 2016

Aplicando o padrão de projeto State para gerenciar fragments. - PARTE 1


   
É comum acontecer problemas quando tentamos criar um fluxo de telas utilizando fragments em mais de 1 conteiner. As vezes não conseguimos entender como podemos mostrar um fragment por cima de outro fragment e qual a melhor maneira de exibir o fragment que estava sendo exibido antes do fragment atual.
Esse gerenciamento pode acabar levando você a criar vários if/else ou um enorme switch case o que não é um boa prática pois diminui a manutenibilidade, além de sujar seu código.

Como exemplo iremos criar um aplicativo simples que terá apenas uma activity e dois containers onde ficaram armazenados os fragments

Colocando em imagens fica mais claro para entender a estrutura do layout que armazenará os fragments:
A ideia é que sejá possível usar os dois containers para exibir os fragments e que cada fragment saiba onde vai ser exibido.
Mas por que usar fragments que serão exibidos um por cima do outro?
Com a popularização dos fragments, um aplicação pode conter diversos fragments e eles podem ser adicionados em vários containers e se a troca de fragments não for bem orquestrada, isso pode causar diversos problemas como, fragments que aparecem em lugares errados ou não aparecem e você não entende o que aconteceu.

Depois de quebrar a cabeça por bastante tempo consegui chegar em uma solução utilizando uma das melhores invenções do Java( Na minha opinião ), Enum.
O Enum aliado ao padrão de projeto State, pode ser um ferramenta poderosa para controle de fluxos, pois com essa dupla é possivel definir qual o próxima tela que devo ir,  baseado na tela atual e caso eu tente ir para uma tela errada!! BUMM!, Exception in your face!!!.

Resumindo de forma bem rápido o que é o padrão de projeto State. Ele tem como principal objetivo definir qual o próximo comportamento/estado de um objeto baseado no comportamento/estado atual garantindo assim que todo fluxo pré-definido será respeitado.

Quero demonstrar como eu consegui fazer um workaround para evitar estes problemas.
A aplicação terá apenas 6 telas, mas ao final do projeto, será possível adicionar novas telas(fragments) sem muito trabalho.

O video abaixo demonstra como o app funcionará.


Fluxo das telas.

As telas serão:
Splash, Login, Sign Up, Home, Settings e User Settings
E seguirão as seguintes regras:




A estrutura do projeto se baseia nas seguintes classes:

1. MainActivity.java -> Activity que contém os dois containers (LinearLayouts) dos fragments.
2. PageManager.java -> Classe que será responsável pela navegação dos fragments.
3. PageId.java -> Enum onde será aplicado o padrão State.
4. TransitionPageConfig.java -> Classe que representará a *configuração da transição (Tela Atual -> Próxima Tela).
5. Fragments que representarão cada tela da aplicação

*As configurações de tela serão:

1. Qual o fragment da tela.
2. Em qual container ela irá aparecer (fragment_container_1 out fragment_container_2).
3. Qual será a animação de saída do fragment atual e a animação de entrada do próximo fragment?
4. Qual será a próxima tela a ser exibida?
5. É preciso remover a tela atual?
6. É preciso alterar a próxima tela?

Mão na massa!!
“Uma caminhada de mil léguas começa com o primeiro passo”, diz o filosofo… 
“int main(){“, diz o programador.

Começaremos pelo Enum onde será aplicado o padrão State.

Começaremos definindo os ids referentes as telas:


Em seguida vamos dar a cada enum dele dois atributos um Fragment, e um inteiro que será o id do container  onde o fragment irá ser adicionado e seus respectivos getters:


Perceba que eu adicionei também um construtor que recebe como parâmetro o id do container. Ao fazer isso cada tela do enum terá que passar como construtor o Id, ficando desse jeito:


Todos os fragments utilizados na aplicação herdam de BaseFragment, que contém um Listener e será usado no PageManager.java para indicar quando o fragment foi destruido.





Agora vamos modificar o método getFragment() e criar o um método abstrato getFragmentInstance() que será implementado por cada item;

Ok, até agora vimos como utilizar o Enum para montar nossa configuração dos fragments, deixando assim o código mais limpo e organizado.

No próximo post irei mostrar como utilizaremos esse Enum para aplicarmos na prática o padrão State.

sexta-feira, 22 de agosto de 2014

Dica - Leitura: O Programador Apaixonado: Construindo uma carreira notável em desenvolvimento de software



Recentemente li o livro : O Programador Apaixonado da galera da Casa do Código .
O livro lhe leva a refletir muito sobre a sua carreira na área de TI, Chad Fowler famoso desenvolvedor de software mostra como podemos melhorar o processo de evolução profissional apenas mudando algumas atitudes e buscando organizar nossas tarefas do dia a dia.
Ao final de cada capítulo uma missão é dada , faça algo!, ainda não consegui cumprir todas , mas já vejo resultados.
Por ter uma didática bem diferente e não ter códigos o livro prendeu minha atenção e me fez refletir muito sobre o caminho que estou seguindo como desenvolvedor.

Parabéns a Casa do Código pelos livros divulgados, e ao Chad Fowler  pela Obra!

Link: O Programador Apaixonado

Grande Abraço!