Coder Social home page Coder Social logo

Shared element transition about fresco HOT 57 CLOSED

facebook avatar facebook commented on April 29, 2024
Shared element transition

from fresco.

Comments (57)

sperochon avatar sperochon commented on April 29, 2024 27

Here is the workaround I use that works fine:
https://github.com/bumptech/glide

from fresco.

ladia12 avatar ladia12 commented on April 29, 2024 23

@plamenko I am using fresco 0.12 and

getWindow().setSharedElementEnterTransition(DraweeTransition.createTransitionSet(
                    ScalingUtils.ScaleType.CENTER_CROP, ScalingUtils.ScaleType.CENTER_CROP));
getWindow().setSharedElementEnterTransition(DraweeTransition.createTransitionSet(
                    ScalingUtils.ScaleType.CENTER_CROP, ScalingUtils.ScaleType.CENTER_CROP));

The animation is working perfectly. But on return to first activity the image is disappearing

from fresco.

goodev avatar goodev commented on April 29, 2024 16

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(Context context) {
super(context);
}

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();
}

}

from fresco.

deepoke avatar deepoke commented on April 29, 2024 6

Has anyone been able to find a workaround since Fresco won't fix this?

from fresco.

dbrant avatar dbrant commented on April 29, 2024 5

@ladia12 How did you resolve the issue of the original image disappearing when returning to the first activity?

from fresco.

goodev avatar goodev commented on April 29, 2024 3

@shumin0809 just add this method, this is a hide public method for the transition.

from fresco.

esnaultdev avatar esnaultdev commented on April 29, 2024 3

Hello everybody,

The ChangeBounds method itself isn't enough and I'm astonished by the answer from Facebook that the current state of shared elements transitions is ok.

I finally found a simple enough solution that seems to work for me on a sample project.
Since the ChangeBounds transition doesn't update the layout itself through onMeasure() but through onSizeChanged(), which is currently not overrided by any drawee view, the scale of the drawable is never updated during the transition.

Here is our CustomDraweeView which updates the TopLevelDrawable during the transition:

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);
    }

    @Override
    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);
        }
    }
}

Here is the xml of the transitionset you will need to inflate:

<?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="@android:integer/config_mediumAnimTime"
    android:transitionOrdering="together"
    tools:targetApi="LOLLIPOP" >
    <changeBounds
        android:interpolator="@android:interpolator/accelerate_decelerate"/>
    <changeTransform
        android:interpolator="@android:interpolator/accelerate_decelerate"/>
</transitionSet>

The only downside I have with this method is when the scale type of the drawables don't match between the fragments or the activities, which you should avoid anyway if you want to use shared elements transitions.

@massimocarli @tyronen
Can anybody at Facebook provide some insight to why DraweeView doesn't currently override this method and to the possible problems that might crop up with this modification? If none is found, I would be happy to create a pull-request for that.

from fresco.

sperochon avatar sperochon commented on April 29, 2024 3

@Gericop Here is a demo that it works fine. I've just commit it onto github. I tried to clean the code at maximum. Be careful: I used only 1 image in my recycler view because the transition name has to be different on each item of the recycler view in order to Fresco to work. So, to simplify, I used only 1 image with 1 transition name.
https://github.com/sperochon/DemoFrescoFragment2Fragment

Hope this help!

from fresco.

ladia12 avatar ladia12 commented on April 29, 2024 3

@Gericop @sperochon I have written a blog post on medium about this. Please see if it helps.

from fresco.

ZakAnun avatar ZakAnun commented on April 29, 2024 3

@ladia12 How did you resolve the issue of the original image disappearing when returning to the first activity?

from fresco.

Syrok77 avatar Syrok77 commented on April 29, 2024 1

@massimocarli ChangeBounds isn't good enough.

This is what I'm trying to achieve (this is using ImageView): https://gfycat.com/HideousEarlyAndalusianhorse

This is what it looks like using SimpleDraweeView: https://gfycat.com/PracticalCorruptGrouper
Note the way the original image resizes incorrectly behind the animated image.

This is what it looks like with just ChangeBounds as the Transition: https://gfycat.com/SorrowfulExemplaryAntlion

from fresco.

tyronen avatar tyronen commented on April 29, 2024

Can you give us more details? What exactly did you try to do, and what happened instead?

from fresco.

jorgemf avatar jorgemf commented on April 29, 2024

In the new android version, lollipop, we can use an ImageView as a shared element transition between activities. In that case the image make a smoth transition from one activity to the next one. When using the SimpleDraweeView it just disappear.

The code to test it should be something like this:

theme of the app:

    <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>

The code to start the second activity:

    Intent intent = new Intent(activity1, Activity2.class);
    ActivityOptions options = ActivityOptions.makeSceneTransitionAnimation(activity1, simpleDraweeView1, "image_transition");
    activity1.startActivity(intent, options.toBundle());

This code should make a transition between the activities where the image moves and resizes from the top left corner of the activity 1 to the bottom right corner of the activity 2. I have tested a similar code loading images from the network and it does not display the animation.

from fresco.

jorgemf avatar jorgemf commented on April 29, 2024

I think this is realted too #99

from fresco.

plamenko avatar plamenko commented on April 29, 2024

I suspect this has to do with attach/detach events that view gets when in transition. We'll have to investigate that.

from fresco.

adnan-SM avatar adnan-SM commented on April 29, 2024

This is something I can confirm as well. Shared Element transitions seem to be broken on Fresco. It would be great if we could get this fixed, as this is a very important feature moving forward.

from fresco.

bamsbamx avatar bamsbamx commented on April 29, 2024

Happened to me too. When setting transtitionName xml attr to SimpleDraweeView, setImageUri() method stopped working

from fresco.

adnan-SM avatar adnan-SM commented on April 29, 2024

Any updates on this ?

from fresco.

goodev avatar goodev commented on April 29, 2024

After the FadeDrawable finished animate real image, there is a log:
com.facebook.samples.comparison D/ViewRootImpl﹕ changeCanvasOpacity: opaque=false

maybe the changeCanvasOpacity cause the image not draw.

from fresco.

shumin0809 avatar shumin0809 commented on April 29, 2024

Is the bug fixed? It's very significant for my project as well. :)

from fresco.

shumin0809 avatar shumin0809 commented on April 29, 2024

@goodev there's not such a method to overwrite.

from fresco.

 avatar commented on April 29, 2024

I am seeing different, but still buggy behaviour with SharedElementTransitions. Don't know if this is the same, related, or separate issue.

_Reproduction_
Pretty standard setup for a SharedElementTransition:

  • RecyclerView in a fragment with GridLayoutManager displaying lots of images as SimpleDraweeViews, setting transitionName on them dynamically in the viewholder bind method (where I am also setting the uri)
  • OnClick fire a transition to a different fragment with a single SimpleDrawee view and the same transitionName also set dynamically

_Expected_
As for normal ImageViews (provided scaleType matches), seamless animation of shared resource between fragments

