Animated Vector Drawable Using Compatibility Library Even on API 22 Device

I wrote an animated vector with the ability to draw using path morphing (which is only available by API 21 and higher). I have a backup animation using a simple rotation for the API below 21. I am using an animated vector support library ( com.android.support:animated-vector-drawable:25.3.1).

This is how I run the animation:

mBinding.switchIcon.setImageResource(R.drawable.ic_animated_vertical_arrow_down_to_up_32dp);

final Drawable animation = mBinding.switchIcon.getDrawable();
if (animation instanceof Animatable) {
    ((Animatable) animation).start();
}

This works fine on APIs 19 and 24, but does not work on APIs 22 and 23 (I don't have the API 21 device under test).

The case of API 19 is logical: the animation is simple, it is handled perfectly by the support library, it works. Fine.

, API 21 . , animation AnimatedVectorDrawableCompat: , , .

API 24? , animation AnimatedVectorDrawable. , .

, : API 21-23 , API 24 ?


  • , , , :

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        AnimatedVectorDrawable drawable = (AnimatedVectorDrawable) getDrawable(R.drawable.ic_animated_vertical_arrow_down_to_up_32dp);
        mBinding.switchIcon.setImageDrawable(drawable);
    } else {
        mBinding.switchIcon.setImageResource(R.drawable.ic_animated_vertical_arrow_down_to_up_32dp);
    }
    
    final Drawable animation = mBinding.switchIcon.getDrawable();
    if (animation instanceof Animatable) {
        ((Animatable) animation).start();
    }
  • () Google: https://issuetracker.google.com/issues/37116940

  • , , API 22 (, , 23) SDK AnimatorSet. .


, , , , , , . , .


AVD, , :

<animated-vector
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:aapt="http://schemas.android.com/aapt">
    <aapt:attr name="android:drawable">
        <vector
            xmlns:android="http://schemas.android.com/apk/res/android"
            android:width="32dp"
            android:height="32dp"
            android:viewportWidth="24"
            android:viewportHeight="24"
            android:alpha="1">
            <group android:name="group">
                <path
                    android:name="path"
                    android:pathData="@string/vertical_arrow_up_path"
                    android:strokeColor="#000000"
                    android:strokeWidth="2"
                    android:strokeLineCap="square"/>
            </group>
        </vector>
    </aapt:attr>
    <target android:name="path">
        <aapt:attr name="android:animation">
            <objectAnimator
                xmlns:android="http://schemas.android.com/apk/res/android"
                android:name="path"
                android:propertyName="pathData"
                android:duration="300"
                android:valueFrom="@string/vertical_arrow_up_path"
                android:valueTo="@string/vertical_arrow_down_path"
                android:valueType="pathType"
                android:interpolator="@android:anim/accelerate_decelerate_interpolator"/>
        </aapt:attr>
    </target>
</animated-vector>

:

<string name="vertical_arrow_up_path" translatable="false">M 7.41 10 L 12 14.585 L 16.59 10</string>
<string name="vertical_arrow_down_path" translatable="false">M 7.41 14.585 L 12 10 L 16.59 14.585</string>

API 22 , (25.3.1), , Animator AVD , .

(25.3.1) AnimatorSet node: a AnimatorSet, , , ObjectAnimator, AVD XML. referent VectorDrawableCompat, pathData, PropertyValuesHolder , . : .

(SDK 22) ( AnimatorSet , ...): AnimatedVectorDrawableState mAnimators 1, ObjectAnimator ( , ). : .

, , - ValueAnimator PropertyValuesHolder. drawable, , typecheck, VectorDrawable. . ...


, , ( @LewisMcGeary , , ). . , API 21-23 SDK, . AnimatedVectorDrawableCompat [whatever]Compat. , .

SDK ObjectAnimator, API, ( , 21+, , 19 ). , ObjectAnimator , . , . PropertyValuesHolder (SDK, API 22):

    private Method getPropertyFunction(Class targetClass, String prefix, Class valueType) {
        // TODO: faster implementation...
        Method returnVal = null;
        String methodName = getMethodName(prefix, mPropertyName);
        Class args[] = null;
        if (valueType == null) {
            try {
                returnVal = targetClass.getMethod(methodName, args);
            } catch (NoSuchMethodException e) {
                // Swallow the error, log it later
            }
        } else {
            args = new Class[1];
            Class typeVariants[];
            if (valueType.equals(Float.class)) {
                typeVariants = FLOAT_VARIANTS;
            } else if (valueType.equals(Integer.class)) {
                typeVariants = INTEGER_VARIANTS;
            } else if (valueType.equals(Double.class)) {
                typeVariants = DOUBLE_VARIANTS;
            } else {
                typeVariants = new Class[1];
                typeVariants[0] = valueType;
            }
            for (Class typeVariant : typeVariants) {
                args[0] = typeVariant;
                try {
                    returnVal = targetClass.getMethod(methodName, args);
                    if (mConverter == null) {
                        // change the value type to suit
                        mValueType = typeVariant;
                    }
                    return returnVal;
                } catch (NoSuchMethodException e) {
                    // Swallow the error and keep trying other variants
                }
            }
            // If we got here, then no appropriate function was found
        }

        if (returnVal == null) {
            Log.w("PropertyValuesHolder", "Method " +
                    getMethodName(prefix, mPropertyName) + "() with type " + valueType +
                    " not found on target class " + targetClass);
        }

        return returnVal;
    }

for, typeVariants . typeVariants Class: android.util.PathParser$PathDataNode. , (targetClass), - Compat: android.support.graphics.drawable.VectorDrawableCompat$VFullPath. , (methodName), setPathData.

, VectorDrawableCompat$VFullPath.setPathData : public void android.support.graphics.drawable.VectorDrawableCompat$VPath.setPathData(android.support.graphics.drawable.PathParser$PathDataNode[])

typeVariants, returnVal null, , ObjectAnimator , VectorDrawableCompat.

, typeVariants? android.util.PathParser$PathDataNode ? - , . AnimatedVectorDrawableCompat, , SDK, API 19 . target node XML, Animator SDK:

Animator objectAnimator = AnimatorInflater.loadAnimator(mContext, id);

AnimatorInflater SDK , , android.util.PathParser$PathDataNode android.support.graphics.drawable.PathParser$PathDataNode. , Google AnimatorInflater ...


, . Google , VectorDrawable SDK 21-23 ( API 22 SVG), . , 19 ( ), 21, 22, 23 24 ( ) , VectorDrawable s...


: (09/06/2017) Google 25.4, API 14+. , ( ).

+4
1

AnimatedVectorDrawableCompat , API 24 ( ).

, , , , API.

, git commit, .

, , (, ). , , , , .

+1

Source: https://habr.com/ru/post/1675787/


All Articles