gvaish
gvaish

Reputation: 9414

Android Animation - Flip

I need to create an animation - Flip a view and show another one.

The width of currently shown view is decreased slowly to zero and after that the width of the view-to-be-shown must be increased from zero.

During this time, the height goes from the currently-shown-height to slightly-decreased-height and back again.

How can I achieve this... using a ViewFlipper.

Upvotes: 30

Views: 32016

Answers (4)

Randy
Randy

Reputation: 1146

I know this is an old question, but none of the above worked for me. I did it this way.

For reference, the image I was flipping was a playing card. The front of the card was showing, and I want to flip the card and show the back.

long duration = getResources().getInteger(R.integer.flip_animation_length).toLong()

// cardDisplay was previously defined as an ImageView in this example
// Set animation and start the animation
cardDisplay.animate().rotationY(180f).setDuration(duration).start()

// wait until the animation is half over
Handler().postDelayed({
    // Change the image at the half-way point
    cardDisplay.setImageDrawable(getResources().getDrawabe(R.drawable.card_back))
},duration/2)

So what is this doing? It's flipping the image on the Y axis (horizontally) and changing the image half-way through the flip - when the card is on its side - so that when the other side of the card starts to show, the new image (card back design) starts to appear.

I slowed this down to take 5 seconds (duration = 5000) to make sure that it looks correct all the way through.

Upvotes: 0

s-hunter
s-hunter

Reputation: 25846

Using the scale animation from CaseyB's answer with objectAnimator. If you don't have the animator folder under res, create one, it requires the objectAnimator layout to reside in this animator foler.

res/animator/shrink_to_middle.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <objectAnimator
        android:valueFrom="1.0"
        android:valueTo="0.0"
        android:propertyName="scaleX"
        android:duration="200"/>
</set>

res/animator/grow_from_middle.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <objectAnimator
        android:valueFrom="0.0"
        android:valueTo="1.0"
        android:propertyName="scaleX"
        android:duration="200"
        android:startOffset="200"/>
</set>

The code:

ImageView iv = (ImageView) findViewById(R.id.my_image);
AnimatorSet shrinkSet = (AnimatorSet) AnimatorInflater.loadAnimator(this, R.animator.shrink_to_middle);
shrinkSet.setTarget(iv);
shrinkSet.start();

iv.setImageResource(R.drawable.another_image);

AnimatorSet growSet = (AnimatorSet) AnimatorInflater.loadAnimator(this, R.animator.grow_from_middle);
growSet.setTarget(iv);
growSet.start();

Upvotes: 3

Davideas
Davideas

Reputation: 3276

Just to notify that I've developed a new library FlipView that includes and extends this specific animation (flip) described by CaseyB. I mean a fully customizable library where you will be able to swap any kind of views and layouts with any kind of animation and shapes you desire, included the Gmail image flipping.

Please have a look.

Upvotes: 3

CaseyB
CaseyB

Reputation: 25058

You can do that with ScaleAnimations set on a ViewFlipper. I do a similar thing without the second scale. I have two animations, one for the view going out and one for the view coming in. I'll post them here as a starting point for you.

shrink_to_middle.xml

<set xmlns:android="http://schemas.android.com/apk/res/android">
    <scale
        android:interpolator="@android:anim/linear_interpolator"
        android:fromXScale="1.0"
        android:toXScale="1.0"
        android:fromYScale="1.0"
        android:toYScale="0.0"
        android:fillAfter="false"
        android:duration="200" />
    <translate
        android:fromYDelta="0"
        android:toYDelta="50%"
        android:duration="200"/>
</set>

grow_from_middle.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <scale
        android:interpolator="@android:anim/linear_interpolator"
        android:fromXScale="1.0"
        android:toXScale="1.0"
        android:fromYScale="0.0"
        android:toYScale="1.0"
        android:fillAfter="false"
        android:startOffset="200"
        android:duration="200" />
    <translate
        android:fromYDelta="50%"
        android:toYDelta="0"
        android:startOffset="200"
        android:duration="200"/>
</set>

Then in the app I set them to the ViewFlipper like this:

mViewFlipper.setInAnimation(context, R.anim.grow_from_middle);
mViewFlipper.setOutAnimation(context, R.anim.shrink_to_middle);

Like I said, this is not exactly what you described, but it's pretty close and will get you started.

--EDIT--

Here is the code using the pivotX and pivotY (well, just pivotY in my case):

shrink_to_middle.xml

<?xml version="1.0" encoding="utf-8"?>
<scale
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/linear_interpolator"
    android:fromXScale="1.0"
    android:toXScale="1.0"
    android:fromYScale="1.0"
    android:toYScale="0.0"
    android:pivotY="50%"
    android:fillAfter="false"
    android:duration="200" />

grow_from_middle.xml

<?xml version="1.0" encoding="utf-8"?>
<scale
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/linear_interpolator"
    android:fromXScale="1.0"
    android:toXScale="1.0"
    android:fromYScale="0.0"
    android:toYScale="1.0"
    android:pivotY="50%"
    android:fillAfter="false"
    android:startOffset="200"
    android:duration="200" />

Upvotes: 47

Related Questions