android动画的几种形式

android的动画有很多种,我今天主要讲的是用的比较基础的三种。帧动画补间动画和属性动画。

帧动画是比较简单的动画就是几个图片组装在一起轮流执行,从而形成动画效果。

xml布局

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.mahui.animationtest.FrameActivity">

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <ImageView
        android:id="@+id/imageView2"
        android:layout_marginLeft="200dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/loading_progress_anim"/>
    <Button
        android:layout_alignParentBottom="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="addanim"
        android:text="加图片"/>
</RelativeLayout>
loading_progress_anim布局若将oneshot设为true则动画只执行一次,若设置为false则动画循环执行。duration是动画执行的时间。

<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android" 
    android:oneshot="false">
    <item android:drawable="@mipmap/loading_progress_1" android:duration="100"/>
    <item android:drawable="@mipmap/loading_progress_2" android:duration="100"/>
    <item android:drawable="@mipmap/loading_progress_3" android:duration="100"/>
    <item android:drawable="@mipmap/loading_progress_4" android:duration="100"/>
</animation-list>

activity布局

public class FrameActivity extends AppCompatActivity {
    private ImageView imageView,imageView2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        imageView = (ImageView) findViewById(R.id.imageView);
        imageView2= (ImageView) findViewById(R.id.imageView2);
        AnimationDrawable animationDrawable = (AnimationDrawable)(imageView2).getDrawable();
        animationDrawable.start();
    }
    public void addanim(View view){
        AnimationDrawable anim=new AnimationDrawable();
        for(int i=1;i<=4;i++){
            int id=getResources().getIdentifier("loading_progress_"+i,"mipmap",getPackageName());
            Drawable drawable=getResources().getDrawable(id);
            anim.addFrame(drawable,300);
        }
        anim.setOneShot(false);
        imageView.setBackgroundDrawable(anim);
        anim.start();
    }
}
不管用何种方式都必须在代码里进行启动。imageview2的启动方式很简单,直接获得红箭的deawable然后启动即可。另一个的启动略复杂些需要将图片根据id一个个加进去。设置时间及循环值,最后才能start,所以极力推荐用xml的形式使用帧动画。

补间动画。

页面布局

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <ImageView
        android:layout_centerInParent="true"
        android:id="@+id/iv_dongxiao"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@mipmap/ic_launcher"/>
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@id/iv_dongxiao"
        android:layout_marginTop="20dp"
        android:orientation="horizontal">
        <Button
            android:onClick="touming"
            android:layout_weight="1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="透明"/>
        <Button
            android:onClick="xuanzhuan"
            android:layout_weight="1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="旋转"/>
        <Button
            android:onClick="suofang"
            android:layout_weight="1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="缩放"/>
        <Button
            android:onClick="weiyi"
            android:layout_weight="1"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="位移"/>
        <Button
            android:onClick="donghuaheji"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="动画合集"/>
    </LinearLayout>
</RelativeLayout>
xml特效:

touming

<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="200"
    android:fillAfter="true"
    android:fromAlpha="1.0"
    android:repeatCount="2"
    android:repeatMode="reverse"
    android:toAlpha="0.9" >
</alpha>
xuanzhuan

<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="2000"
    android:fromDegrees="0"
    android:pivotX="50%"
    android:pivotY="50%"
    android:repeatCount="2"
    android:toDegrees="360" >
</rotate>
suofang

<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="2000"
    android:pivotX="50%"
    android:pivotY="50%"
    android:fromXScale="0.2"
    android:fromYScale="0.2"
    android:toXScale="2.0"
    android:toYScale="2.0" >
</scale>
weiyi

<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromXDelta="10%p"
    android:toXDelta="20%p"
    android:fromYDelta="10%p"
    android:toYDelta="20%p"
    android:duration="2000"
    android:repeatCount="2"
    android:repeatMode="reverse">
</translate>

