Raymond Chenon Raymond Chenon - 4 months ago 14
Android Question

Why Fade transition doesn't work on Shared Element

I have 2 Activities , the Shared Element transition works fine.ChangeBounds is the only the transition applied.

I want to apply a fade transition while the shared element moves, so the ordering is ORDERING_TOGETHER.

public class TransitionUtils {

public static Transition makeSharedElementEnterTransition(final Context context, final long duration) {
TransitionSet set = new TransitionSet();
set.setOrdering(TransitionSet.ORDERING_TOGETHER);
set.setDuration(duration);

Transition changeBounds = new ChangeBounds();
changeBounds.addTarget(context.getString(R.string.transition_name_search_text));
set.addTransition(changeBounds);

Transition fade = new Fade(Fade.OUT);
fade.addTarget(context.getString(R.string.transition_name_search_text));
set.addTransition(fade);

return set;
}

}


The startActivity calls ActivityOptions.makeSceneTransitionAnimation

In the EndActivity , the enter shared element transition is set

public class EndActivity extends Activity{
@Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.blabla);
getWindow().setSharedElementEnterTransition(TransitionUtils.makeSharedElementReEnterTransition(this,2000));
}
}


Notes : I noticed that


  • Fade() is often applied to getWindow().setEnterTransition()

  • setting a
    duration to TransitionSet applies to all Transistions contained
    except Fade.



How to apply a Fade Transition to a sharedElement ?
What am I doing wrong ?

Answer

android.transition.Fade uses TransitionAlpha , which cannot be resolved in my IDE. android.transition.Fade works for enter and exit transition between activities.

So I created my own Fade to use Alpha. An Android view's opacity is set by alpha. And shared element uses View.

You call it like this :

Transition fadeOut = new FadeTransition(1f, 0f, new LinearInterpolator());
fadeOut.addTarget(transitionName);

The full code is here

@TargetApi(21)
public class FadeTransition extends Transition {

    private static final String PROPNAME_BACKGROUND = "android:faderay:background";
    private static final String PROPNAME_TEXT_COLOR = "android:faderay:textColor";
    private static final String PROPNAME_ALPHA = "android:faderay:alpha";

    private float startAlpha;
    private float endAlpha;
    private TimeInterpolator timeInterpolator;

    public FadeTransition(final float startAlpha, final float endAlpha, final TimeInterpolator timeInterpolator) {
        this.startAlpha = startAlpha;
        this.endAlpha = endAlpha;
        this.timeInterpolator = timeInterpolator;
    }

    public FadeTransition(final Context context, final AttributeSet attrs) {
        super(context, attrs);
    }

    private void captureValues(final TransitionValues transitionValues) {
        transitionValues.values.put(PROPNAME_BACKGROUND, transitionValues.view.getBackground());
        transitionValues.values.put(PROPNAME_ALPHA, transitionValues.view.getAlpha());
        if (transitionValues.view instanceof TextView) {
            transitionValues.values.put(PROPNAME_TEXT_COLOR, ((TextView) transitionValues.view).getCurrentTextColor());
        }
    }

    @Override
    public void captureStartValues(final TransitionValues transitionValues) {
        captureValues(transitionValues);
    }

    @Override
    public void captureEndValues(final TransitionValues transitionValues) {
        captureValues(transitionValues);
    }

    @SuppressLint("NewApi")
    @Override
    public Animator createAnimator(final ViewGroup sceneRoot, final TransitionValues startValues,
            final TransitionValues endValues) {

        TextView textView = (TextView) endValues.view;

        if (startAlpha != endAlpha) {
            textView.setAlpha(endAlpha);
        }

        ObjectAnimator fade = ObjectAnimator.ofFloat(textView, View.ALPHA, startAlpha, endAlpha);
        fade.setInterpolator(timeInterpolator);
        return fade;
    }
}