I've used ObjectAnimator.ofFloat in an Android App which doesn't work on every device the same way.
MainActivity (extends Activity):
Button button1 = (Button) findViewById(R.id.button1);
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startAnimation();
}
});
public void startAnimation() {
ImageView aniView = (ImageView) findViewById(R.id.imageView1);
ObjectAnimator fadeOut = ObjectAnimator.ofFloat(aniView, "alpha", 0f);
fadeOut.setDuration(2000);
ObjectAnimator mover = ObjectAnimator.ofFloat(aniView, "translationX", -500f, 0f);
mover.setInterpolator(new TimeInterpolator() {
@Override
public float getInterpolation(float input) {
Log.v("MainActivity", "getInterpolation() " + String.format("%.4f", input));
return input;
}
});
mover.setDuration(2000);
ObjectAnimator fadeIn = ObjectAnimator.ofFloat(aniView, "alpha", 0f, 1f);
fadeIn.setDuration(2000);
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.play(mover).with(fadeIn).after(fadeOut);
animatorSet.start();
}
Samsung Galaxy S4 (Android 4.4.2):
getInterpolation() 1,0000
getInterpolation() 1,0000
Samsung Galaxy S5 (Android 4.4.2):
getInterpolation() 0,0000
getInterpolation() 0,0000
getInterpolation() 0,0085
getInterpolation() 0,0170
getInterpolation() 0,0255
...
...
getInterpolation() 0,9740
getInterpolation() 0,9825
getInterpolation() 0,9910
getInterpolation() 0,9995
getInterpolation() 1,0000
Has anyone an idea, why this doesn't work properly?
Users can easily manipulate the scale value in Developer options or custom ROM providers. This could be a very tricky problem if you don't know what caused it in the first place.
Solution
You can just set an animation duration scale to 1 or any other pleasing value programmatically via Reflection API's capability. Thus, this will behave the same all across Android devices for your app.
Unfortunately, Android is not giving us a warning about it on its page and a solution choice rather than Reflection due to the function itself is restricted from public usage via @hide
annotation.
For more about Android's API restriction, You could read this thread;
What does @hide mean in the Android source code?
In Java
try {
ValueAnimator.class.getMethod("setDurationScale", float.class).invoke(null, 1f);
} catch (Throwable t) {
Log.e(TAG, t.getMessage());
}
In Kotlin
// You could also surround this line with try-catch block like above in Java example
ValueAnimator::class.java.getMethod("setDurationScale", Float::class.javaPrimitiveType).invoke(null, 1f)
I believe, this solution is more solid and robust rather than making users set it in developer settings.
On the Galaxy S4, under Developer Options, there is the option Animator duration scale. For some wild reason, this is off by default. After switching this to 1x, my animations on the S4 started to work perfectly. This may be what is causing your problem.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With