donghuaheji

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >
    <rotate
        android:duration="2000"
        android:fromDegrees="0"
        android:pivotX="50%"
        android:pivotY="50%"
        android:repeatCount="2"
        android:toDegrees="360" >
    </rotate>
    <scale
        android:duration="2000"
        android:fromXScale="0.2"
        android:fromYScale="0.2"
        android:pivotX="50%"
        android:pivotY="50%"
        android:toXScale="2.0"
        android:toYScale="2.0" >
    </scale>

    <alpha
        android:duration="2000"
        android:fillAfter="true"
        android:fromAlpha="1.0"
        android:repeatCount="2"
        android:repeatMode="reverse"
        android:toAlpha="0.5" >
    </alpha>
</set>

activity

public class TweenActivity extends AppCompatActivity {
    private ImageView iv_dongxiao;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.dongxiao);
        iv_dongxiao= (ImageView) findViewById(R.id.iv_dongxiao);
    }
    public void touming(View view){
        //xml
        iv_dongxiao.startAnimation(AnimationUtils.loadAnimation(this,R.anim.touming));
        // 1.0f代表完全不透明
        // 0.0f代表完全透明
        /*float fromAlpha = 1.0f;
        float toAlpha = 0.0f;
        AlphaAnimation aa = new AlphaAnimation(fromAlpha, toAlpha);

        // 动画的配置
        aa.setDuration(2 * 1000); // 动画持续多久
        aa.setFillAfter(true); // 设为true之后,界面会停留在动画播放完时的界面
        aa.setRepeatCount(1); // 设置动画重复的次数
        aa.setRepeatMode(Animation.RESTART); // 动画重启或逆转,默认值为重启动画

        // 启动动画
        iv_dongxiao.startAnimation(aa);*/
    }
    public void xuanzhuan(View view){
        //xml
        iv_dongxiao.startAnimation(AnimationUtils.loadAnimation(this,R.anim.xuanzhuan));
        // 旋转的起始角度
        /*float fromDegrees = 0;
        // 旋转的目标角度
        float toDegrees = 360;

        // 旋转的X轴中心点类型
        // 分为三种类型:Animation.ABSOLUTE, Animation.RELATIVE_TO_SELF,Animation.RELATIVE_TO_PARENT.
        // X轴的原点的类型(相对于自己而言还是相对于父容器而言)
        int pivotXType = Animation.RELATIVE_TO_SELF;

        // 旋转的X轴坐标的值,一般被指定为一个百分比数;1.0代表着100%
        // 开始伸缩时的X轴的原点(例:0.5就是指以图片宽度的二分之一的位置作为X轴的原点)
        float pivotXValue = 0.0f;

        // Y轴的原点的类型
        int pivotYType = Animation.RELATIVE_TO_SELF;
        // 开始伸缩时的Y轴的原点
        float pivotYValue = 0.0f;
        *//*
        *这里对pivotXValue和pivotYValue的值详细说明一下
        *在Android中的坐标轴Y轴向下是增张的,X轴向右是增长的;
         *pivotXValue在API中被说明为:旋转的X轴坐标的值,一般被指定为一个百分比数;1.0代表着100%
        *也就是说,当我们指定为0.0f时,代表作是图片的X轴的0点;当指定为0.5f时,代表图片的width/2的位置;当被指定为1.0f时,代表图片的width位置;
        *//*
        RotateAnimation ra = new RotateAnimation(fromDegrees, toDegrees, pivotXType, pivotXValue, pivotYType, pivotYValue);

        // 动画的配置
        ra.setDuration(2 * 1000); // 动画持续多久
        ra.setRepeatCount(1); // 设置动画重复的次数
        ra.setStartOffset(2 * 1000); // 设置动画启动时间的偏移量,简单来说就是多长时间后启动动画

        // 启动动画
        iv_dongxiao.startAnimation(ra);*/
    }
    public void suofang(View view){
        //xml
        iv_dongxiao.startAnimation(AnimationUtils.loadAnimation(this,R.anim.suofang));

        // 0.0f代表0点的位置;0.5f代表图片宽度的一半的位置;1.0f代表图片整个图片宽度的位置;2.0f代表整个图片宽度的2倍;
        // 水平方向比例尺的起始值
        /*float fromX = 0.0f;
        // 水平方向比例尺的终值
        float toX = 2.0f;

        // 垂直方向比例尺的起始值
        float fromY = 0.0f;
        // 垂直方向比例尺的终值
        float toY = 2.0f;

        // X轴的原点的类型(相对于自己而言还是相对于父容器而言)
        int pivotXType = Animation.RELATIVE_TO_SELF;
        // 开始伸缩时的X轴的原点(例:0.5就是指以图片宽度的二分之一的位置作为X轴的原点)
        float pivotXValue = 0.0f;
        int pivotYType = Animation.RELATIVE_TO_SELF;
        float pivotYValue = 0.0f;
        ScaleAnimation sa = new ScaleAnimation(fromX, toX, fromY, toY, pivotXType, pivotXValue, pivotYType, pivotYValue);
        sa.setDuration(2 * 1000);

        // 整个动画会呈现,从左上角向右下加放大2倍
        iv_dongxiao.startAnimation(sa);*/
    }
    public void weiyi(View view){
        //xml
        iv_dongxiao.startAnimation(AnimationUtils.loadAnimation(this,R.anim.weiyi));
        // 位移的x轴起始坐标的类型(相对于自己还是相对父容器)
        /*int fromXType = Animation.RELATIVE_TO_PARENT;
        // x轴起点
        float fromXValue = -0.5f;
        int toXType = Animation.RELATIVE_TO_PARENT;
        // X轴的终点
        float toXValue = 0.5f;

        int fromYType = Animation.RELATIVE_TO_PARENT;
        // Y轴的起始坐标
        float fromYValue = -0.5f;
        int toYType = Animation.RELATIVE_TO_PARENT;
        // Y轴的终点坐标
        float toYValue = 0.5f;

        TranslateAnimation ta = new TranslateAnimation(fromXType, fromXValue, toXType, toXValue, fromYType, fromYValue, toYType, toYValue);
        ta.setDuration(2 * 1000);

        iv_dongxiao.startAnimation(ta);*/
    }
    public void donghuaheji(View view){
        //xml
        iv_dongxiao.startAnimation(AnimationUtils.loadAnimation(this,R.anim.donghuaheji));
        /*AnimationSet set = new AnimationSet(false);

        ScaleAnimation  sa = new ScaleAnimation(0.1f, 2.0f, 0.1f, 2.0f, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);

        sa.setDuration(3000); //设置动画的时间
        sa.setRepeatCount(1); //设置动画的显示次数
        sa.setRepeatMode(AlphaAnimation.REVERSE);//设置播放模式

        RotateAnimation ra = new RotateAnimation(0, 360, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);

        ra.setDuration(3000); //设置动画的时间
        ra.setRepeatCount(1); //设置动画的显示次数
        ra.setRepeatMode(AlphaAnimation.REVERSE);//设置播放模式


        TranslateAnimation ta = new TranslateAnimation(Animation.RELATIVE_TO_PARENT, -0.5f, Animation.RELATIVE_TO_PARENT, 0.5f, Animation.RELATIVE_TO_PARENT, -0.5f, Animation.RELATIVE_TO_PARENT, 0.5f);
        ta.setDuration(3000); //设置动画的时间
        ta.setRepeatCount(1); //设置动画的显示次数
        ta.setRepeatMode(AlphaAnimation.REVERSE);//设置播放模式

        set.addAnimation(sa);
        set.addAnimation(ta);
        set.addAnimation(ra);

        //播放动画
        iv_dongxiao.startAnimation(set);*/
    }
}
该特效就是通过xml控制相关的属性,