_Observed_
SharedElementTransition occurs but there is a flicker before the target image appears (seems that the target image isn't set early enough)

_Notes_
I have tried loading images from web and disk, and the image is loaded and in the cache before launching the transition. The target fragment's code is pulling the exact same uri. I fiddled around trying to use the pipeline directly (and learned a lot) but failed to affect the result.

_Setup_
Devices: Nexus 5 & Nexus 7 (2013), both running Android 5.1.1 (API 22)
Up to date library and tools: fresco (0.5.0), Android Studio (1.3 Preview 3 EAP.0), compileSdk (22), build tools (22.0.1)

_Realisations_
While writing this post I've noticed 2 things that might be relevant:

  • The two Drawees are different sizes (this is not a problem for transitioning standard ImageViews and I don't remember anything about pre-fetching that sets the target dimensions)
  • From memory I think I am passing fresco the fragments as Context somewhere in the code, perhaps meaning the two fragments each have their own cache??

from fresco.

 avatar commented on April 29, 2024

@jorgemf - Doesn't your posted code need a matching transitionName attribute set in the Activity 1 layout? https://developer.android.com/training/material/animations.html

_Start an activity with a shared element_
...
4 - Assign a common name to the shared elements in both layouts with the android:transitionName attribute.

For my issue it might just be that I need to postpone the transition. I'll have a look at this today:
http://www.androiddesignpatterns.com/2015/03/activity-postponed-shared-element-transitions-part3b.html

from fresco.

LuizGadao avatar LuizGadao commented on April 29, 2024

I'm with the same problem. I using fresco 0.5.3 and SimpleDraweeView not load image with attr "android:transitionName". Anybody know outher solution using Fresco?

from fresco.

LuizGadao avatar LuizGadao commented on April 29, 2024

@jorgemf If you set "android-background" in your Activity1 Layout.xml, it work not perfectly, but will work.
I set in my test it: android:background="@android:color/transparent"

from fresco.

jorgemf avatar jorgemf commented on April 29, 2024

@LuizGadao If you set a background you lose all the advantages of the library. I think it is pointless as you want it for images downloaded from internet. Not for static resources as a background.
After testing some libraries, picasso is working fine for me. No problems at all.

from fresco.

LuizGadao avatar LuizGadao commented on April 29, 2024

@jorgemf I agree with you. It is only a hack for do it work.

from fresco.

jurenovic avatar jurenovic commented on April 29, 2024

Any news on this one?

from fresco.

derekcsm avatar derekcsm commented on April 29, 2024

@LuizGadao can you post an example of your workaround XML?

from fresco.

 avatar commented on April 29, 2024

Thank you for reporting this issue and appreciate your patience. We've notified the core team for an update on this issue. We're looking for a response within the next 30 days or the issue may be closed.

from fresco.

boxcounter avatar boxcounter commented on April 29, 2024

Any news on this one?

PS:
TranslateDraweeView provided by @goodev does not work correctly on some devices like XiaoMi2, HuaWei P8. ReenterTransition starts at wrong position.

from fresco.

giannign1 avatar giannign1 commented on April 29, 2024

Like as boxcounter said, Tra slateDraweeView doesn't work on HTC One M8, neither

from fresco.

mortyccp avatar mortyccp commented on April 29, 2024

If you are using ChangeImageTransform Transition, then I think the share element transition fails because ChangeImageTransform is animating the ImageView's Matrix which I think its not support by default DraweeView.

from fresco.

JackFan-Z avatar JackFan-Z commented on April 29, 2024

The problem I met is the shared element starts with "fitCenter" while originally it was "centerCrop".
The project can reproduce the issue
https://github.com/JackFan-Z/ActivitySharedElementTransition.git

Though I added a workaround
it doesn't work on my another private project using fresco.
Could someone find out where the real problem is?

Wrong start state of transition
2015-10-01 11 26 34

Before transition
2015-10-01 11 26 50

from fresco.

mortyccp avatar mortyccp commented on April 29, 2024

@JackFan-Z
Share element in transition is setting the final view to the initial values and animate it to the final values.

Normal ImageView combined with ChangeImageTransform will capture the start and end values of the image matrix and then animating the image matrix change.

However DraweeView overrides certain function related to image matrix so the ChangeImageTransform will not have any effect on the image.

So what you end up is only ChangeBounds taking effect.

Currently, I found no way to manipulate the image matrix of DraweeView. Even the setActualImageMatrix has been marked deprecated. Let assume it is not deprecated and it works exact like the default setImageMatrix of default ImageView. Even so It is really not very connivence to animate the change of it due to the fact that you don't have any way to change the matrix after you have set the DraweeViewHierarchy. So you end up need to create a new DraweeViewHierarchy on every onAnimationUpdate call.

I don't know why DraweeView implement in this way. And I am think the current possible solution is to get back the underlying Bitmap and create another ImageView to do the ChangeImageTransformTransition.

from fresco.

JackFan-Z avatar JackFan-Z commented on April 29, 2024

@soapsign
Thanks for your comment.

Actually in my private project, I did try create a dummy ImageView which take the same bitmap as shared element. The problem still exists.
I'm not sure whether the problem I'm facing is related to fresco or not.
But it's for sure that I can reproduce the same problem easily with SimpleDraweeView.

from fresco.

massimocarli avatar massimocarli commented on April 29, 2024

The ChangeImageTransform uses the intrinsic dimensions to determine the transformation matrix. Our implementation of DraweeView uses a DraweeHierarchy which that has intrinsic dimensions equals to -1 for width and height. This is because Drawee already applies correct scale type scaling and hence there is no need for a view to do so. Furthermore, ImageView can only apply one scale type whereas drawable hierarchy can use separate scale types for each image branch (placeholder, failure image, actual image, etc.). Returning actual intrinsic dimensions to the view just puts as on risk of having sizing bugs.
If you want transition working you should use ChangeBounds.

from fresco.

boxcounter avatar boxcounter commented on April 29, 2024

How about add a new option like "fresco:ImageMatrixSrc=actual" ?

from fresco.

massimocarli avatar massimocarli commented on April 29, 2024

@boxcounter At the moment we think what we have now is ok. But you could create a pull request for your proposal :)

from fresco.

tatyana-parnyuk avatar tatyana-parnyuk commented on April 29, 2024

@massimocarli ChangeBounds works well only when shared image has the same size on both activities/views. But when image should be resized during transition, it crops and looks bad.
What you propose to do in such way? ChangeImageTransform resolve this, but it isn't work in DraweeView.

from fresco.

ppamorim avatar ppamorim commented on April 29, 2024

Same here...

from fresco.

pipipzz avatar pipipzz commented on April 29, 2024

Hey Folks, I have the same issue. ChangeBounds is not working smoothly. If there is a workaround or a fix, please tell us. Shared element transition is one of the best things that material design introduced and fresco is one of the finest library that I have used till now. Please let the developers use both seamlessly.

from fresco.

burzumrus avatar burzumrus commented on April 29, 2024

Hi all! In new Fresco release 0.10 with custom ScaleType transform between different ScaleTypes is trivial. Here is my implementation
https://gist.github.com/burzumrus/a589aa7e36ca003ddaf2334218c50ad0

Usage is simple

TransitionSet transitionSet = new TransitionSet();
transitionSet.addTransition(new ChangeBounds());
transitionSet.addTransition(new DraweeTransform(ScalingUtils.ScaleType.CENTER_CROP, ScalingUtils.ScaleType.FIT_CENTER));
getWindow().setSharedElementEnterTransition(transitionSet);

from fresco.

plamenko avatar plamenko commented on April 29, 2024

@burzumrus that's amazing! Thanks for implementing it. That's exactly what I had in mind with InterpolatingScaleType. Consider making a pull-request for Fresco if not done already.

from fresco.

gregkorossy avatar gregkorossy commented on April 29, 2024

Did anyone try these with fragment-to-fragment animations? Because it doesn't seem to work on v0.12.
Edit: is it possible that the RecyclerView causes troubles?
Edit 2: Seems like the problem is that ChangeBounds itself only uses X and Y window coords if the reparenting is set to true. Setting it via ChangeBounds's setReparenting(true) is deprecated and ChangeTransform is recommended instead. So for a RecyclerView, transitionSet.addTransition(new ChangeTransform()); is also required. (The returning animation seems bad still, but at least the entering animation is okay (except that the scale type has no effect changing startValues.view to endValues.view in createAnimator(...) solves this) with this.)

from fresco.

sperochon avatar sperochon commented on April 29, 2024

@Gericop and @ladia12 0.12 works well in my project in fragment-to-fragment animations.
I use it also in RecyclerView.
The thing is that you can only use 'replace' fragment transaction. You can't use 'add' transaction.
If it can help you, here is an example (without fresco) of fragment-to-fragment transition that helped me to start on something that worked (you can downloads the project code on github)
http://www.androidauthority.com/using-shared-element-transitions-activities-fragments-631996/

from fresco.

gregkorossy avatar gregkorossy commented on April 29, 2024

@sperochon I use replace and it's in a RecyclerView but it doesn't work (and honestly, it's surprising that it works for you, maybe you use a different version of RecyclerView? I use v24.1.1). I had to make a few changes in order to make the animations work:

  • added ChangeTransform to the transition set via transitionSet.addTransition(new ChangeTransform());
    • this is due to the fact that the ChangeBounds reports incorrect position of the start view in a RecyclerView (it always returns the first element's X,Y coords)
  • in createAnimator(...) replace if (mFromScale == mToScale) with if(mFromScale == mToScale && startBounds.equals(endBounds))
    • the transform won't happen otherwise if the two drawees share the same scale type, even though their sizes are not the same
  • in createAnimator(...) replace final GenericDraweeView draweeView = (GenericDraweeView) startValues.view; with final GenericDraweeView draweeView = (GenericDraweeView) endValues.view; (mind the startValues -> endValues change)
    • use the end drawee instead of the starting one
  • in AnimatorUpdateListener after the scaleType.setValue(fraction) call, insert the following lines:
Drawable drawable = draweeView.getTopLevelDrawable();

if (drawable != null) {
    drawable.setBounds(0, 0, draweeView.getWidth(), draweeView.getHeight());
}

This last piece of code is based on @aohayou's solution (because I couldn't make CustomDraweeView work).
Tested this on Android 5.0.2 with support lib version v24.1.1.

NOTE that this solution won't work if you animate between images with the same sizes.

from fresco.

gregkorossy avatar gregkorossy commented on April 29, 2024

@sperochon Try it with multiple images.
By the way, I tested your demo with unmodified source. This is the result:

device-2016-08-14-220810_1

This is completely wrong. The end view starts from a different position and the scale type has no effect whatsoever. I don't know how can you say for this that "it works fine" because it clearly doesn't.

from fresco.

sperochon avatar sperochon commented on April 29, 2024

@Gericop I've just updated the code. I forgot to specify a different layout for the end fragment. Try again, please.

from fresco.

gregkorossy avatar gregkorossy commented on April 29, 2024

@sperochon In API 23 emulator, it works fine. On my device (API 21) it doesn't. Also tested it in an API 21 emulator, it doesn't work there either.
So the point is: the current implementation does not work on API 21 (didn't test it on API 22), but works on API 23.

Edit: your demo only tests the default ChangeBounds and ChangeTransform transitions, not the DraweeTransition implementation Facebook supplied.

from fresco.

sperochon avatar sperochon commented on April 29, 2024

Unfortunately, you're right... I've tested it on my devices:
Android 5.0 + Fresco v0.11/v0.12 -> KO
Android 6.0 + Fresco v0.11/v0.12 -> OK
Didn't notice it before...

from fresco.

gregkorossy avatar gregkorossy commented on April 29, 2024

@ladia12 That post has nothing to do with the problem I was (we were) facing... Your blog entry is about inter-Activity transition, while my issue is related to inter-Fragment. Furthermore, the real bug is in how API 21 handles the ChangeBounds and/or ChangeTransform transitions where the Facebook supplied DraweeTransition doesn't help either. My solution, on the other hand, overcomes this, if the source and target images have different dimensions (width and/or height).

from fresco.

sperochon avatar sperochon commented on April 29, 2024

Just for info:
Android 5.0 + Fresco v0.11/v0.12/0.13 -> KO
Android >= 5.1 + Fresco v0.11/0.12/0.13 -> OK

from fresco.

kycqdhl3c avatar kycqdhl3c commented on April 29, 2024

@dbrant I have the same issue, Have you find some way to resolve?

from fresco.

oprisnik avatar oprisnik commented on April 29, 2024

See #1446

from fresco.

bembem1011 avatar bembem1011 commented on April 29, 2024

@ladia12 How did you resolve the issue of the original image disappearing when returning to the first activity? My original image is in recyclerview's viewholder

from fresco.

ladia12 avatar ladia12 commented on April 29, 2024

from fresco.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.