Transição, Zoom Pinch e Drag to back de ImageView

Nesse artigo vou explicar de forma objetiva como fazer transição de imagens entre Activities distintas usando o framework Glide para carregar as imagens, aplicar zoom no detalhe da imagem com o framework PhotoView e Drag to back de forma nativa.

Transição de imagen entre as Activities:

Primeiro vamos carregar uma imagem utilizando o Glide:

Passamos no método loadImage a ImageView para ser carregada pelo Glide. No Glide.load() passamos a URL dá imagem e no into() a imageView. Isso é feito na nossa MainActivity.

Em seguida setamos o click na nossa ImageView para fazer a transição.

Utilizamos a notação @OnClick do ButterKnife e o método transition() que criamos, onde passamos a nossa ImageView, a url da imagem e o id de transição para a outra View.

Criamos o nosso Intent passando a url e o id no putExtra() para ser setado na outra Activity.

Setamos no ViewCompat.setTransitionName() o nome da transição e a transição no ActivityOptionsCompat.makeSceneTransitionAnimation() e iniciamos a nossa próxima Activity passando nossa transição.

Custom FrameLayout:

Para começar a criar nossa activity que receberá a transição, vamos começar pelo widget que vamos utilizar no layout.

Vamos criar nosso widget FrameTouch que será utilizado na nossa segunda activity:

Utilizamos o GestureDetector e o ScaleGestureDetector para pegar os eventos de touch na nossa View.

Primeiro implementamos o ScaleGestureDetector.OnScaleGestureListener, que permiti que o ZoomPinch continue funcionando corretamente, com os métodos de Scale.

Criamos a classe MyGestureListener para pegar os eventos de transladação da View. No método onScroll() chamamos o onScrollMovie() e passamos os atributos distanceX e distanceY para transladar a imagem na view que a implementa.

O método onScrollMovie faz parte da interface OnFrameTouchListener.

Para finalizar nosso widget temos mais alguns métodos.

No dispatchTouchEvent(), verificamos que a view recebeu um evento de Touch e a partir disso, disparamos o que queremos fazer.

Quando o event for ACTION_UP ele chama o método onFrameTouchUp(), que vai verificar se a imagem está pronta para voltar a view anterior ou continuar na sua view, onde ela for implementada através da interface FrameOnTouch.

E vai ficar assim nosso xml:

E agora com o nosso xml pronto utilizando o nosso widget, vamos para nossa ZoomPichActivity.java.

Primeiro vamos configurar o ZoomPinch, finalizar nossa transição, e depois implementar os métodos do OnFrameTouchListener.

Configurando o ZoomPinch:

Para ser bem direto vamos ver o código na prática:

Criamos nossa variavael mAttacher e no método onCreate da view setamos as propriedadese e a imageView que vai utilizar o framework. Setamos o mínimo e o máximo do Scale do zoom e o tipo do Zoom. E quando o Glide finalizar o load da imagem setamos mAttacher.update() para que nossa imagem use as propriedades do framework(essse exemplo do load da imagem ainda é sem transição, que veremos em seguida).

No onDestroy() e onBackPressed() temos que limpar o mAttacher para nao causar crash.

Finalizando a transição da imagem e a implementação da interface do FrameOnTouchListener:

No código a seguir finalizamos a transição:

Em seguida temos nossos métodos que fazem a mágica do DragToBack acontecer:

getDistance(): O método getDistance() retorna a distancia que a photo está do seu lugar de origem.

calColor(): Calcula a cor conforme a transladação da imagem na view, para dar o efeito de quanto mais longe a imagem estiver do lugar de origem o background vai ficando transparente e quanto mais perto vai voltando a ser preto.

onFramTouchUp(): É chamado quando o usuário solta a imagem e verifica se a distancia do seu lugar de origem é o suficiente para setar o onBackPressed() ou continuar na view onde está voltando a ter o background preto.

onScrollMove(): É chamado quando o usuário faz o drag na imagem e translada a mesma conforme for arrastada nos eixos X e Y.

E no fim nossa Activity tem que ficar assim:

Conclusão

De maneira simples temos uma transição fluída, e que podemos implementar nos nossos projetos.

Por que essa feature foi feita? E como foi feita?

Ela foi feita para um projeto da empresa onde eu trabalho juntamente com o outro Dev Android Bruno Stone. Se não fosse em conjunto essa feature não teria saído do campo da ideia. Foi após uma conversa que tivemos de como fazer, olhando como era em outros apps como Facebook e chegamos a conclusão que valia apena gastar um tempo nisso para que o detalhe desse componente ficasse o melhor possível para UX do app.

Source:

No meu gitHub está o código fonte dessa feature, e um app na play para vocês verem na prática.

Seguem os links:

https://github.com/ifucolo/ZoomPich-Android

https://play.google.com/store/apps/details?id=example.com.zoompinch

Contato: iagofucolo@gmail.com

Fique a vontade pra mandar um email com alguma dúvida.

Bibliografia