alpha透明,rotate旋转,scale缩放,translate移动位置。同样,实现效果可以通过代码和xml配置,建议直接用配置。

最后一个是属性动画。

xml的属性动画

scalex.xml

<?xml version="1.0" encoding="utf-8"?>
<objectAnimator xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1000"
    android:propertyName="scaleX"
    android:valueFrom="1.0"
    android:valueTo="2.0"
    android:valueType="floatType" >
</objectAnimator>
scale.xml

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:ordering="together" >

    <objectAnimator
        android:duration="1000"
        android:propertyName="scaleX"
        android:valueFrom="1"
        android:valueTo="0.5" >
    </objectAnimator>
    <objectAnimator
        android:duration="1000"
        android:propertyName="scaleY"
        android:valueFrom="1"
        android:valueTo="0.5" >
    </objectAnimator>

</set>
xml_4_anim.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:layout_below="@id/imageView"
        android:layout_marginTop="100dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="scaleX"
        android:text="横向放大" />
    <Button
        android:layout_below="@id/imageView"
        android:layout_marginTop="100dp"
        android:layout_marginLeft="100dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="scaleXandScaleY"
        android:text="整体缩小" />

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@mipmap/ic_launcher"
        android:layout_centerVertical="true"
        android:layout_centerHorizontal="true" />
