htafoya
htafoya

Reputation: 19283

Android shared element transition animation

I'm using shared element transitions to persist my view throughout activities. I would like the view to perform some animation (f.e. a flip card) while the activities are being changed.

In other words, to perform an additional animation other than the basic shared transitions (move, scale)

Is this possible?

Upvotes: 0

Views: 214

Answers (1)

htafoya
htafoya

Reputation: 19283

It can be done with a Custom transition, for example for the flip it could be done with the following: (used for an ImageView which changed views within activities, using transitionDrawable as the src)

import android.animation.Animator
import android.animation.AnimatorListenerAdapter
import android.animation.AnimatorSet
import android.animation.ObjectAnimator
import android.content.Context
import android.graphics.drawable.TransitionDrawable
import android.transition.Transition
import android.transition.TransitionValues
import android.util.AttributeSet
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView

class FlipTransition(ctx: Context, atts: AttributeSet): Transition(ctx, atts) {

    private val PROPNAME_DRAWABLE = "FlipTransition:drawable"

    private fun captureValues(transitionValues: TransitionValues) {
        val view = transitionValues.view
        if (view !is ImageView || view.getVisibility() != View.VISIBLE) {
            return
        }
        transitionValues.values[PROPNAME_DRAWABLE] = view.drawable
    }

    override fun captureStartValues(transitionValues: TransitionValues) {
       captureValues(transitionValues)
    }

    override fun captureEndValues(transitionValues: TransitionValues) {
        captureValues(transitionValues)
    }

    override fun createAnimator(
        sceneRoot: ViewGroup,
        startValues: TransitionValues?,
        endValues: TransitionValues?
    ): Animator? {

        if (startValues != null && endValues != null && endValues.view is ImageView) {
            val endView:ImageView = endValues.view as ImageView
            val startView:ImageView = startValues.view as ImageView

            val startAnim = ObjectAnimator.ofFloat(startView, "rotationY", 0F, 90F )
            startAnim.addListener(object: AnimatorListenerAdapter() {
                override fun onAnimationEnd(animation: Animator?) {
                    startView.rotationY = 0F
                    (startView.drawable as TransitionDrawable).startTransition(300)
                }
            })

            val endAnim = ObjectAnimator.ofFloat(endView, "rotationY", 270F, 360F )
            endAnim.addListener(object: AnimatorListenerAdapter() {
                override fun onAnimationEnd(animation: Animator?) {
                    (startView.drawable as TransitionDrawable).reverseTransition(300)
                }
            })

            return AnimatorSet().apply {
                play(startAnim).before(endAnim)
            };
        }

        return null
    }


}

Upvotes: 0

Related Questions