Android属性动画

本文深入探讨了Android属性动画的工作原理,特别是ObjectAnimator类中的propertyName参数如何被用来改变目标对象的属性值。通过分析源码,解释了动画设置过程中的关键步骤,包括如何找到并调用目标对象上的setter方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Android属性动画看api没说这个property到底是啥玩意,

源码里初始化时

public static ObjectAnimator ofInt(Object target, String propertyName, int... values) {
    ObjectAnimator anim = new ObjectAnimator(target, propertyName);
    anim.setIntValues(values);
    return anim;
}
private ObjectAnimator(Object target, String propertyName) {
    setTarget(target);
    setPropertyName(propertyName);
}
 */
public void setPropertyName(@NonNull String propertyName) {
    // mValues could be null if this is being constructed piecemeal. Just record the
    // propertyName to be used later when setValues() is called if so.
    if (mValues != null) {
        PropertyValuesHolder valuesHolder = mValues[0];
        String oldName = valuesHolder.getPropertyName();
        valuesHolder.setPropertyName(propertyName);
        mValuesMap.remove(oldName);
        mValuesMap.put(propertyName, valuesHolder);
    }
    mPropertyName = propertyName;
    // New property/values/target should cause re-initialization prior to starting
    mInitialized = false;
}
propertyName这个值可能会传给PropertyValuesHolder,这个类很不错。

动画么,总要修改值,咱只传了一个object,与propertyName还有一些值,在实例化时ofint的实例化成
IntPropertyValuesHolder这个类,都在PropertyValuesHolder里,在intPropertyValuesHolder
里有个方法
@Override
void setupSetter(Class targetClass) {
    if (mProperty != null) {
        return;
    }
    // Check new static hashmap<propName, int> for setter method
    synchronized(sJNISetterPropertyMap) {
        HashMap<String, Long> propertyMap = sJNISetterPropertyMap.get(targetClass);
        boolean wasInMap = false;
        if (propertyMap != null) {
            wasInMap = propertyMap.containsKey(mPropertyName);
            if (wasInMap) {
                Long jniSetter = propertyMap.get(mPropertyName);
                if (jniSetter != null) {
                    mJniSetter = jniSetter;
                }
            }
        }
        if (!wasInMap) {
            String methodName = getMethodName("set", mPropertyName);
            try {
                mJniSetter = nGetIntMethod(targetClass, methodName);
            } catch (NoSuchMethodError e) {
                // Couldn't find it via JNI - try reflection next. Probably means the method
                // doesn't exist, or the type is wrong. An error will be logged later if
                // reflection fails as well.
            }
            if (propertyMap == null) {
                propertyMap = new HashMap<String, Long>();
                sJNISetterPropertyMap.put(targetClass, propertyMap);
            }
            propertyMap.put(mPropertyName, mJniSetter);
        }
    }
    if (mJniSetter == 0) {
        // Couldn't find method through fast JNI approach - just use reflection
        super.setupSetter(targetClass);
    }
}
这个里面的getMethodName这个方法是告诉我们这个属性值到底应该放什么的方法,它的代码是这样的
static String getMethodName(String prefix, String propertyName) {
    if (propertyName == null || propertyName.length() == 0) {
        // shouldn't get here
        return prefix;
    }
    char firstLetter = Character.toUpperCase(propertyName.charAt(0));
    String theRest = propertyName.substring(1);
    return prefix + firstLetter + theRest;
}
这段代码大家都看得懂。当然Android里最重要的东西都是C层做的,这里的
propertyMap = new HashMap<String, Long>();里放的是方法名字与方法的类似id的值,是个native方法。之后再测试
public class Person {

    public int getXy() {
        return xy;
    }

    public void setXy(int xy) {
        this.xy = xy;
    }

    private int xy;

}

ValueAnimator animator = ObjectAnimator.ofInt(person, "xY", 0, 100);
animator.setDuration(2000);
animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
    @Override
    public void onAnimationUpdate(ValueAnimator animation) {
        Integer value = (Integer) animation.getAnimatedValue();
        Log.i("lhq", "onAnimationUpdate: value = " + value);
    }
});

因为xY处理后变成XY,找不到了,换成xy或Xy都是
希望对大家有用


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值