</RelativeLayout>
Xml4AnimActivity

public class Xml4AnimActivity extends Activity{
    ImageView imageView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.xml_4_anim);
        imageView= (ImageView) findViewById(R.id.imageView);
    }
    public void scaleX(View view){
        Animator animator= AnimatorInflater.loadAnimator(this,R.animator.scalex);
        animator.setTarget(imageView);
        animator.start();
    }
    public void scaleXandScaleY(View view){
        Animator animator=AnimatorInflater.loadAnimator(this,R.animator.scale);
        imageView.setPivotX(0);
        imageView.setPivotY(0);
        imageView.invalidate();
        animator.setTarget(imageView);
        animator.start();
    }
}

setTarget里面有动画的对象,然后启动动画。

用代码实现上述功能。

object_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <ImageView
        android:onClick="change"
        android:layout_centerInParent="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@mipmap/ic_launcher"/>
</RelativeLayout>
activity

public class ObjectAnimActivity extends Activity{
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.object_main);
    }
    public void change(final View view){
        ObjectAnimator animator=ObjectAnimator.ofFloat(view,"mh",1.0F,0.2F).setDuration(1000);
        animator.start();
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                float cVal= (float) animation.getAnimatedValue();
                view.setAlpha(cVal);
                view.setScaleX(cVal);
                view.setScaleY(cVal);
            }
        });
    }
}
运用代码设置相关属性。

animator_set.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/id_container">

    <ImageView
        android:id="@+id/ball"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerInParent="true"
        android:src="@drawable/ball_shape" />

    <Button
        android:layout_below="@id/ball"
        android:layout_marginTop="100dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="easyrun"
        android:text="简单的多动画Together" />

    <Button
        android:layout_marginLeft="200dp"
        android:layout_marginTop="100dp"
        android:layout_below="@id/ball"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="playrun"
        android:text="多动画按次序执行" />

</RelativeLayout>

activity

public class AnimatorSetActivity extends Activity{
    private ImageView ball;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.animator_set);
        ball= (ImageView) findViewById(R.id.ball);
    }
    public void easyrun(View view){
        ObjectAnimator objectAnimator1=ObjectAnimator.ofFloat(ball,"scaleX",1.0f,2f);
        ObjectAnimator objectAnimator2=ObjectAnimator.ofFloat(ball,"scaleY",1.0f,2f);
        AnimatorSet animatorSet=new AnimatorSet();
        animatorSet.setDuration(2000);
        animatorSet.setInterpolator(new LinearInterpolator());
        animatorSet.playTogether(objectAnimator1,objectAnimator2);
        animatorSet.start();
    }
    public void playrun(View view){
        float cx = ball.getX();
        ObjectAnimator anim1 = ObjectAnimator.ofFloat(ball, "scaleX", 1.0f, 2f);
        ObjectAnimator anim2 = ObjectAnimator.ofFloat(ball, "scaleY", 1.0f, 2f);
        ObjectAnimator anim3 = ObjectAnimator.ofFloat(ball, "x",  cx ,  0f);
        ObjectAnimator anim4 = ObjectAnimator.ofFloat(ball, "x", cx);
        AnimatorSet animSet = new AnimatorSet();
        animSet.play(anim1).with(anim2);
        animSet.play(anim2).with(anim3);
        animSet.play(anim4).after(anim3);
        animSet.setDuration(1000);
        animSet.start();
    }
}
组合执行动效

