Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Shared element transition #22

Closed
jorgemf opened this issue Mar 28, 2015 · 57 comments
Closed

Shared element transition #22

jorgemf opened this issue Mar 28, 2015 · 57 comments

Comments

@jorgemf
Copy link

jorgemf commented Mar 28, 2015

Shared element transition doesn't seem to work.

Tested in a motorola device with android 5.0

@tyronen tyronen added the bug label Apr 7, 2015
@tyronen
Copy link
Contributor

tyronen commented Apr 7, 2015

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

@jorgemf
Copy link
Author

jorgemf commented Apr 7, 2015

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.

@jorgemf
Copy link
Author

jorgemf commented Apr 7, 2015

I think this is realted too #99

@plamenko
Copy link
Contributor

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

@adnan-SM
Copy link

adnan-SM commented May 8, 2015

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.

@bamsbamx
Copy link

bamsbamx commented May 9, 2015

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

@adnan-SM
Copy link

Any updates on this ?

@goodev
Copy link

goodev commented May 27, 2015

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.

@shumin0809
Copy link

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

@goodev
Copy link

goodev commented Jun 5, 2015

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

}

@shumin0809
Copy link

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

@goodev
Copy link

goodev commented Jun 12, 2015

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

@ghost
Copy link

ghost commented Jun 13, 2015

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

@ghost
Copy link

ghost commented Jun 14, 2015

@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

@LuizGadao
Copy link

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?

@LuizGadao
Copy link

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

@jorgemf
Copy link
Author

jorgemf commented Jul 7, 2015

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

@LuizGadao
Copy link

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

@jurenovic
Copy link

Any news on this one?

@derekcsm
Copy link

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

@ghost
Copy link

ghost commented Aug 5, 2015

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.

@boxcounter
Copy link

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.

@giannign1
Copy link

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

@mortyccp
Copy link

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.

@plamenko
Copy link
Contributor

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

ghost pushed a commit that referenced this issue May 20, 2016
Summary:
As mentioned in #22 ChangeImageTransform for DraweeViews is not working correctly, when ScaleType is changing during transition. This pull request resolve this issue by added custom DraweeTransition, which animates ScaleType transition correctly

InterpolatingScaleType is changed by adding start and end values of parentBounds. In pervious version it used parameter parentBounds, which changing every animation frame and it caused wrong animation behaviour.

Transition sample is changed due to use DraweeTransition. Also background was added in sample image, to show how animation works
Closes #1225

Reviewed By: plamenko

Differential Revision: D3322074

Pulled By: kirwan

fbshipit-source-id: 1da6aee40b2e15d39bfc699e41488905fa2a08c0
@ladia12
Copy link

ladia12 commented Jul 23, 2016

@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

@gregkorossy
Copy link

gregkorossy commented Aug 13, 2016

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

@sperochon
Copy link

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

@gregkorossy
Copy link

gregkorossy commented Aug 14, 2016

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

@sperochon
Copy link

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

@gregkorossy
Copy link

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

@sperochon
Copy link

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

@gregkorossy
Copy link

gregkorossy commented Aug 14, 2016

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

@sperochon
Copy link

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

@ladia12
Copy link

ladia12 commented Aug 16, 2016

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

@gregkorossy
Copy link

@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).

@sperochon
Copy link

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

@dbrant
Copy link

dbrant commented Jul 13, 2017

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

@kycqdhl3c
Copy link

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

@oprisnik
Copy link
Contributor

See #1446

@ZakAnun
Copy link

ZakAnun commented Oct 8, 2018

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

@bembem1011
Copy link

@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

@ladia12
Copy link

ladia12 commented Jun 21, 2019 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests