美文网首页
android Property Animation(属性动画)

android Property Animation(属性动画)

作者: hao_developer | 来源:发表于2021-01-18 10:08 被阅读0次

补间动画通过动画改变控件的位置时,只是改变了View的显示效果并不会真正的改变View的属性(如View的真实位置等),控件的作用域还在原地,而且补间动画是只能够作用在View上。

属性动画通过动画改变控件的位置时,控件的真实位置会随着改变,控件的作用域在变换后的位置。

下面我们就来学习属性动画的平移、缩放、旋转、透明度变化和属性动画的一些组合动画。

1486192623_7989.gif
属性动画的平移、缩放、旋转、透明度变化
1486192625_5651.gif
属性动画的组合动画
一、先来看属性动画的平移、缩放、旋转、透明度变化
代码实现如下:
AnimationProperty.java
public class AnimationProperty {
 
    public static ObjectAnimator setAnimProperty(ObjectAnimator objectAnimator) {
 
        // objectAnimator.setRepeatCount(2); // 动画重复次数
        // 动画重复模式分别为:RESTART(重新播放)和REVERSE(往返播放)两种
        // objectAnimator.setRepeatMode(ObjectAnimator.RESTART);
        objectAnimator.setDuration(2000); // 动画播放时长
        // objectAnimator.start(); //开启动画
        // objectAnimator.setStartDelay(2000); // 延时开启动画
        // objectAnimator.cancel(); //停止动画
        // objectAnimator.end(); //直接到最终状态
        return objectAnimator;
    }
 
    public static ValueAnimator setAnimProperty(ValueAnimator valueAnimator) {
 
        valueAnimator.setRepeatCount(2);
        valueAnimator.setRepeatMode(ObjectAnimator.RESTART);
        valueAnimator.setDuration(2000).start();
        return valueAnimator;
    }
 
}

PropertyAnimationActivity.java

public class PropertyAnimationActivity extends Activity {
 
    protected static final String TAG = "Havorld";
    private ImageView imageView;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_property);
 
        imageView = (ImageView) findViewById(R.id.iv);
        imageView.setOnClickListener(new OnClickListener() {
 
            @Override
            public void onClick(View v) {
 
                Toast.makeText(getApplicationContext(), "点击了图片",
                        Toast.LENGTH_SHORT).show();
            }
        });
    }
 
    /**
     * 平移动画
     */
    public void trans(View view) {
 
        /**
         * imageView: 要作用的控件; translationY: 要作用动作的属性名 ; float... values:
         * 可变参数是依次移动的位移
         * 
         */
        // ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(imageView,
        // "translationY", 20, 40, 80, 120, 160); //竖直平移
        ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(imageView,
                "translationX", 0, 50, 100, 150, 200, 250, 300); // 水平平移
 
        // 监听动画是否成功执行
        objectAnimator.addUpdateListener(new AnimatorUpdateListener() {
 
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
 
                float currentValue = (Float) animation.getAnimatedValue();
                Log.i(TAG, "currentValue:" + currentValue);
                // 直接设置动画
                // imageView.setTranslationX(translationX);
                // imageView.setTranslationY(translationY);
                // imageView.setScaleX(caleX);
                // imageView.setScaleY(scaleY);
                // imageView.setRotation(rotation);
                // imageView.setRotationX(rotation);
                // imageView.setRotationY(rotation);
                // imageView.setImageAlpha(alpha);
                // imageView.setAlpha(alpha);
            }
        });
        // 动画监听
        objectAnimator.addListener(new AnimatorListener() {
 
            // 动画开始执行
            @Override
            public void onAnimationStart(Animator animation) {
 
                Log.e(TAG, "onAnimationStart");
            }
 
            // 动画重复执行
            @Override
            public void onAnimationRepeat(Animator animation) {
 
                Log.e(TAG, "onAnimationRepeat");
            }
 
            // 动画执行完成
            @Override
            public void onAnimationEnd(Animator animation) {
                // 获取控件平移的距离
                float translationX = imageView.getTranslationX();
                Log.e(TAG, "translationX:" + translationX);
            }
 
            // 动画取消执行
            @Override
            public void onAnimationCancel(Animator animation) {
 
                Log.e(TAG, "onAnimationCancel");
            }
        });
 
        // 简化上述动画监听,可以复写上面的任意方法
        objectAnimator.addListener(new AnimatorListenerAdapter() {
 
        });
 
        // 设置动画属性并开启动画
        AnimationProperty.setAnimProperty(objectAnimator).start();
 
        // XmlTranslation();
        // valueAnimator();
    }
 
    /**
     * 通过XML设置平移
     */
    private void XmlTranslation() {
        // 通过XML设置属性动画
        Animator animator = AnimatorInflater.loadAnimator(this,
                R.animator.object_animator_translationx);
        animator.setTarget(imageView);
        animator.start();
    }
 
    /**
     * 通过ValueAnimator设置平移
     */
    private void valueAnimator() {
 
        ValueAnimator valueAnimator = ValueAnimator.ofFloat(0, 1000);
        valueAnimator.setTarget(imageView);
        AnimationProperty.setAnimProperty(valueAnimator);
        valueAnimator.addUpdateListener(new AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float animatedValue = (Float) animation.getAnimatedValue();
                imageView.setTranslationY(animatedValue);
            }
        });
    }
 
    /**
     * 缩放动画
     */
    public void scale(View view) {
 
        // 横向缩放
        ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(imageView,
                "scaleX", 1.0f, 1.2f, 1.5f, 1.8f, 2.0f, 1.8f, 1.5f, 1.0f);
        // 纵向缩放
        // ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(imageView,
        // "scaleY", 1.0f, 1.2f, 1.5f, 1.8f, 2.0f,1.8f, 0.5f,1.0f);
        // 通过代码设置属性动画
        AnimationProperty.setAnimProperty(objectAnimator).start();
 
    }
 
    /**
     * 旋转动画
     */
    public void rotate(View view) {
 
        ObjectAnimator objectAnimator = ObjectAnimator
                .ofFloat(imageView, "rotationX", 0, 60, 120, 150, 180, 210,
                        240, 270, 300, 330, 360);
        AnimationProperty.setAnimProperty(objectAnimator).start();
    }
 
    /**
     * 透明度变化动画
     */
    public void alpha(View view) {
 
        ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(imageView,
                "alpha", 0, 0.1f, 0.3f, 0.5f, 0.8f, 1.0f);
        AnimationProperty.setAnimProperty(objectAnimator).start();
    }
 
}

