Android 动画矢量绘图无法正常工作

Android Animated Vector Drawable doesn't work properly

我有以下ImageView

<androidx.appcompat.widget.AppCompatImageView
        android:id="@+id/image_header_toggle"
        android:layout_width="28dp"
        android:layout_height="28dp"
        android:layout_marginEnd="10dp"
        app:layout_constraintBottom_toBottomOf="@+id/text_header_name"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="@+id/text_header_name"
        android:src="@drawable/ic_header_off_to_on"
        app:tint="?attr/colorPrimary"/>

和我通过 https://shapeshifter.design/

制作的两个动画绘图

ic_header_off_to_on.xml

<animated-vector
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:aapt="http://schemas.android.com/aapt">
    <aapt:attr name="android:drawable">
        <vector
            android:name="vector"
            android:width="24dp"
            android:height="24dp"
            android:viewportWidth="24"
            android:viewportHeight="24">
            <group
                android:name="group"
                android:pivotX="12"
                android:pivotY="12">
                <path
                    android:name="path_1"
                    android:pathData="M 15.41 16.58 L 10.83 12 L 15.41 7.41 L 14 6 L 8 12 L 14 18 L 15.41 16.58 Z"
                    android:fillColor="#000"
                    android:strokeWidth="1"/>
            </group>
        </vector>
    </aapt:attr>
    <target android:name="group">
        <aapt:attr name="android:animation">
            <objectAnimator
                android:propertyName="rotation"
                android:duration="300"
                android:valueFrom="0"
                android:valueTo="-90"
                android:valueType="floatType"
                android:interpolator="@android:interpolator/fast_out_slow_in"/>
        </aapt:attr>
    </target>
</animated-vector>

ic_header_on_to_off.xml

<animated-vector
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:aapt="http://schemas.android.com/aapt">
    <aapt:attr name="android:drawable">
        <vector
            android:name="vector"
            android:width="24dp"
            android:height="24dp"
            android:viewportWidth="24"
            android:viewportHeight="24">
            <group
                android:name="group"
                android:pivotX="12"
                android:pivotY="12"
                android:rotation="270">
                <path
                    android:name="path_1"
                    android:pathData="M 15.41 16.58 L 10.83 12 L 15.41 7.41 L 14 6 L 8 12 L 14 18 L 15.41 16.58 Z"
                    android:fillColor="#000"
                    android:strokeWidth="1"/>
            </group>
        </vector>
    </aapt:attr>
    <target android:name="group">
        <aapt:attr name="android:animation">
            <objectAnimator
                android:propertyName="rotation"
                android:duration="300"
                android:valueFrom="270"
                android:valueTo="0"
                android:valueType="floatType"
                android:interpolator="@android:interpolator/fast_out_slow_in"/>
        </aapt:attr>
    </target>
</animated-vector>

以及我用来切换图标的这段代码

val res = if (isExpanded) R.drawable.ic_header_off_to_on else R.drawable.ic_header_on_to_off
    
image_header_toggle.setImageResource(res)
(view.image_header_toggle.drawable as? AnimatedVectorDrawable)?.start()
image_header_toggle.setOnClickListener { isExpanded = !isExpanded }

off_to_on 动画似乎播放得很好,但 on_to_off 动画效果不佳,图像只是被替换了。 It looks like this >_<

我刚发现这个问题并尝试了一些东西。一个更优雅的解决方案是用我的删除你的 Kotlin 代码。这将实现平滑过渡,您甚至可以更改它的持续时间。您可以只使用一个而不需要 2 个可绘制对象。如果您使用 Fragment 而不是 Activity,请不要忘记设置 view.findViewById 而不是 findViewById:

class MainActivity : AppCompatActivity() {

    private var isExpanded = true

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)


        val imageView = findViewById<ImageView>(R.id.image_header_toggle)

        imageView.setOnClickListener {
            if (!isExpanded) {
                imageView.animate().apply {
                duration = 500
                rotation(0f)
                isExpanded = true}
            }else{
                imageView.animate().apply {
                duration = 500
                rotation(-90f)
                isExpanded = false}
            }
        }
    }
}