安卓Animation类与xml制作动画

有时要对控件添加一点动画效果,在安卓中,动画效果也是一个类,也就是Animation类。把动画效果这个类弄好后,在与控件类关联到一起,就可以实现控件有一些动作特效这样的效果了。动画效果的定义,要在xml文件中。

效果图:

屏幕录制有些卡顿。不过影响不大。

以上的例子其实只是用了ImageView这个控件,然后不同的控件用了逐渐放大,还有位置平移这个动作。

下面说说怎么实现:

先实例化Animation类:

 Animation myAnimation;

//通过loadAnimation函数 把动画效果的xml文件加载进来  实例化动作类
 myAnimation = AnimationUtils.loadAnimation(Selection.this, R.anim.my_anim);

  

实现xml文件(以下给出自带的4种特效):

alpha 渐变透明度动画效果

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android" >
    <alpha
        android:duration="1000"
        android:fromAlpha="0.0"
        android:toAlpha="1.0" />
    <!--
     透明度控制动画效果 alpha 渐变透明度动画效果
        浮点型值:
            fromAlpha 属性为动画起始时透明度
            toAlpha   属性为动画结束时透明度
            说明: 
                0.0表示完全透明
                1.0表示完全不透明
            以上值取0.0-1.0之间的float数据类型的数字
        
        长整型值:
            duration  属性为动画持续时间
            说明:     
                时间以毫秒为单位

    -->
</set>

scale 渐变尺寸伸缩动画效果

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

    <scale
        android:duration="1000"
        android:fillAfter="false"
        android:fromXScale="0.0"
        android:fromYScale="0.0"
        android:interpolator="@android:anim/accelerate_decelerate_interpolator"
        android:pivotX="50%"
        android:pivotY="50%"
        android:toXScale="1.4"
        android:toYScale="1.4" />

</set><!--
     尺寸伸缩动画效果 scale
       属性:interpolator 指定一个动画的插入器
        在我试验过程中,使用android.res.anim中的资源时候发现
        有三种动画插入器:
            accelerate_decelerate_interpolator  加速-减速 动画插入器
            accelerate_interpolator        加速-动画插入器
            decelerate_interpolator        减速- 动画插入器
        其他的属于特定的动画效果
      浮点型值:
         
            fromXScale 属性为动画起始时 X坐标上的伸缩尺寸    
            toXScale   属性为动画结束时 X坐标上的伸缩尺寸     
        
            fromYScale 属性为动画起始时Y坐标上的伸缩尺寸    
            toYScale   属性为动画结束时Y坐标上的伸缩尺寸    
        
            说明:
                 以上四种属性值    
    
                    0.0表示收缩到没有 
                    1.0表示正常无伸缩     
                    值小于1.0表示收缩  
                    值大于1.0表示放大
        
            pivotX     属性为动画相对于物件的X坐标的开始位置
            pivotY     属性为动画相对于物件的Y坐标的开始位置
        
            说明:
                    以上两个属性值 从0%-100%中取值
                    50%为物件的X或Y方向坐标上的中点位置
        
        长整型值:
            duration  属性为动画持续时间
            说明:   时间以毫秒为单位

        布尔型值:
            fillAfter 属性 当设置为true ,该动画转化在动画结束后被应用
-->

translate 画面转换位置移动动画效果

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

    <translate
        android:duration="2000"
        android:fromXDelta="30"
        android:fromYDelta="30"
        android:toXDelta="-80"
        android:toYDelta="300" />
    <!--
     translate 位置转移动画效果
        整型值:
            fromXDelta 属性为动画起始时 X坐标上的位置    
            toXDelta   属性为动画结束时 X坐标上的位置
            fromYDelta 属性为动画起始时 Y坐标上的位置
            toYDelta   属性为动画结束时 Y坐标上的位置
            注意:
                     没有指定fromXType toXType fromYType toYType 时候,
                     默认是以自己为相对参照物             
        长整型值:
            duration  属性为动画持续时间
            说明:   时间以毫秒为单位
-->

</set>

