A transição de elementos compartilhados não parece funcionar.
Testado em um dispositivo motorola com Android 5.0
Você pode nos dar mais detalhes? O que exatamente você tentou fazer e o que aconteceu em vez disso?
Na nova versão do Android, lollipop, podemos usar um ImageView como uma transição de elemento compartilhado entre as atividades. Nesse caso, a imagem faz uma transição suave de uma atividade para a próxima. Ao usar o SimpleDraweeView, ele simplesmente desaparece.
O código para testá-lo deve ser algo assim:
tema do aplicativo:
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:windowContentTransitions">true</item>
<item name="android:windowAllowEnterTransitionOverlap">true</item>
<item name="android:windowAllowReturnTransitionOverlap">true</item>
</style>
Activity1 Layout.xml:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.facebook.drawee.view.SimpleDraweeView
android:id="@+id/image"
android:layout_width="@dimen/size_1"
android:layout_height="@dimen/size_1"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"/>
</RelativeLayout>
Activity2 Layout.xml:
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.facebook.drawee.view.SimpleDraweeView
android:id="@+id/image"
android:layout_width="@dimen/size_2"
android:layout_height="@dimen/size_2"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:transitionName="image_transition"/>
</RelativeLayout>
O código para iniciar a segunda atividade:
Intent intent = new Intent(activity1, Activity2.class);
ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(activity1, simpleDraweeView1, "image_transition");
activity1.startActivity(intent, options.toBundle());
Este código deve fazer uma transição entre as atividades onde a imagem se move e redimensiona do canto superior esquerdo da atividade 1 para o canto inferior direito da atividade 2. Eu testei um código semelhante carregando imagens da rede e ele não exibe a animação.
Acho que isso também está relacionado https://github.com/facebook/fresco/issues/99
Suspeito que isso tenha a ver com eventos de anexação / desconexão que o modo de exibição obtém durante a transição. Teremos que investigar isso.
Isso também posso confirmar. As transições de elementos compartilhados parecem estar interrompidas no Fresco. Seria ótimo se pudéssemos consertar isso, pois esse é um recurso muito importante no futuro.
Aconteceu comigo também. Ao definir transtitionName xml attr para SimpleDraweeView, o método setImageUri () parou de funcionar
Alguma atualização sobre isso?
Após o FadeDrawable terminar de animar a imagem real, há um registro:
com.facebook.samples.comparison D / ViewRootImpl ﹕ changeCanvasOpacity: opaque = false
talvez o changeCanvasOpacity faça com que a imagem não seja desenhada.
O bug foi corrigido? É muito significativo para o meu projeto também. :)
package org.goodev.droidddle.drawee;
import com.facebook.drawee.generic.GenericDraweeHierarchy;
import com.facebook.drawee.view.SimpleDraweeView;
import android.content.Context;
import android.graphics.Matrix;
import android.util.AttributeSet;
public class TranslateDraweeView extends SimpleDraweeView {
public TranslateDraweeView (contexto de contexto) {
super (contexto);
}
public TranslateDraweeView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public TranslateDraweeView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
public TranslateDraweeView(Context context, GenericDraweeHierarchy hierarchy) {
super(context, hierarchy);
}
// looks like overwrite this method can fix this issue
// but still don't figure out why
public void animateTransform(Matrix matrix) {
invalidate();
}
}
@goodev não existe tal método para sobrescrever.
@ shumin0809 basta adicionar este método, é um método público de ocultação para a transição.
Estou vendo um comportamento diferente, mas ainda problemático, com SharedElementTransitions. Não sei se este é o mesmo problema, relacionado ou separado.
_Reprodução _
Configuração bastante padrão para uma SharedElementTransition:
_Esperado _
Quanto a ImageViews normais (correspondências de scaleType fornecidas), animação contínua de recurso compartilhado entre fragmentos
_Observado _
SharedElementTransition ocorre, mas há uma oscilação antes que a imagem de destino apareça (parece que a imagem de destino não foi definida com antecedência suficiente)
_Notas _
Tentei carregar imagens da web e do disco, e a imagem é carregada e está no cache antes de iniciar a transição. O código do fragmento de destino está puxando exatamente o mesmo uri. Eu tentei usar o pipeline diretamente (e aprendi muito), mas não consegui afetar o resultado.
_Setup _
Dispositivos: Nexus 5 e Nexus 7 (2013), ambos executando Android 5.1.1 (API 22)
Biblioteca e ferramentas atualizadas: fresco (0.5.0), Android Studio (1.3 Preview 3 EAP.0), compileSdk (22), ferramentas de compilação (22.0.1)
_Realizações _
Enquanto escrevo esta postagem, percebi 2 coisas que podem ser relevantes:
@jorgemf - seu código postado não precisa de um atributo de transição https://developer.android.com/training/material/animations.html
_Iniciar uma atividade com um elemento compartilhado _
...
4 - Atribua um nome comum aos elementos compartilhados em ambos os layouts com o atributo android: transactionName .
Para o meu problema, pode ser que eu precise adiar a transição. Vou dar uma olhada nisso hoje:
http://www.androiddesignpatterns.com/2015/03/activity-postponed-shared-element-transitions-part3b.html
Estou com o mesmo problema. Estou usando o fresco 0.5.3 e SimpleDraweeView e não carrego a imagem com attr " android: silenceName". Alguém conhece outra solução usando Fresco?
@jorgemf Se você definir "android-background" em seu Activity1 Layout.xml, não funcionará perfeitamente, mas funcionará.
Eu defini em meu teste: android: background = "@ android: color / transparent "
@LuizGadao Se você definir um fundo você perde todas as vantagens da biblioteca. Acho que é inútil como você quer para imagens baixadas da internet. Não para recursos estáticos como pano de fundo.
Depois de testar algumas bibliotecas, o picasso está funcionando bem para mim. Sem problemas.
@jorgemf eu concordo com você. É apenas um hack para fazer funcionar.
Algumas notícias sobre este?
@LuizGadao você pode postar um exemplo de seu XML de solução alternativa?
Obrigado por relatar este problema e apreciamos sua paciência. Notificamos a equipe principal para uma atualização sobre este problema. Esperamos uma resposta nos próximos 30 dias ou o problema pode ser resolvido.
Algumas notícias sobre este?
PS:
TranslateDraweeView fornecido por @goodev não funciona corretamente em alguns dispositivos como XiaoMi2, HuaWei P8. ReenterTransition começa na posição errada.
Como disse o boxcounter, Tra slateDraweeView não funciona no HTC One M8, nem
Se você estiver usando a transição ChangeImageTransform, então acho que a transição do elemento de compartilhamento falha porque ChangeImageTransform está animando a matriz de ImageView, que acho que não é compatível por padrão com DraweeView.
O problema que encontrei é que o elemento compartilhado começa com "fitCenter" enquanto originalmente era "centerCrop".
O projeto pode reproduzir o problema
https://github.com/JackFan-Z/ActivitySharedElementTransition.git
Embora eu tenha adicionado uma solução alternativa
não funciona no meu outro projeto privado usando afresco.
Alguém poderia descobrir onde está o verdadeiro problema?
Estado de transição errado
Antes da transição
@ JackFan-Z
Compartilhar elemento na transição é definir a visualização final para os valores iniciais e animá-la para os valores finais.
ImageView normal combinado com ChangeImageTransform
irá capturar os valores inicial e final da matriz da imagem e então animar a mudança da matriz da imagem.
No entanto, DraweeView
substitui certas funções relacionadas à matriz da imagem, de forma que ChangeImageTransform
não terá nenhum efeito na imagem.
Então, o que você acaba sendo apenas ChangeBounds entrando em vigor.
Atualmente, não encontrei nenhuma maneira de manipular a matriz de imagem de DraweeView. Até mesmo setActualImageMatrix
foi marcado como obsoleto. Vamos supor que ele não esteja obsoleto e funcione exatamente como o setImageMatrix
padrão do ImageView padrão. Mesmo assim, não é realmente muito conivente animar a mudança dela devido ao fato de que você não tem como mudar a matriz depois de definir DraweeViewHierarchy
. Então, você precisa criar um novo DraweeViewHierarchy
a cada onAnimationUpdate
chamada.
Eu não sei por que DraweeView implementar desta forma. E eu acho que a solução possível atual é recuperar o Bitmap subjacente e criar outro ImageView para fazer a ChangeImageTransform
Transição.
@soapsign
Obrigado por seu comentário.
Na verdade, em meu projeto privado, tentei criar um ImageView fictício que usa o mesmo bitmap como elemento compartilhado. O problema ainda existe.
Não tenho certeza se o problema que estou enfrentando está relacionado ao fresco ou não.
Mas com certeza posso reproduzir o mesmo problema facilmente com SimpleDraweeView.
O ChangeImageTransform
usa as dimensões intrínsecas para determinar a matriz de transformação. Nossa implementação de DraweeView
usa um DraweeHierarchy
que possui dimensões intrínsecas iguais a -1 para width
e height
. Isso ocorre porque Drawee
já aplica a escala do tipo de escala correto e, portanto, não há necessidade de uma visualização para fazê-lo. Além disso, ImageView
só pode aplicar um tipo de escala, enquanto a hierarquia drawable pode usar tipos de escala separados para cada ramificação da imagem (placeholder, imagem de falha, imagem real, etc.). Retornar dimensões intrínsecas reais à exibição apenas coloca como risco de ter bugs de dimensionamento.
Se você quiser que a transição funcione, você deve usar ChangeBounds
.
Que tal adicionar uma nova opção como " fresco: ImageMatrixSrc = atual "?
@boxcounter No momento achamos que o que temos agora está ok. Mas você pode criar uma solicitação pull para sua proposta :)
@massimocarli ChangeBounds funciona bem apenas quando a imagem compartilhada tem o mesmo tamanho em ambas as atividades / visualizações. Mas quando a imagem deve ser redimensionada durante a transição, ela é cortada e fica ruim.
O que você se propõe a fazer dessa forma? ChangeImageTransform resolve isso, mas não funciona em DraweeView.
Mesmo aqui...
@massimocarli ChangeBounds não é bom o suficiente.
Isso é o que estou tentando alcançar (isso é usando ImageView): https://gfycat.com/HideousEarlyAndalusianhorse
Isso é o que parece usando SimpleDraweeView: https://gfycat.com/PracticalCorruptGrouper
Observe a maneira como a imagem original é redimensionada incorretamente atrás da imagem animada.
Isso é o que parece apenas com ChangeBounds como a transição: https://gfycat.com/SorrowfulExemplaryAntlion
Ei pessoal, eu tenho o mesmo problema. ChangeBounds não está funcionando bem. Se houver uma solução alternativa ou solução, informe-nos. A transição de elementos compartilhados é uma das melhores coisas que o material design introduziu e o fresco é uma das melhores bibliotecas que usei até agora. Por favor, deixe os desenvolvedores usarem ambos perfeitamente.
Alguém conseguiu encontrar uma solução alternativa, visto que o Fresco não corrige isso?
Aqui está a solução alternativa que utilizo que funciona bem:
https://github.com/bumptech/glide
Olá pessoal,
O método ChangeBounds em si não é suficiente e estou surpreso com a resposta do Facebook de que o estado atual das transições de elementos compartilhados está ok.
Finalmente encontrei uma solução simples que parece funcionar para mim em um projeto de amostra.
Uma vez que a transição ChangeBounds não atualiza o próprio layout por meio de onMeasure (), mas por meio de onSizeChanged (), que atualmente não é anulado por nenhuma vista de desenho, a escala do drawable nunca é atualizada durante a transição.
Aqui está nosso CustomDraweeView, que atualiza o TopLevelDrawable durante a transição:
public class CustomDraweeView extends SimpleDraweeView {
public CustomDraweeView(Context context, GenericDraweeHierarchy hierarchy) {
super(context, hierarchy);
}
public CustomDraweeView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
<strong i="10">@Override</strong>
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
Drawable drawable = getTopLevelDrawable();
if (drawable != null) {
drawable.setBounds(0, 0, w, h);
}
}
}
Aqui está o xml do conjunto de transições que você precisará aumentar:
<?xml version="1.0" encoding="utf-8"?>
<transitionSet
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:duration="<strong i="14">@android</strong>:integer/config_mediumAnimTime"
android:transitionOrdering="together"
tools:targetApi="LOLLIPOP" >
<changeBounds
android:interpolator="<strong i="15">@android</strong>:interpolator/accelerate_decelerate"/>
<changeTransform
android:interpolator="<strong i="16">@android</strong>:interpolator/accelerate_decelerate"/>
</transitionSet>
A única desvantagem que tenho com esse método é quando o tipo de escala dos drawables não corresponde entre os fragmentos ou as atividades, o que você deve evitar de qualquer maneira se quiser usar transições de elementos compartilhados.
@massimocarli @tyronen
Alguém no Facebook pode fornecer algumas dicas de por que DraweeView não substitui esse método atualmente e os possíveis problemas que podem surgir com essa modificação? Se nenhum for encontrado, ficarei feliz em criar uma solicitação de pull para isso.
Olá a todos! Na nova versão do Fresco 0.10 com a transformação ScaleType personalizada entre diferentes ScaleTypes é trivial. Aqui está minha implementação
https://gist.github.com/burzumrus/a589aa7e36ca003ddaf2334218c50ad0
O uso é simples
TransitionSet transitionSet = new TransitionSet();
transitionSet.addTransition(new ChangeBounds());
transitionSet.addTransition(new DraweeTransform(ScalingUtils.ScaleType.CENTER_CROP, ScalingUtils.ScaleType.FIT_CENTER));
getWindow().setSharedElementEnterTransition(transitionSet);
@burzumrus isso é incrível! Obrigado por implementá-lo. Isso é exatamente o que eu tinha em mente com InterpolatingScaleType
. Considere fazer uma solicitação de pull para Fresco, se ainda não tiver feito.
@plamenko estou usando o fresco 0.12 e
getWindow().setSharedElementEnterTransition(DraweeTransition.createTransitionSet(
ScalingUtils.ScaleType.CENTER_CROP, ScalingUtils.ScaleType.CENTER_CROP));
getWindow().setSharedElementEnterTransition(DraweeTransition.createTransitionSet(
ScalingUtils.ScaleType.CENTER_CROP, ScalingUtils.ScaleType.CENTER_CROP));
A animação está funcionando perfeitamente. Mas, no retorno à primeira atividade, a imagem está desaparecendo
Alguém tentou fazer isso com animações de fragmento a fragmento? Porque não parece funcionar na v0.12.
Edit : é possível que o RecyclerView cause problemas?
Edição 2 : Parece que o problema é que ChangeBounds
si só usa as coordenadas X e Y _window_ se a redefinição estiver definida como verdadeira. Configurá-lo por meio de ChangeBounds
's setReparenting(true)
está obsoleto e ChangeTransform
é recomendado em seu lugar. Portanto, para RecyclerView
, transitionSet.addTransition(new ChangeTransform());
também é necessário. (A animação de retorno ainda parece ruim, mas pelo menos a animação de entrada está bem ( exceto que o tipo de escala não tem efeito mudando startValues.view
para endValues.view
em createAnimator(...)
resolve isso) com isto.)
@Gericop e @ ladia12 0.12 funcionam bem no meu projeto em animações fragmento a fragmento.
Eu também o uso no RecyclerView.
O fato é que você só pode usar a transação de fragmento 'substituir'. Você não pode usar a transação 'adicionar'.
Se isso pode ajudá-lo, aqui está um exemplo (sem afresco) de transição fragmento a fragmento que me ajudou a começar em algo que funcionou (você pode baixar o código do projeto no github)
http://www.androidauthority.com/using-shared-element-transitions-activities-fragments-631996/
@sperochon Eu uso substituir e está em um RecyclerView, mas não funciona (e honestamente, é surpreendente que funcione para você, talvez você use uma versão diferente do RecyclerView? Eu uso a v24.1.1). Tive que fazer algumas alterações para fazer as animações funcionarem:
ChangeTransform
ao conjunto de transição por meio de transitionSet.addTransition(new ChangeTransform());
ChangeBounds
relata a posição incorreta da visualização inicial em um RecyclerView
(ele sempre retorna as coordenadas X, Y do primeiro elemento)createAnimator(...)
substitua if (mFromScale == mToScale)
por if(mFromScale == mToScale && startBounds.equals(endBounds))
createAnimator(...)
substitua final GenericDraweeView draweeView = (GenericDraweeView) startValues.view;
por final GenericDraweeView draweeView = (GenericDraweeView) endValues.view;
(lembre-se da mudança de startValues
-> endValues
)AnimatorUpdateListener
após a chamada scaleType.setValue(fraction)
, insira as seguintes linhas:Drawable drawable = draweeView.getTopLevelDrawable();
if (drawable != null) {
drawable.setBounds(0, 0, draweeView.getWidth(), draweeView.getHeight());
}
Esta última parte do código é baseada na solução de @Aohayou (porque eu não consegui fazer CustomDraweeView
funcionar).
Testado no Android 5.0.2 com suporte à versão lib v24.1.1.
NOTE que esta solução não funcionará se você fizer uma animação entre imagens com os mesmos tamanhos.
@Gericop Aqui está uma demonstração de que funciona bem. Acabei de enviá-lo para o github. Tentei limpar o código no máximo. Cuidado: usei apenas 1 imagem em minha visualização da recicladora porque o nome da transição deve ser diferente em cada item da visualização da recicladora para que o Fresco funcione. Então, para simplificar, usei apenas 1 imagem com 1 nome de transição.
https://github.com/sperochon/DemoFrescoFragment2Fragment
Espero que esta ajuda!
@sperochon Experimente com várias imagens.
A propósito, testei sua demonstração com fonte não modificada. Este é o resultado:
Isso está completamente errado. A vista final começa em uma posição diferente e o tipo de escala não tem efeito algum. Não sei como você pode dizer que "funciona bem" porque claramente não funciona.
@Gericop Acabei de atualizar o código. Esqueci de especificar um layout diferente para o fragmento final. Tente de novo por favor.
@sperochon No emulador API 23, funciona bem. No meu dispositivo (API 21) isso não acontece. Também testei em um emulador API 21, também não funciona lá.
Portanto, a questão é: a implementação atual não funciona na API 21 (não a testei na API 22), mas funciona na API 23.
Editar : sua demonstração testa apenas as transições ChangeBounds
e ChangeTransform
padrão, não a implementação DraweeTransition
fornecida pelo Facebook.
Infelizmente, você está certo ... Eu testei em meus dispositivos:
Android 5.0 + Fresco v0.11 / v0.12 -> KO
Android 6.0 + Fresco v0.11 / v0.12 -> OK
Não tinha percebido antes ...
@Gericop @sperochon Escrevi um post no
@ ladia12 Essa postagem não tem nada a ver com o problema que eu estava (estávamos) enfrentando ... Sua entrada no blog é sobre a transição _inter- Activity _, enquanto meu problema está relacionado a _inter- Fragment _. Além disso, o verdadeiro bug está em como a API 21 lida com as transições ChangeBounds
e / ou ChangeTransform
onde o Facebook forneceu DraweeTransition
também não ajuda. Minha solução, por outro lado, supera isso, se as imagens de origem e destino tiverem dimensões diferentes (largura e / ou altura).
Apenas para informação:
Android 5.0 + Fresco v0.11 / v0.12 / 0.13 -> KO
Android> = 5.1 + Fresco v0.11 / 0.12 / 0.13 -> OK
@ ladia12 Como você resolveu o problema do desaparecimento da imagem original ao retornar para a primeira atividade?
@dbrant Estou com o mesmo problema, encontrou uma maneira de resolver?
Veja # 1446
@ ladia12 Como você resolveu o problema do desaparecimento da imagem original ao retornar para a primeira atividade?
@ ladia12 Como você resolveu o problema do desaparecimento da imagem original ao retornar para a primeira atividade? Minha imagem original está no visor do Recyclerview
Acabei usando o Picasso para a transição do elemento compartilhado. Não foi consertado
em Fresco. Então, Picasso é leve e não há nenhum problema em usá-lo
junto com Fresco.
Na quarta-feira, 19 de junho de 2019 às 17:11 bembem1011 [email protected] escreveu:
@ ladia12 https://github.com/ladia12 Como você resolveu o problema de
a imagem original desaparecendo ao retornar para a primeira atividade? Meu
a imagem original está no visor do Recyclerview-
Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/facebook/fresco/issues/22?email_source=notifications&email_token=AAXQ5WYUP5KBJYNBOZX7CCDP3ILM5A5CNFSM4A6ZMH32YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGODYBSZCI#issuecomment-503524489 ,
ou silenciar o tópico
https://github.com/notifications/unsubscribe-auth/AAXQ5W5EXO5SV4R2PXVTG7LP3ILM5ANCNFSM4A6ZMH3Q
.
Comentários muito úteis
Aqui está a solução alternativa que utilizo que funciona bem:
https://github.com/bumptech/glide