视图动效。直接在控件上加配置

view_layout.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ImageView
        android:id="@+id/id_ball"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/ball_shape" />

    <Button
        android:layout_alignParentBottom="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="viewAnim"
        android:text="视图动效" />

    <Button
        android:layout_marginLeft="100dp"
        android:layout_alignParentBottom="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="propertyValuesHolder"
        android:text="属性值 " />

</RelativeLayout>
activity

public class ViewAnimateActivity extends Activity{
    private ImageView id_ball;
    private float mScreenHeight;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.view_layout);
        id_ball= (ImageView) findViewById(R.id.id_ball);

        DisplayMetrics outMetrics = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(outMetrics);
        mScreenHeight = outMetrics.heightPixels;
    }
    public void viewAnim(View view){
        id_ball.animate().alpha(0).y(mScreenHeight/2).setDuration(1000).withStartAction(new Runnable() {
            @Override
            public void run() {
            }
        }).withEndAction(new Runnable() {
            @Override
            public void run() {
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        id_ball.setY(0);
                        id_ball.setAlpha(1.0f);
                    }
                });
            }
        }).start();
    }
    public void propertyValuesHolder(View view){
        PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat("alpha", 1f, 0f, 1f);
        PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat("scaleX", 1f, 0, 1f);
        PropertyValuesHolder pvhZ = PropertyValuesHolder.ofFloat("scaleY", 1f, 0, 1f);
        ObjectAnimator.ofPropertyValuesHolder(id_ball, pvhX, pvhY,pvhZ).setDuration(1000).start();
    }
}
直接在控件后面加上配置。

视图进出时的动效

layout_anim.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/id_container"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="addBtn"
        android:text="addBtns" />

    <CheckBox
        android:id="@+id/id_appear"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:checked="true"
        android:text="APPEARING" />

    <CheckBox
        android:id="@+id/id_change_appear"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:checked="true"
        android:text="CHANGE_APPEARING" />

    <CheckBox
        android:id="@+id/id_disappear"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:checked="true"
        android:text="DISAPPEARING" />

    <CheckBox
        android:id="@+id/id_change_disappear"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:checked="true"
        android:text="CHANGE_DISAPPEARING " />

</LinearLayout>
activity

public class LayoutAnimaActivity extends Activity implements CompoundButton.OnCheckedChangeListener {
    private ViewGroup viewGroup;
    private GridLayout mGridLayout;
    private int mVal;
    private LayoutTransition mTransition;

    private CheckBox mAppear, mChangeAppear, mDisAppear, mChangeDisAppear;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.layout_anim);

        viewGroup = (ViewGroup) findViewById(R.id.id_container);

       mAppear = (CheckBox) findViewById(R.id.id_appear);
        mChangeAppear = (CheckBox) findViewById(R.id.id_change_appear);
        mDisAppear = (CheckBox) findViewById(R.id.id_disappear);
        mChangeDisAppear = (CheckBox) findViewById(R.id.id_change_disappear);

        mAppear.setOnCheckedChangeListener(this);
        mChangeAppear.setOnCheckedChangeListener(this);
        mDisAppear.setOnCheckedChangeListener(this);
        mChangeDisAppear.setOnCheckedChangeListener(this);
        mGridLayout=new GridLayout(this);
        mGridLayout.setColumnCount(5);
        viewGroup.addView(mGridLayout);
        mTransition=new LayoutTransition();
        mTransition.setAnimator(LayoutTransition.APPEARING,(mAppear.isChecked()?ObjectAnimator.ofFloat(this,"scaleX",0,1):null));
        mGridLayout.setLayoutTransition(mTransition);
    }

    public void addBtn(View view){
        final Button button=new Button(this);
        button.setText((++mVal)+"");
        mGridLayout.addView(button,Math.min(1,mGridLayout.getChildCount()));
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mGridLayout.removeView(button);
            }
        });
    }

    @Override
    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        mTransition=new LayoutTransition();
        mTransition.setAnimator(LayoutTransition.APPEARING,(mAppear.isChecked()? ObjectAnimator.ofFloat(this,"scaleX",0,1):null));
        mTransition.setAnimator(LayoutTransition.CHANGE_APPEARING,(mChangeAppear.isChecked()?mTransition.getAnimator(LayoutTransition.CHANGE_APPEARING):null));
        mTransition.setAnimator(LayoutTransition.DISAPPEARING,(mDisAppear.isChecked()?mTransition.getAnimator(LayoutTransition.DISAPPEARING):null));
        mTransition.setAnimator(LayoutTransition.CHANGE_DISAPPEARING,(mChangeDisAppear.isChecked()?mTransition.getAnimator(LayoutTransition.CHANGE_DISAPPEARING):null));
        mGridLayout.setLayoutTransition(mTransition);
    }
}
加上或者去除button的时候根据checkbox的选中状态加上动效。