rotate 画面转移旋转动画效果

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

    <rotate
        android:duration="3000"
        android:fromDegrees="0"
        android:interpolator="@android:anim/accelerate_decelerate_interpolator"
        android:pivotX="50%"
        android:pivotY="50%"
        android:toDegrees="+350" />
    <!--
     rotate 旋转动画效果
       属性:interpolator 指定一个动画的插入器
             在我试验过程中,使用android.res.anim中的资源时候发现
             有三种动画插入器:
                accelerate_decelerate_interpolator   加速-减速 动画插入器
                accelerate_interpolator               加速-动画插入器
                decelerate_interpolator               减速- 动画插入器
             其他的属于特定的动画效果
                           
       浮点数型值:
            fromDegrees 属性为动画起始时物件的角度    
            toDegrees   属性为动画结束时物件旋转的角度 可以大于360度   

        
            说明:
                     当角度为负数——表示逆时针旋转
                     当角度为正数——表示顺时针旋转              
                     (负数from——to正数:顺时针旋转)   
                     (负数from——to负数:逆时针旋转) 
                     (正数from——to正数:顺时针旋转) 
                     (正数from——to负数:逆时针旋转)       

            pivotX     属性为动画相对于物件的X坐标的开始位置
            pivotY     属性为动画相对于物件的Y坐标的开始位置
                
            说明:        以上两个属性值 从0%-100%中取值
                         50%为物件的X或Y方向坐标上的中点位置

        长整型值:
            duration  属性为动画持续时间
            说明:       时间以毫秒为单位

    -->

</set>

 把Animation类和控件关联在一起

  

  
//控件开始动作
imgPic.startAnimation(myAnimation);

 挺简单的吧,只要先实现xml文件,定义好动作的类型。再通过loadAnimation函数,用xml文件实例化Animaiton类。然后再把animaiton类和控件类关联在一起,控件就会开始有动作效果了。

不过要注意的是:animation类只能运行在主线程中!!!!!!

而且我发现一个问题,直接在代码中加入动作效果,不会自动执行。并且如果同时定义了多个有动作效果的控件的话,他们是会同时执行的,那有什么办法可以按顺序执行呢?

结合到UI还有主线程的问题,很自然就想到了Handler类。

我的解决办法是:进入activity后,开启一个新线程,这个线程按我们的需求,发消息给Handler类来执行动作,这样就可以执行了。

这是在onCreate里面的代码:

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);

        //用于更新在主线程的UI
        handler = new Handler() {

            @Override
            public void handleMessage(Message msg) {
                super.handleMessage(msg);

                switch (msg.arg1){

                    case 0: {
                        myAnimation = AnimationUtils.loadAnimation(Selection.this, R.anim.my_anim);

                        imgPic.startAnimation(myAnimation);

                        imgPic.setVisibility(View.VISIBLE);
                             }break;


                    case 1: {

                        myAnimation = AnimationUtils.loadAnimation(Selection.this, R.anim.studio_anim);

                        LWGstudio.startAnimation(myAnimation);

                        LWGstudio.setVisibility(View.VISIBLE);
                    }break;








                    case 2: {

                        backAnimation = AnimationUtils.loadAnimation(Selection.this, R.anim.back_anim);

                        back.startAnimation(backAnimation);

                        back.setVisibility(View.VISIBLE);



                    }break;





                }




            }
        };

        //透明状态栏
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);

        imgPic = (ImageView)findViewById(R.id.ask);

        imgPic.setVisibility(View.INVISIBLE);

        back = (ImageView)findViewById(R.id.firstback);

        back.setVisibility(View.INVISIBLE);


        LWGstudio = (ImageView)findViewById(R.id.LWGstudio);

        LWGstudio.setVisibility(View.INVISIBLE);



                        new Thread(new Runnable() {
                            @Override
                            public void run() {

                                //进去隔一秒 出现askFood
                                try {
                                    Thread.sleep(1000);
                                } catch (InterruptedException e) {
                                    e.printStackTrace();
                                }

                                Message ok = new Message();
                                ok.arg1 = 0;//区分更新什么UI
                                handler.sendMessage(ok);


                                try {
                                    Thread.sleep(2000);
                                } catch (InterruptedException e) {
                                    e.printStackTrace();
                                }

                                //第一个动作执行后,隔两秒执行LWGstudio出现的动作
                                ok = new Message();
                                ok.arg1 = 1;//区分更新什么UI
                                handler.sendMessage(ok);

                                try {
                                    Thread.sleep(1000);
                                } catch (InterruptedException e) {
                                    e.printStackTrace();
                                }
                                
                                //最后出现全屏变绿的动作
                                ok = new Message();
                                ok.arg1 = 2;//区分更新什么UI
                                handler.sendMessage(ok);


                            }
                        }).start();










            }

  

原文地址:https://www.cnblogs.com/wzben/p/5150427.html