I have a few buttons in an Android app of mine, "Start", "Stop", and "Pause". When Start is pressed is becomes disabled and Stop and Pause become enabled. Similarly, when Stop or Pause is pressed, Start becomes enabled again. When these buttons change state, I would like to animate the change with a bouncing animation to visually indicate to the user that the button is now available. The problem is that the animation is actually changing the buttons size(background). Check out this gif to see what I mean (watch the Stop button):
Here is the code for the animation:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:interpolator="@android:anim/linear_interpolator">
<scale
android:fromXScale="1.0"
android:toXScale="1.1"
android:fromYScale="1.0"
android:toYScale="1.1"
android:pivotX="50%"
android:pivotY="50%"
android:duration="200"
android:repeatCount="0"
android:repeatMode="reverse" />
</set>
And how I'm applying it to the buttons:
Animation scaleAnimation = AnimationUtils.loadAnimation(this, R.anim.scale_button);
startButton.startAnimation(scaleAnimation);
stopButton.startAnimation(scaleAnimation);
Why is the Stop button size changing and how can I keep it from doing this?
Thanks!
Note: I originally set the "repeatCount" of the animation to 1 so that it would scale the button back down. I changed it to 0 to debug this problem but the same thing is still happening.
I'd refrain from using Animation
. You have to play with fillEnabled
, fillAfter
, fillBefore
flags, it's not convenient and non-intuitive API to use.
Instead, prefer Animator
s API.
The animation you'd like to implement will look something like this:
val scaleX = ObjectAnimator.ofFloat(view, View.SCALE_X, 1.0f, 1.1f).setDuration(200)
val scaleY = ObjectAnimator.ofFloat(view, View.SCALE_Y, 1.0f, 1.1f).setDuration(200)
val downscaleX = ObjectAnimator.ofFloat(view, View.SCALE_X, 1.1f, 1.0f).setDuration(200)
val downscaleY = ObjectAnimator.ofFloat(view, View.SCALE_Y, 1.1f, 1.0f).setDuration(200)
val set = AnimatorSet()
set.playTogether(scaleX, scaleY)
set.play(downscaleX).after(scaleX)
set.playTogether(downscaleX, downscaleY)
set.start()
Or, you can play with fluent API:
view.animate()
.scaleXBy(0.1f)
.scaleYBy(0.1f)
.setDuration(200)
.withEndAction {
view.animate()
.scaleXBy(-0.1f)
.scaleYBy(-0.1f)
.duration = 200
}