Reputation: 15740
I'm trying to build an animation where this image:
Becomes this image:
Where the three bars fade in like 1...2...3... then back to none. At this point the animation will repeat. Here is what I tried to make work:
AlphaAnimation anim = (AlphaAnimation) AnimationUtils.loadAnimation(this, R.anim.fade_in);
anim.setRepeatMode(Animation.RESTART);
anim.setRepeatCount(Animation.INFINITE);
anim.setStartOffset(3000);
LayoutAnimationController controller = new LayoutAnimationController(anim, 0.5f);
rl.setLayoutAnimation(controller);
rl.startLayoutAnimation();
This almost works, but the problem is that the first child in the view group of those wifi bars doesn't wait for the last child to complete its animation before it goes off. The result is a beat that looks like 1...2...3..1..2.3...1...3...1..2.3 instead of a nice 1..2..3..1..2..3. I need to find a way to make the controller wait until the cycle is completed before setting the 1st child off again. I haven't been able to find any solutions on this, does anyone have some input? I'm open to changing the way I'm doing this altogether, this LayoutAnimationController class just seemed to be the best way up until this point.
Thanks!
Upvotes: 4
Views: 1829
Reputation: 14571
When I had to use an animation for a image, I prepared the frames. I used AnimatioDrawable with this class:
* This class is a hack to simply get an on finish callback for an
* AnimationDrawable.
*
*/
public class CustomAnimationDrawable extends AnimationDrawable {
// We need to keep our own frame count because mCurFrame in AnimationDrawable is private
private int mCurFrameHack = -1;
// This is the Runnable that we will call when the animation finishes
private Runnable mCallback = null;
/*
* We override the run method in order to increment the frame count the same
* way the AnimationDrawable class does. Also, when we are on the last frame we
* schedule our callback to be called after the duration of the last frame.
*/
@Override
public void run() {
super.run();
mCurFrameHack += 1;
if (mCurFrameHack == (getNumberOfFrames() - 1) && mCallback != null) {
scheduleSelf(mCallback, SystemClock.uptimeMillis() + getDuration(mCurFrameHack));
}
}
/*
* We override this method simply to reset the frame count just as is done in
* AnimationDrawable.
*/
@Override
public void unscheduleSelf(Runnable what) {
// TODO Auto-generated method stub
super.unscheduleSelf(what);
mCurFrameHack = -1;
}
public void setOnFinishCallback(Runnable callback) {
mCallback = callback;
}
public Runnable getOnFinishCallback() {
return mCallback;
}
}
And in my code I use it like:
CustomAnimationDrawable staticAnimation = new CustomAnimationDrawable();
//add frames with resources and duration. step is just a class of mine
staticAnimation.addFrame(getResources().getDrawable(step.getStepImageResId()), step.getStepDuration());
staticAnimation.addFrame(getResources().getDrawable(step.getStepImageResId()), step.getStepDuration());
staticAnimation.addFrame(getResources().getDrawable(step.getStepImageResId()), step.getStepDuration());
staticAnimation.setOneShot(false);
imgView.setBackgroundDrawable(staticAnimation);
staticAnimation.start();
Probably not the best solution out there, but it worked for my needs.
Upvotes: 2