I have two questions, the first being simply: What is the easiest manner in which to add a custom flipping animation to an AdapterViewFlipper (where more than one property must be changed sequentially), preferably the solution using values defined in XML.
In the second question I'm asking clarification on a very odd behavior that I will first explain.
I've spent several days now messing around with animations trying to animate an AdapterViewFlipper as described above, mostly as a learning exercise. I have found that the methods available (inherited from AdapterViewAnimator are setInAnimatior() and setOutAnimatior(), both receive an ObjectAnimator parameter. ObjectAnimator as I understand (wrongly maybe?) to only be able to animate one Property per XML tag or Java instantiation, (sometimes an x and y Property simultaneously). The documentation shows that typically ObjectAnimators are grouped into AnimatorSet objects which can be created cleanly in XML, my problem is getting these AnimatorSet objects to animate the view transition. I was nearly to the point of creating an extension of AdapterViewFlipper to try to solve this when something weird happened.
To explain, below is one of my original attempts to animate the flipping (I've simplified the code to a single flipping direction, the opposite direction is similar only differing in the XML "valueFrom" and "valueTo" values):
...
AnimatorSet inLeftSet;
AnimatorSet outLeftSet;
@Override // This is in a fragment
public View onCreateView(...) {
...
inLeftSet = (AnimatorSet) AnimatorInflater.loadAnimator(
this.getContext(),
R.animator.card_flip_left_in);
outLeftSet = (AnimatorSet) AnimatorInflater.loadAnimator(
this.getContext(),
R.animator.card_flip_left_out);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
...
case (R.id.next_image):
outRightSet.setTarget(flipper.getCurrentView());
flipper.showNext();
inRightSet.setTarget(flipper.getCurrentView());
outRightSet.start();
inRightSet.start();
break;
...
}
And the corresponding XML files are:
card_flip_right_in.xml
<set xmlns:android="http://schemas.android.com/apk/res/android">
<objectAnimator
android:duration="0"
android:propertyName="alpha"
android:valueFrom="1.0"
android:valueTo="0.0"/>
<objectAnimator
android:duration="@integer/card_flip_time_full"
android:interpolator="@android:interpolator/accelerate_decelerate"
android:propertyName="rotationY"
android:valueFrom="180"
android:valueTo="
<objectAnimator
android:duration="1"
android:propertyName="alpha"
android:startOffset="@integer/card_flip_time_half"
android:valueFrom="0.0"
android:valueTo="1.0"/>
</set>
card_flip_right_out.xml
<set xmlns:android="http://schemas.android.com/apk/res/android">
<objectAnimator
android:duration="@integer/card_flip_time_full"
android:interpolator="@android:interpolator/accelerate_decelerate"
android:propertyName="rotationY"
android:valueFrom="0"
android:valueTo="-180"/>
<objectAnimator
android:duration="1"
android:propertyName="alpha"
android:startOffset="@integer/card_flip_time_half"
android:valueFrom="1.0"
android:valueTo="0.0"/>
</set>
This did not produce the desired result (example of the desired animation can be viewed from this Tutorial). Rather the initial ImageView spun completely around before flickering and finally displaying the next ImageView suddenly and without animation.
Here comes the weird part, I created this next snippet inside the onClick() for rotating right (next image), and it completely didn't work the ImageView just flashed to the next with no animation, BUT, when I accidentally clicked previous image (which has the same code as above) it animated perfectly!?!?
Iterator<Animator> iterator = outRightSet.getChildAnimations().iterator();
while (iterator.hasNext()) {
flipper.setOutAnimation((ObjectAnimator) iterator.next());
iterator.remove();
}
iterator = inRightSet.getChildAnimations().iterator();
while (iterator.hasNext()) {
flipper.setInAnimation((ObjectAnimator) iterator.next());
iterator.remove();
}
There was originally more code as it was a test, but through trial and error I nailed down the part of the code that makes it work to the above snippet. What is stranger than anything is that I moved this out of the onClick() to the onCreateView() Override, right after the AnimatorSet objects are inflated and it still worked. Needing to only execute once for all animations to work as intended in both directions, rotating left and rotating right.
Though I'm thrilled that it works, I'm bothered that it works, because I don't know why that it works. My original intention with the test code was to try to pass each ObjectAnimator from the AnimatorSet individually to the AdapterViewFlipper through setOutAnimation() and setInAnimation() methods, a test that I wasn't sure would do anything (I was having a hard time finding adequate usage explanations in the documentation) and now I would really like to understand what is going on, and if there is a simpler, more proper, or easier-for-others-who-may-need-to-work-on-my-code way to achieve this same result.
Thanks in advance for any help.