Androids ObjectAnimator.ofFloat无法正常工作

时间:2014-08-26 12:16:36

标签: android animation android-animation

我在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

有谁有想法,为什么这不能正常工作?

2 个答案:

答案 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)

我相信,此解决方案比让用户在开发人员设置中进行设置更为可靠和可靠。