我在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
有谁有想法,为什么这不能正常工作?
答案 0 :(得分:20)
在Galaxy S4上,在开发者选项下,有 Animator持续时间刻度选项。出于某些原因,默认情况下 off 。将此切换为 1x 后,我在S4上的动画开始完美运行。这可能是造成问题的原因。
答案 1 :(得分:0)
用户可以在开发人员选项或自定义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)
我相信,此解决方案比让用户在开发人员设置中进行设置更为可靠和可靠。