最后一个是用ValueAnimator

value_layout.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/id_container">

    <ImageView
        android:id="@+id/id_ball"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/ball_shape" />

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:orientation="horizontal" >

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="verticalRun"
            android:text="垂直" />

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="paowuxian"
            android:text="抛物线" />

        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="fadeOut"
            android:text="淡出且删除" />

    </LinearLayout>

</RelativeLayout>
activity

public class ValueAnimatorActivity extends Activity{
    private ImageView id_ball;
    private float mScreenHeight;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.value_layout);
        DisplayMetrics outMetrics = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(outMetrics);
        mScreenHeight = outMetrics.heightPixels;
        id_ball= (ImageView) findViewById(R.id.id_ball);
    }

    /**
     * 垂直
     * @param view
     */
    public void verticalRun(View view){
        /*ValueAnimator animator = ValueAnimator.ofFloat(0, mScreenHeight - mBlueBall.getHeight());
        animator.setTarget(mBlueBall);
        animator.setDuration(1000).start();
        // animator.setInterpolator(value)
        animator.addUpdateListener(new AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                mBlueBall.setTranslationY((Float) animation.getAnimatedValue());
            }
        });*/
        ValueAnimator animator=ValueAnimator.ofFloat(0,mScreenHeight-id_ball.getHeight());
        animator.setTarget(id_ball);
        animator.setDuration(1000).start();
        animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                id_ball.setTranslationY((Float) animation.getAnimatedValue());
            }
        });
    }

    /**
     * 抛物线
     * @param view
     */
    public void paowuxian(View view){
        ValueAnimator valueAnimator = new ValueAnimator();
        valueAnimator.setDuration(3000);
        valueAnimator.setObjectValues(new PointF(0, 0));
        valueAnimator.setInterpolator(new LinearInterpolator());
        valueAnimator.setEvaluator(new TypeEvaluator<PointF>() {
            // fraction = t / duration
            @Override
            public PointF evaluate(float fraction, PointF startValue, PointF endValue) {
                // x方向200px/s ,则y方向0.5 * g * t (g = 100px / s*s)
                PointF point = new PointF();
                point.x = 200 * fraction * 3;
                point.y = 0.5f * 100 * (fraction * 3) * (fraction * 3);
                return point;
            }
        });

        valueAnimator.start();
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                PointF point = (PointF) animation.getAnimatedValue();
                id_ball.setX(point.x);
                id_ball.setY(point.y);
            }
        });
    }

    /**
     * 淡出且删除
     * @param view
     */
    public void fadeOut(View view){
        ObjectAnimator anim = ObjectAnimator.ofFloat(id_ball, "alpha", 0.5f);
        anim.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                ViewGroup parent = (ViewGroup) id_ball.getParent();
                if (parent != null)
                    parent.removeView(id_ball);
            }
        });

        anim.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {}

            @Override
            public void onAnimationRepeat(Animator animation) {}
            @Override
            public void onAnimationEnd(Animator animation) {
                ViewGroup parent = (ViewGroup) id_ball.getParent();
                if (parent != null)
                    parent.removeView(id_ball);
            }

            @Override
            public void onAnimationCancel(Animator animation) {}
        });
        anim.start();
    }
}

源代码

https://github.com/Maliola/AnimationTest

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值