Android Animation - Flip

2019-01-16 04:08发布

问题:

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.

回答1:

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


回答2:

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.



回答3:

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