动画——View Animation,Drawable Animation,Property Animation,LayoutTransition

本文详细介绍了Android中的三种动画:ViewAnimation、DrawableAnimation和PropertyAnimation的工作原理及实现方式,并着重讲解了如何利用XML和代码实现各种动画效果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

View Animation

View Animation(Tween Animation):补间动画,给出两个关键帧,通过一些算法将给定属性值在给定的时间内在两个关键帧间渐变。

View animation只能应用于View对象,而且只支持一部分属性,如支持缩放旋转而不支持背景颜色的改变。

而且对于View animation,它只是改变了View对象绘制的位置,而没有改变View对象本身,比如,你有一个Button,坐标(100,100),Width:200,Height:50,而你有一个动画使其变为Width:100,Height:100,你会发现动画过程中触发按钮点击的区域仍是(100,100)-(300,150)。

View Animation就是一系列View形状的变换,如大小的缩放,透明度的改变,位置的改变,动画的定义既可以用代码定义也可以用XML定义,当然,建议用XML定义。

可以给一个View同时设置多个动画,比如从透明至不透明的淡入效果,与从小到大的放大效果,这些动画可以同时进行,也可以在一个完成之后开始另一个。

用XML定义的动画放在/res/anim/文件夹内,XML文件的根元素可以为<alpha>,<scale>,<translate>,<rotate>,interpolator元素或<set>(表示以上几个动画的集合,set可以嵌套)。默认情况下,所有动画是同时进行的,可以通过startOffset属性设置各个动画的开始偏移(开始时间)来达到动画顺序播放的效果。

可以通过设置interpolator属性改变动画渐变的方式,如AccelerateInterpolator,开始时慢,然后逐渐加快。默认为AccelerateDecelerateInterpolator。

在代码中实现

透明度:

 AlphaAnimation animation = new AlphaAnimation(0.0f,1.0f);
                animation.setDuration(2000);
                imageView.startAnimation(animation);

平移:
注意:如果ImageView在LinearLayout分布中并且是垂直分布的,这样是不可以水平移动的。

TranslateAnimation animation = new TranslateAnimation(0,0,0,300);
 animation.setDuration(2000);
 imageView.startAnimation(animation);

旋转
RotateAnimation()有4个参数,也可以写2个,后两个是旋转中心,如果不填默认为以(0,0)点为旋转中心。

 RotateAnimation animation = new RotateAnimation(0,360,300,300);
animation.setDuration(2000);
imageView.startAnimation(animation);

缩放:
放缩参数:,1,2,为从x的0.5倍到1倍,3,4也是这个意思
默认是从imageView的左上角的点开始向右下角放缩的,5,6两个参数为缩放中心,它的缩放的方向根据在Imageview的位置的不同而不同。

 ScaleAnimation animation = new ScaleAnimation(1,2,1,2,100,100);
 animation.setDuration(2000); imageView.startAnimation(animation);

View Animation不但可以单独设置不同类型的动画而且可以组合设置,这就用到了AnimationSet,代码如下;

 AnimationSet set = new AnimationSet(false);
                TranslateAnimation animation1 = new TranslateAnimation(0,0,0,300);
                ScaleAnimation animation2 = new ScaleAnimation(1,2,1,2);
                RotateAnimation animation3  = new RotateAnimation(0,360,300,300);
                animation1.setDuration(3000);
                animation2.setDuration(3000);
                animation3.setDuration(3000);
                animation2.setStartOffset(3000);
                animation3.setStartOffset(6000);
                set.addAnimation(animation1);
                set.addAnimation(animation2);
                set.addAnimation(animation3);
                imageView.startAnimation(set);

在XML文件中实现:

)在res中新建一个文件夹(名字必须为ainm)。一般在android中不会显示,所以去project中的app——>src->main->src中找到。
2)在文件夹中新建一个文件,选择文件的类型为动画(Animation)
3)在这个XML文件中进行相应的设置:

<set xmlns:android="http://schemas.android.com/apk/res/android">
 <alpha android:duration="3000" android:fromAlpha="0.1" android:toAlpha="1" ></alpha>
 <translate android:duration="3000" android:fromYDelta="0" android:toYDelta="300" android:startOffset="3000"></translate>
 <rotate android:duration="3000"
     android:startOffset="6000"
     android:pivotX="300"
     android:pivotY="300"
     android:fromDegrees="0"
     android:toDegrees="360">
 </rotate>
 <scale android:fromXScale="1" android:toXScale="3"
     android:fromYScale="1" android:toYScale="3"
     android:startOffset="9000"
     android:duration="3000" ></scale>