activity_property.XML

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="10dp"
    tools:context=".PropertyAnimationActivity" >
 
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal" >
 
        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:onClick="trans"
            android:text="平移" />
 
        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:onClick="scale"
            android:text="缩放" />
 
        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:onClick="rotate"
            android:text="旋转" />
 
        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:onClick="alpha"
            android:text="透明" />
    </LinearLayout>
 
    <ImageView
        android:id="@+id/iv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:layout_marginTop="10dp"
        android:src="@drawable/cl" />
 
</LinearLayout>

在代码中调用ObjectAnimator.ofFloat(imageView,"translationX", 0, 50, 100, 150, 200, 250, 300);

意思就是ObjectAnimator会不断地改变imageView对象的translationX属性的值从0变化到300。然后imageView对象根据translationX属性值的改变来不断刷新界面的显示,产生横向移动的动画效果。

ObjectAnimator是如何进行操作的呢?ObjectAnimator内部的工作机制是去寻找translationX这个属性名对应的get和set方法:
public void setTranslationX(float value);
public float getTranslationX();

imageView中确实有这两个方法:

imageView.getTranslationX();
imageView.setTranslationX(translationX);

这两个方法是由其父类View对象提供,所以使用ObjectAnimator.ofFloat()调用属性动画时对应的控件必须要有set和get方法。其他的scaleX,rotationX,alpha也是一样的道理。

注:使用ValueAnimator掉用属性动画时不需要其控件必须有set和get方法。

二、接下来看属性动画的组合动画

直接上代码:

PropertyGroupAnimationActivity.java

public class PropertyGroupAnimationActivity extends Activity {
 
