Android 中的缩放动画会降低图像质量

Scale animation in Android degrades image quality

In Android 5.0 (API Level 21) and above, you can define vector drawables, which scale without losing definition.

我在 Android Studio (API 28) 中使用 Vector Assets。示例:ic_mybutton.xml。 矢量可绘制对象以原始质量显示在视图上:image, image, image

ImageButton button = new ImageButton(context);
button.setImageResource(R.drawable.ic_mybutton);

在按钮和图像按钮(或其他视图)上使用此动画:

Animation animation = new ScaleAnimation(
        1.0f, 0.9f,
        1.0f, 0.9f,
        Animation.RELATIVE_TO_SELF, 0f,
        Animation.RELATIVE_TO_SELF, 1f);
animation.setFillAfter(true);
animation.setDuration(1000);
button.startAnimation(animation);

产生可怕的图像失真:image, image, image。 我做错了什么?

这个问题可以用动画师解决。

所有其他已知的库,例如 Boom, RxAnimation 等,在缩放时会降低图像质量。

anim_scale.xml:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <objectAnimator
        android:duration="@android:integer/config_shortAnimTime"
        android:propertyName="scaleX"
        android:repeatCount="1"
        android:valueFrom="1.0"
        android:valueTo="0.9"
        android:valueType="floatType" />
    <objectAnimator
        android:duration="@android:integer/config_shortAnimTime"
        android:propertyName="scaleY"
        android:repeatCount="1"
        android:valueFrom="1.0"
        android:valueTo="0.9"
        android:valueType="floatType" />
</set>

animated_vector.xml:

<?xml version="1.0" encoding="utf-8"?>
<animated-vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:drawable="@drawable/ic_mybutton">
    <target
        android:animation="@animator/anim_scale"
        android:name="anim_scale" />
</animated-vector>

将您的路径放入 <group> 标记并设置基准。

ic_mybutton.xml:

<group
  android:name="anim_scale"
  android:pivotX="177.5"
  android:pivotY="37.5">
  ...
</group>

因此(稍作改动),您可以在不损失矢量图像质量的情况下制作按钮单击动画:

ImageButton button = findViewById(R.id.button_apply);
button.setImageResource(R.drawable.animated_vector);
button.setOnClickListener(v -> ((Animatable) button.getDrawable()).start());

P.S。 以下方法不起作用(质量下降):

ObjectAnimator animator = ObjectAnimator.ofFloat(button, "scale", 0.9f);
animator.setDuration(200);
animator.start();

并且 StateListAnimator class 也会降低图像质量。