custom repeating of translation animation in android
I'm doing animation of spinning with different images (like horizontal roulette) one image at a time from left to right over the screen.
At every animation cycle I need to change image to random from the list, so I found if I use repeating animation then setting new ImageResource on onAnimationRepeat of AnimationListener doesn't update my ImageView. I've decided to use custom triggering of next animation from onAnimationEnd. Here a pice of code:
ImageView image = (ImageView)(ImageView)findViewById(R.id.imageId);
Animation aMid = AnimationUtils.loadAnimation(this, R.anim.plant_middle);
aMid.setFillEnabled(true);
aMid.setFillAfter(true);
aMid.setAnimationListener(new AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
setRandomImageResource();
}
@Override
public void onAnimationRepeat(Animation animation) { }
@Override
public void onAnimationEnd(Animation animation) {
if(customCounter < SPIN_COUNT){
customCounter++;
im开发者_如何学Cage.startAnimation(aMid);
}
}
});
And Animation ixm is pretty simple, it's about ImageView comes from left of the screen to it's right:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:shareInterpolator="true">
<translate
android:interpolator="@android:anim/linear_interpolator"
android:fromXDelta="-100%"
android:toXDelta="100%"
android:fromYDelta="0%"
android:toYDelta="0%"
android:duration="4000" />
</set>
The problem is in that between every animation cycle ImageView appears in the center of the screen for a very short moment, like it is flying from right back to left to start next animation cycle, or like it flickers in the middle where it's initially positioned in layout xml.
Setting it's visibility to GONE on onAnimationEnd and VISIBLE on onAnimationEnd doesn't work our the problem.
What do?
I used your code for my application and I'll tell you how I decide this problem.
First of all when you create an ImageView
tag into the XML file you must not set a source for it like that:
<ImageView android:id="@+id/cloud_image"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:layout_alignParentTop="true"
android:layout_marginTop="20dip"
android:adjustViewBounds="false"
android:scaleType="fitXY" />
After that you must set the ImageView
source into onAnimationStart()
function and must set empty image (empty and 100% transparent image) source into onAnimationEnd()
function:
// == Animation listener ====================================================
mCloudsAnimation.setAnimationListener(new AnimationListener() {
public void onAnimationStart(Animation animation) {
mCloudsImage.setBackgroundResource(R.drawable.clouds);
}
public void onAnimationRepeat(Animation animation) {
}
public void onAnimationEnd(Animation animation) {
mCloudsImage.setBackgroundResource(R.drawable.clear_sky);
mCloudsImage.startAnimation(mCloudsAnimation);
}
});
It works on the emulator. Now I'm going to try it on my device.
I managed to achieve needed by setting layout margin left to -1000 and back on onAnimationEnd/onAnimationStart instead of doing visibility. However solution is ugly.
Add "setFillAfter(true)" to the AnimationSet too (not only to the animation) It worked for me.
精彩评论