</set>

4)在Activity中:

 Animation animation =   AnimationUtils.loadAnimation(getApplicationContext(), R.anim.animation_rotate);
 imageViewAnimation.startAnimation(animation);//iMagevIew与AlphaAnimation关联并开始

运行就可以了
duration为运行时间。
startOffset为延迟时间。
pivot 为中心点。

Drawable Animation

Drawable Animation不是我们的重点,老师并没有讲。这里摘录一些其他博文的内容:
Drawable Animation(Frame Animation):帧动画,就像GIF图片,通过一系列Drawable依次显示来模拟动画的效果。在XML中的定义方式如下:

<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
    android:oneshot="true">
    <item android:drawable="@drawable/rocket_thrust1" android:duration="200" />
    <item android:drawable="@drawable/rocket_thrust2" android:duration="200" />
    <item android:drawable="@drawable/rocket_thrust3" android:duration="200" />
</animation-list>

必须以为根元素,以表示要轮换显示的图片,duration属性表示各项显示的时间。XML文件要放在/res/drawable/目录下。示例:

protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        imageView = (ImageView) findViewById(R.id.imageView1);
        imageView.setBackgroundResource(R.drawable.drawable_anim);
        anim = (AnimationDrawable) imageView.getBackground();
    }

    public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            anim.stop();
            anim.start();
            return true;
        }
        return super.onTouchEvent(event);
    }

我在实验中遇到两点问题:

要在代码中调用Imageview的setBackgroundResource方法,如果直接在XML布局文件中设置其src属性当触发动画时会FC。
在动画start()之前要先stop(),不然在第一次动画之后会停在最后一帧,这样动画就只会触发一次。
最后一点是SDK中提到的,不要在onCreate中调用start,因为AnimationDrawable还没有完全跟Window相关联,如果想要界面显示时就开始动画的话,可以在onWindowFoucsChanged()中调用start()。

Property Animation

Property Animation从字面意思就是属性动画,也即是说通过改变对象的属性已达到动画的目的,这与View Animation是不一样的, View Animation实际上并没有达到改变View属性的目的。

引入其他博客的内容:


属性动画,这个是在Android 3.0中才引进的,它更改的是对象的实际属性,在View Animation(Tween Animation)中,其改变的是View的绘制效果,真正的View的属性保持不变,比如无论你在对话中如何缩放Button的大小,Button的有效点击区域还是没有应用动画时的区域,其位置与大小都不变。而在Property Animation中,改变的是对象的实际属性,如Button的缩放,Button的位置与大小属性值都改变了。而且Property Animation不止可以应用于View,还可以应用于任何对象。Property Animation只是表示一个值在一段时间内的改变,当值改变时要做什么事情完全是你自己决定的。

在Property Animation中,可以对动画应用以下属性:

Duration:动画的持续时间
TimeInterpolation:属性值的计算方式,如先快后慢
TypeEvaluator:根据属性的开始、结束值与TimeInterpolation计算出的因子计算出当前时间的属性值
Repeat Count and behavoir:重复次数与方式,如播放3次、5次、无限循环,可以此动画一直重复,或播放完时再反向播放
Animation sets:动画集合,即可以同时对一个对象应用几个动画,这些动画可以同时播放也可以对不同动画设置不同开始偏移
Frame refreash delay:多少时间刷新一次,即每隔多少时间计算一次属性值,默认为10ms,最终刷新时间还受系统进程调度与硬件的影响

这里有详细的表述地址:
http://www.cnblogs.com/angeldevil/archive/2011/12/02/2271096.html

这里我们重点描述的是:ObjectAnimator

ObjectAnimator

继承自ValueAnimator,要指定一个对象及该对象的一个属性,当属性值计算完成时自动设置为该对象的相应属性,即完成了Property Animation的全部两步操作。实际应用中一般都会用ObjectAnimator来改变某一对象的某一属性,但用ObjectAnimator有一定的限制,要想使用ObjectAnimator,应该满足以下条件:

对象应该有一个setter函数:set<PropertyName>(驼峰命名法)
如上面的例子中,像ofFloat之类的工场方法,第一个参数为对象名,第二个为属性名,后面的参数为可变参数,如果values…参数只设置了一个值的话,那么会假定为目的值,属性值的变化范围为当前值到目的值,为了获得当前值,该对象要有相应属性的getter方法:get<PropertyName>
如果有getter方法,其应返回值类型应与相应的setter方法的参数类型一致。

如果上述条件不满足,则不能用ObjectAnimator,应用ValueAnimator代替。

在代码中实现

我们可以在任何View上设置点击事件:
在XML的某个View的属性上设置: android:onClick=”startAnimation”
startAnimation是函数名(随便选)在Activity中建立一个相同类型名字的函数,在这个函数中进行一系列的操作,当点击这个View的时候就会启动这个函数。
例如在Activity中:

public void startAnimation(View view){

}

注意:这个函数的参数必须是View,这个view就是代表这个View。

在这个函数中建立 ObjectAnimator的对象,传入要变化的对象View,变化的属性,以及变化范围。代码如下:

 ObjectAnimator.ofFloat(imageView,"scaleX",1,2).setDuration(3000).start();
       ObjectAnimator animation= ObjectAnimator.ofFloat(imageView, "scaleY", 1, 2).setDuration(3000);
        animation.setStartDelay(3000);//设置延迟时间
        animation.start();//启动

在XML中实现:

在res中建立一个文件夹,名字无所谓,在文件夹下建立一个文件,文件的类型为animator。在这个文件中进行一系列的操作:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
 <objectAnimator android:propertyName="translationY"
     android:duration="3000"
     android:valueFrom="0"
     android:valueTo="300">

 </objectAnimator>
    <objectAnimator android:propertyName="rotationY" android:duration="3000" android:valueFrom="0" android:valueTo="360"></objectAnimator>

</set>

在代码中:

  Animator animator = AnimatorInflater.loadAnimator(getApplicationContext(), R.animator.animtor_scal);
     animator.setTarget(imageViewAnimation);
     animator.start();

这里的旋转只能沿着X轴,Y轴和中心进行旋转,不可以沿着某个设定的中心点进行旋转。

LayoutTransition

ViewGroup中的子元素可以通过setVisibility使其Visible、Invisible或Gone,当有子元素可见性改变时(VISIBLE、GONE),可以向其应用动画,通过LayoutTransition类应用此类动画:

transition.setAnimator(LayoutTransition.DISAPPEARING, customDisappearingAnim);

通过setAnimator应用动画,第一个参数表示应用的情境,可以以下4种类型:

APPEARING        当一个元素在其父元素中变为Visible时对这个元素应用动画
CHANGE_APPEARING    当一个元素在其父元素中变为Visible时,因系统要重新布局有一些元素需要移动,对这些要移动的元素应用动画
DISAPPEARING       当一个元素在其父元素中变为GONE时对其应用动画
CHANGE_DISAPPEARING   当一个元素在其父元素中变为GONE时,因系统要重新布局有一些元素需要移动,这些要移动的元素应用动画.

第二个参数为一Animator。

mTransitioner.setStagger(LayoutTransition.CHANGE_APPEARING, 30);

此函数设置动画延迟时间,参数分别为类型与时间。
代码如下:

 protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        add_View = (Button) findViewById(R.id.add_View);
        linearLayout_animation = (LinearLayout) findViewById(R.id.myAnimation);
        LayoutTransition transition = new LayoutTransition();
//        transition.setStagger();
        transition.setAnimator(LayoutTransition.APPEARING, AnimatorInflater.loadAnimator(getApplicationContext(),R.animator.myanimator));
//        linearLayout_animation.setLayoutTransition(transition);

        add_View.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                count++;
                final Button bnt = new Button(MainActivity.this);
                ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
                bnt.setLayoutParams(params);
//                bnt.setScaleX(0f);
//                bnt.setY(0f);
                bnt.setRotationX(30);
                bnt.setRotationY(40);
                bnt.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        linearLayout_animation.removeView(v);
                    }
                });
                bnt.setText("按钮"+count);
                linearLayout_animation.addView(bnt);
            }
        });
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值