    protected static final String TAG = "Havorld";
    private ImageView imageView;
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_property_group);
 
        imageView = (ImageView) findViewById(R.id.iv);
        imageView.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
 
                Toast.makeText(getApplicationContext(), "点击了图片",
                        Toast.LENGTH_SHORT).show();
            }
        });
 
    }
 
    /**
     * 组合动画一
     */
    public void animatorSet(View view) {
 
        AnimatorSet animatorSet = new AnimatorSet();
 
        ObjectAnimator translationXAnimation = AnimationProperty
                .setAnimProperty(ObjectAnimator.ofFloat(imageView,
                        "translationX", 0, 10, 20, 30, 40, 50));
 
        ObjectAnimator translationYAnimation = AnimationProperty
                .setAnimProperty(ObjectAnimator.ofFloat(imageView,
                        "translationY", 0, 20, 40, 80, 100));
 
        ObjectAnimator scaleXAnimation = AnimationProperty
                .setAnimProperty(ObjectAnimator.ofFloat(imageView, "scaleX",
                        1.0f, 1.2f, 1.5f, 1.8f, 2.0f, 1.8f, 1.5f, 1.0f));
 
        ObjectAnimator rotationAnimation = AnimationProperty
                .setAnimProperty(ObjectAnimator.ofFloat(imageView, "rotation",
                        0, 60, 120, 150, 180, 210, 240, 270, 300, 330, 360));
        ObjectAnimator alphaAnimation = AnimationProperty
                .setAnimProperty(ObjectAnimator.ofFloat(imageView, "alpha", 0,
                        0.1f, 0.3f, 0.5f, 0.8f, 1.0f));
 
        // after(Animator anim) 将现有动画插入到传入的动画之后执行
        // after(long delay) 将现有动画延迟指定毫秒后执行
        // before(Animator anim) 将现有动画插入到传入的动画之前执行
        // with(Animator anim) 将现有动画和传入的动画同时执行
 
        // 按顺序播放动画组合方法一,弦播放alphaAnimation动画后,开始一块播放translationXAnimation和translationYAnimation动画,
        // 完了之后再一块播放scaleXAnimation和rotationAnimation
        // animatorSet.play(translationXAnimation).with(translationYAnimation);
        // animatorSet.play(scaleXAnimation).with(rotationAnimation)
        // .after(alphaAnimation);
 
        // 按顺序播放动画组合方法二
        // animatorSet.playSequentially(translationXAnimation,translationYAnimation,scaleXAnimation,rotationAnimation,alphaAnimation);
 
        // 组合动画
        animatorSet.playTogether(translationXAnimation, translationYAnimation,
                scaleXAnimation, rotationAnimation, alphaAnimation);
 
        animatorSet.start();
    }
 
    /**
     * 组合动画二
     */
    public void viewProperty(View view) {
 
        ViewPropertyAnimator viewPropertyAnimator = imageView.animate();
        viewPropertyAnimator.x(20).y(30);//移动到坐标(20,30)处
        viewPropertyAnimator.alpha(0.5f);//设置控件透明度为0.5
    }
 
    /**
     * 组合动画三
     */
    public void propertyValuesHolder(View view) {
 
        PropertyValuesHolder scaleX = PropertyValuesHolder.ofFloat("scaleX",
                1f, 0, 1f);
        PropertyValuesHolder scaleY = PropertyValuesHolder.ofFloat("scaleY",
                1f, 0, 1f);
        PropertyValuesHolder alpha = PropertyValuesHolder.ofFloat("alpha", 1f,
                0f, 1f);
        PropertyValuesHolder rotation = PropertyValuesHolder.ofFloat(
                "rotation", 0, 90);
        ObjectAnimator objectAnimator = ObjectAnimator.ofPropertyValuesHolder(
                imageView, alpha, scaleX, scaleY, rotation);
        AnimationProperty.setAnimProperty(objectAnimator).start();
 
    }
 
    /**
     * 一个动画实现多个效果
     */
    public void groupAnimation(View view) {
 
        ObjectAnimator animator = ObjectAnimator.ofFloat(imageView, "Havorld",
                1.0F, 1.5F);
        ObjectAnimator objectAnimator = AnimationProperty
                .setAnimProperty(animator);
 
        //监听动画的执行
        objectAnimator.addUpdateListener(new AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float animatedValue = (Float) animation.getAnimatedValue();
                Log.e(TAG, "animatedValue:" + animatedValue);
                imageView.setAlpha(animatedValue);
                imageView.setScaleX(animatedValue);
                imageView.setScaleY(animatedValue);
            }
        });
        objectAnimator.start();
    }
 
}

activity_property_group.XML

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".PropertyAnimationActivity" >
 
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal" >
 
        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:onClick="animatorSet"
            android:text="AnimatorSet"
            android:textSize="12sp" />
 
        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:onClick="viewProperty"
            android:text="ViewProperty"
            android:textSize="12sp" />
 
        <Button
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:ellipsize="end"
            android:onClick="propertyValuesHolder"
            android:singleLine="true"
            android:text="propertyValuesHolder"
            android:textSize="12sp" />
    </LinearLayout>
 
    <ImageView
        android:id="@+id/iv"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:layout_marginTop="10dp"
        android:src="@drawable/cl" />
 
</LinearLayout>

相关文章

网友评论

      本文标题:android Property Animation(属性动画)

      本文链接:https://www.haomeiwen.com/subject/xmlwaktx.html