Android animation startOffset broken or buggy?

By : Andy
Source: Stackoverflow.com
Question!

I've taken some animation xml straight from the android docs, and as far as I can see, doesn't work on either my 2.1 update 1 emulator or my 2.1 update 1 Galaxy S device.

Specifically, I'm trying to create an animation to pulsate a view (i.e. make it smaller then larger in one animation) This is the very simple markup:

<?xml version="1.0" encoding="utf-8"?> 
<set 
        xmlns:android="http://schemas.android.com/apk/res/android"> 
        <scale 
                android:fromXScale="1.0" 
                android:toXScale="0.5" 
                android:fromYScale="1.0" 
                android:toYScale="0.5" 
                android:pivotX="50%" 
                android:pivotY="50%" 
                android:duration="1000" /> 
                <set android:startOffset="1000"> 
                        <scale 
                        android:fromXScale="0.5" 
                        android:toXScale="1.0" 
                        android:fromYScale="0.5" 
                        android:toYScale="1.0" 
                        android:pivotX="50%" 
                        android:pivotY="50%" 
                        android:duration="1000" /> 
                </set> 
</set> 

So what I'm trying to achieve is to reduce the view from its size to half of it over a second, then to increase it back to its original size over a second. So to re-iterate, over two seconds it should go from original -> half size -> original.

What actually happens is it snaps instantly to half of the views size (even though fromX/YScale is at 1.0) and then performs the animation over two seconds and snaps back to original size afterwards.

Can anyone else try this out quickly? If others see this behaviour I'll submit it as a bug. I just can't believe something so basic could be broken!?

Also, copying this animation under the "Tween Animation" heading on this page http://developer.android.com/guide/topics/graphics/2d-graphics.html word for word also doesn't animate as per the page says. Seems to be broken in exactly the same way!

Anyone got any ideas?

Thanks!

Andy.

By : Andy


Answers
I removed the second <set> tag, so there's only one <set> with two <scale> children. This got one cycle working ok but it failed to repeat. Maybe you have to listen for the animation ending and manually restart it (so the offsets start from 0 each time).

On the bright side I was able to use repeatMode to achieve the effect you seem to want, using just one tag:

<scale xmlns:android="http://schemas.android.com/apk/res/android" 
        android:repeatMode="reverse"
        android:fromXScale="1.0" 
        android:toXScale="0.5" 
        android:fromYScale="1.0" 
        android:toYScale="0.5" 
        android:pivotX="50%" 
        android:pivotY="50%" 
        android:duration="1000" />


Something that I've recently discovered and is partially responsible for the undesired behavior of your animation is the fact that many XML attributes used in the <set> tag do not work!

In your code example you have <set android:startOffset="1000">

Because of a ridiculous bug/defect, Android will ignore this attribute which will cause your second child <set> of animations to start concurrently with your parent <set>

What makes this even more frustrating is that this attribute works programatically in code, setStartOffset() but not in XML.

I spent a few frustrating hours figuring out which attributes work in code and XML for AnimationSets and submitted a bug report/issue here: Issue 17662

In summary:

setRepeatCount() / android:repeatCount

This attribute (as well as repeatMode) does not work in code or XML. This makes repeating an entire set of animations difficult.

setDuration() / android:duration

Setting this on an AnimationSet in code WORKS (overrides all durations of children animations), but not when included in the tag in XML

setFillAfter() / android:fillAfter

This works in both code and XML for the tag. Strangely I have gotten it to also work without the need to set fillEnabled to true.

setFillBefore() / android:fillBefore

Seems to have no effect/ignored in both code and XML

setFillEnabled() / android:fillEnabled

Seems to have no effect/ignored in both code and XML. I can still get fillAfter to work even without including fillEnabled or setting fillEnabled to false.

setStartOffset() / android:startOffset

This works only in code and not XML.

Needless to say this causes a lot of unnecessary frustration.

By : Tony Chan


Try the following codes. What's missing is repeatMode = "-1" in previous answer. Then you'll see the image pulsating indefinitely without using listener.

In res/anim/pulsate.xml:

<?xml version="1.0" encoding="utf-8"?><set xmlns:android="http://schemas.android.com/apk/res/android" >
<scale
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1000"
    android:fromXScale="0.5"
    android:fromYScale="0.5"
    android:pivotX="50%"
    android:pivotY="50%"
    android:repeatMode="reverse"
    android:repeatCount="-1"
    android:toXScale="1.0"
    android:toYScale="1.0" />

In java file:

Animation animPulsate = AnimationUtils.loadAnimation(JoinRecipeClubActivity.this, R.anim.pulsate);
ImageView ivFinger = (ImageView) findViewById(R.id.wivFinger);
ivFinger.startAnimation(animPulsate);


This video can help you solving your question :)
By: admin