我在Android应用程序中使用过ObjectAnimator.ofFloat,但并不是在每个设备上都以相同的方式工作。
MainActivity(扩展活动):
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();
}
三星Galaxy S4(Android 4.4.2):
getInterpolation() 1,0000
getInterpolation() 1,0000
三星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
有人有一个主意,为什么这不能正常工作?
在Galaxy S4的开发人员选项下,有选项动画持续时间比例。出于某种疯狂的原因,默认情况下为off。将其切换为1x后,我在S4上的动画开始正常工作。这可能是导致您出现问题的原因。
用户可以在开发人员选项或自定义ROM提供程序中轻松操纵比例值。如果您首先不知道是什么原因造成的,那么这可能是一个非常棘手的问题。
解决方案>>
您可以通过反射API的功能以编程方式将动画时长比例设置为1或任何其他令人愉悦的值。因此,对于您的应用,这在所有Android设备上的行为都相同。不幸的是,Android并未在其页面上向我们发出警告,而是提供了解决方案选择而不是反射,这是因为该函数本身受到@hide
注释的限制而无法公开使用。
有关Android API限制的更多信息,您可以阅读此主题;
What does @hide mean in the Android source code?
使用Java
try { ValueAnimator.class.getMethod("setDurationScale", float.class).invoke(null, 1f); } catch (Throwable t) { Log.e(TAG, t.getMessage()); }
在科特林
// 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)
我相信,此解决方案比让用户在开发人员设置中进行设置更可靠,更可靠。