仔细想了一下,发现之前写的东西有很多漏了,改又不好改,只好在这里另写一篇补充了
之前讲到ObjectAnimator但是没有说xml设置方法,在这里提一下
<?xml version="1.0" encoding="utf-8"?>
<objectAnimator
xmlns:android="http://schemas.android.com/apk/res/android"
android:valueFrom="0"
android:valueTo="1"
android:valueType="floatType"
android:propertyName="alpha"
android:duration="3000"
/>
private class ObjXmlButtonListener implements View.OnClickListener {
@Override
public void onClick(View v) {
Animator animator= AnimatorInflater.loadAnimator(AnimationActivity.this,R.animator.object_animator_test);
animator.setTarget(v);
animator.start();
}
}
如果看过前面的文章的话很容易就能看懂,只是多了一个propertyName属性,是要变化的属性名称
下面讲一下常用的视图属性
private class ObjRotationButtonListener implements View.OnClickListener {
@Override
public void onClick(View v) {
ObjectAnimator objectAnimator=ObjectAnimator.ofFloat(v,"rotation",0f,720f);
objectAnimator.setDuration(3000);
objectAnimator.start();
}
}
private class ObjScaleXButton implements View.OnClickListener {
@Override
public void onClick(View v) {
ObjectAnimator objectAnimator=ObjectAnimator.ofFloat(v,"scaleX",1f,3f,1f);
objectAnimator.setDuration(3000);
objectAnimator.start();
}
}
private class ObjTranslationXButtonListener implements View.OnClickListener {
@Override
public void onClick(View v) {
float x=v.getTranslationX();
ObjectAnimator objectAnimator=ObjectAnimator.ofFloat(v,"translationX",x,300, x);
objectAnimator.setDuration(3000);
objectAnimator.start();
}
}
用法很简单,第一个参数要执行动画的对象,第二个属性名称,随后是不定长参数,传的是数值变化路径,打个比方如果a,b两个参数就是a->b,如果a,b,c三个参数,就是a->b->c
下面是视图常用属性
当然了,之前说过,ObjectAnimator可以传任意属性值,只要有对应的get和set方法
拿TranslationX举个例子
public void setTranslationX(float translationX) {
if (translationX != getTranslationX()) {
invalidateViewProperty(true, false);
mRenderNode.setTranslationX(translationX);
invalidateViewProperty(false, true);
invalidateParentIfNeededAndWasQuickRejected();
notifySubtreeAccessibilityStateChangedIfNeeded();
}
}
public float getTranslationX() {
return mRenderNode.getTranslationX();
}
这些属性都是View所有的,所以凡是继承于View类的对象都可以用这些属性
能用的属性对应的对象内必定有相应的get和set方法,但有相应get和set方法的对象,这个属性不一定能用
因为可能相应的get和set方法不能反映值的变化
比如说如果你想改变Button的宽度,那么传width不会起作用
因为Button和TextView的setWidth方法是设置最大宽度和最小宽度的
public void setWidth(int pixels) {
mMaxWidth = mMinWidth = pixels;
mMaxWidthMode = mMinWidthMode = PIXELS;
requestLayout();
invalidate();
}
那么遇到这种情况该如何解决呢?
我们可以通过用一个类来包装该对象,给他加上对应的get 和set方法
private class WidthButtonListener implements View.OnClickListener {
@Override
public void onClick(View v) {
ViewWrapper viewWrapper=new ViewWrapper(v);
ObjectAnimator.ofInt(viewWrapper, "width", viewWrapper.getWidth(),500).setDuration(3000).start();
}
}
private class ViewWrapper {
private View mTarget;
public ViewWrapper(View target) {
mTarget = target;
}
public int getWidth() {
return mTarget.getLayoutParams().width;
}
public void setWidth(int width) {
mTarget.getLayoutParams().width = width;
mTarget.requestLayout();
}
}
那当我们想要使用多个动画怎么办呢,不要怕,android还提供了AnimatorSet类用于管理动画播放
AnimatorSet.play(Animator anim) :播放当前动画
AnimatorSet.after(long delay) :将现有动画延迟x毫秒后执行
AnimatorSet.with(Animator anim) :将现有动画和传入的动画同时执行
AnimatorSet.after(Animator anim) :将现有动画插入到传入的动画之后执行
AnimatorSet.before(Animator anim) : 将现有动画插入到传入的动画之前执行
举个例子
private class AnimatorSetButtonListener implements View.OnClickListener {
@Override
public void onClick(View v) {
float x=v.getTranslationX();
// 步骤1:设置需要组合的动画效果
ObjectAnimator translation = ObjectAnimator.ofFloat(v, "translationX", x, 300,x);
// 平移动画
ObjectAnimator rotate = ObjectAnimator.ofFloat(v, "rotation", 0f, 720f);
// 旋转动画
ObjectAnimator alpha = ObjectAnimator.ofFloat(v, "alpha", 1f, 0f, 1f);
// 透明度动画
// 步骤2:创建组合动画的对象
AnimatorSet animSet = new AnimatorSet();
// 步骤3:根据需求组合动画
animSet.play(translation).with(rotate).before(alpha);
animSet.setDuration(5000);
// 步骤4:启动动画
animSet.start();
}
}
如果有复杂的动画也可以用xml嵌套来写
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:ordering="sequentially">
<!--表示Set集合内的动画按顺序进行
ordering的属性值:sequentially & together
sequentially:表示set中的动画,按照先后顺序逐步进行(a 完成之后进行 b )
together:表示set中的动画,在同一时间同时进行,为默认值-->
<set android:ordering="together">
<!--同时执行-->
<objectAnimator
android:duration="2000"
android:propertyName="translationX"
android:valueFrom="0"
android:valueTo="300"
android:valueType="floatType"/>
<objectAnimator
android:duration="3000"
android:propertyName="rotation"
android:valueFrom="0"
android:valueTo="360"
android:valueType="floatType"/>
</set>
<set android:ordering="sequentially">
<!--按顺序执行-->
<objectAnimator
android:duration="1500"
android:propertyName="alpha"
android:valueFrom="1"
android:valueTo="0"
android:valueType="floatType"/>
<objectAnimator
android:duration="1500"
android:propertyName="alpha"
android:valueFrom="0"
android:valueTo="1"
android:valueType="floatType"/>
</set>
</set>
private class XmlAnimatorSetButtonListener implements View.OnClickListener {
@Override
public void onClick(View v) {
AnimatorSet animator = (AnimatorSet) AnimatorInflater.loadAnimator(AnimationActivity.this, R.animator.animatorset);
// 创建组合动画对象 & 加载XML动画
animator.setTarget(v);
// 设置动画作用对象
animator.start();
}
}