0

I'm trying to chain two View Animations of the same type, in this case alpha. Initially, I want my View to fade-out while translating left, then after this has completed the View should fade back in at the center of the screen.

I can get the animation to slide and fade to the left without issue, however, when I attempt to add a fade-in animation afterwards, no animation occurs, the alpha just abruptly changes to 0.2. I have tried playing with fillAfter and fillBefore but these don't seem to make a difference. I understand that View Animation has no impact on the actual properties of the View. Here is my code so far:

<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:fillBefore="false"
    android:fillEnabled="true"
    android:shareInterpolator="false">

    <translate
        android:duration="450"
        android:fromXDelta="0%p"
        android:toXDelta="-100%p" />

    <alpha
        android:duration="450"
        android:fromAlpha="1.0"
        android:toAlpha="0.2" />

    <alpha
        android:duration="450"
        android:fromAlpha="0.2"
        android:toAlpha="1.0"
        android:startOffset="450" />
</set>

I know I could probably achieve the desired effect using Animation Listeners, however, an XML only solution would be more elegant in my opinion.

Blake Mumford
  • 17,201
  • 12
  • 49
  • 67

2 Answers2

4

in android fillAfter and fillBefore are kind of tricky. let's try to follow their logic:

fillAfter = apply the changes AFTER the animation occurs

ok, that's wa easy... but what excactly is fillBefore?

fillBefore = apply some animation values BEFORE animation starts

so in your sample, remove fillBefore from your set and make one of the following changes:

    <!-- fillAfter = true -->
    <!-- after animation complete don't change opacity back to 1.. let it remain 0.2  -->
    <alpha
    android:duration="450"
    android:fillAfter="true"  
    android:fromAlpha="1.0"
    android:toAlpha="0.2" />

    <!-- fillBefore = true -->
    <!-- before animation starts set alpha to 0.2  -->
    <alpha
    android:duration="450"
    android:fillBefore="true"
    android:fromAlpha="0.2"
    android:toAlpha="1.0"
    android:startOffset="450" />

you don't need both - it just to show the meaning of those commands in your case

EDIT: just to prove that this can be done :)

<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:fillEnabled="true"
    android:shareInterpolator="true" >

    <translate
        android:duration="450"
        android:fillAfter="false"
        android:fillEnabled="true"
        android:fromXDelta="0%p"
        android:toXDelta="-100%p" />

    <alpha
        android:duration="450"
        android:fillAfter="false"
        android:fillEnabled="true"
        android:fromAlpha="1.0"
        android:toAlpha="0" />

    <alpha
        android:duration="450"
        android:fillAfter="true"
        android:fillBefore="false"
        android:fromAlpha="0.2"
        android:startOffset="450"
        android:toAlpha="1.0" />

</set>
ymz
  • 6,602
  • 1
  • 20
  • 39
  • Thanks for your answer. I tried both of those options, neither of them worked unfortunately. Same result, opacity jumps to 0.2 immediately. Translate works fine. No alpha animation, neither fade-out nor fade-in. – Blake Mumford Nov 28 '14 at 01:48
  • in the "worst" case you can split your animation into 2 different files and make the timing of those parts with **AnimationListener**: http://stackoverflow.com/questions/7609974/android-animation-listener – ymz Nov 28 '14 at 01:56
  • Yeah I know, as I said in my question, I'd prefer an XML only solution as this would be the most elegant. I can't seen any reason why this would not be possible either. – Blake Mumford Nov 28 '14 at 01:57
0

ymz's answer got my 90% of the way there, howevere there were two changes I had to make in order to get the desired effect. The main problem was that the first fade-out animation was skipped, to fix this make the following changes:

  1. Remove the fillEnabled="true" attribute from the AnimationSet. I don't know why, but if this attribute is set to true on the Set rather than its children then the first alpha (fade-out) animation won't work. It will simply skip to the value of the fromAlpha on the second alpha animation (fade-in).
  2. Add the fillEnabled=true attribute to the second (fade-in) alpha animation. This is because we need fillBefore to be set to false (as per the docs fillBefore will be ignored unless fillEnabled is set to true).

The final solution looks like this:

<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:shareInterpolator="false">

    <translate
        android:duration="800"
        android:fillAfter="false"
        android:fillEnabled="true"
        android:fromXDelta="0%p"
        android:toXDelta="-100%p"
        android:startOffset="0"/>

    <alpha
        android:duration="800"
        android:fillAfter="false"
        android:fillEnabled="true"
        android:fromAlpha="1"
        android:toAlpha="0"
        android:startOffset="0"/>

    <alpha
        android:duration="800"
        android:fillAfter="true"
        android:fillEnabled="true"
        android:fillBefore="false"
        android:fromAlpha="0.1"
        android:startOffset="800"
        android:toAlpha="1.0" />
</set>
Community
  • 1
  • 1
Blake Mumford
  • 17,201
  • 12
  • 49
  • 67