Android 属性动画(二)

版权声明:原创文章,转载请注明 https://blog.csdn.net/qq_37482202/article/details/82953919

仔细想了一下,发现之前写的东西有很多漏了,改又不好改,只好在这里另写一篇补充了

之前讲到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();
        }
    }

猜你喜欢

转载自blog.csdn.net/qq_37482202/article/details/82953919