【Android基础】动画

Android里的动画分为两类,以3.0版本为分水岭。

3.0前已存在

  • 帧动画
  • 补间动画

3.0出现

  • 属性动画

帧动画

顾名思义,快速切换几张图片来达到动画的效果。

建立帧动画xml

Note:不要把这个帧动画文件放到anim文件夹中,要放到drawable文件夹中

<?xml version="1.0" encoding="utf-8"?>
<animation-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:drawable="@drawable/a_0"
        android:duration="100"></item>
    <item
        android:drawable="@drawable/a_1"
        android:duration="200"></item>
    <item
        android:drawable="@drawable/a_2"
        android:duration="300"></item>
</animation-list>

java中启动动画

public class FrameAnimActivity extends AppCompatActivity {

    private ImageView iv_anim;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_frame);
        initView();
    }

    private void initView() {
        iv_anim = (ImageView) findViewById(R.id.iv_anim);
        iv_anim.setImageResource(R.drawable.frame_anim);
        AnimationDrawable animationDrawable = (AnimationDrawable) iv_anim.getDrawable();
        animationDrawable.start();
    }
}

android:oneshot=”false” ,这个oneshot 的含义就是动画执行一次(true)还是循环执行多次。

补间动画 Tweened Animation

alpha 淡入淡出

XML声明动画

<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
       android:duration="1000"
       android:fromAlpha="1.0"
       android:interpolator="@android:anim/accelerate_decelerate_interpolator"
       android:toAlpha="0.0"/>

Note:AS的自动补全对除了fromAlpha及toAlpha均不予默认支持,但是如duration,interpolator仍旧是存在的。

Java中启动动画

 ImageView iv_alpha_cat = (ImageView) findViewById(R.id.iv_alpha_cat);
 Animation alphaCat = AnimationUtils.loadAnimation(this, R.anim.anim_alpha_cat);
 iv_alpha_cat.startAnimation(alphaCat);

translate 平移

<?xml version="1.0" encoding="utf-8"?>
<translate
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1000"
    android:fromXDelta="300"
    android:fromYDelta="300"
    android:toXDelta="0"
    android:toYDelta="0">
</translate>
  • 无论是fromXDelta还是toXDelta的值都是**相对**View原始位置的X,Y距离。
  • 如果不加android:duration ,动画是不执行的。

rotate 旋转

<?xml version="1.0" encoding="utf-8"?>
<rotate
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1000"
    android:fromDegrees="0"
    android:pivotX="10%"
    android:pivotY="10%"
    android:repeatCount="infinite"
    android:repeatMode="reverse"
    android:toDegrees="60">

</rotate>

scale 缩放

<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
       android:duration="1000"
       android:fromXScale="0.5"
       android:fromYScale="0.5"
       android:repeatCount="infinite"
       android:repeatMode="reverse"
       android:toXScale="1.5"
       android:toYScale="1.5"
    >

</scale>

动画集合

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <alpha
        android:duration="1000"
        android:fromAlpha="1.0"
        android:interpolator="@android:anim/accelerate_decelerate_interpolator"
        android:repeatCount="infinite"
        android:repeatMode="reverse"
        android:toAlpha="0.0"/>

    <rotate
        android:duration="1000"
        android:fromDegrees="0"
        android:pivotX="10%"
        android:pivotY="10%"
        android:repeatCount="infinite"
        android:repeatMode="reverse"
        android:toDegrees="60">

    </rotate>

    <scale
        android:duration="1000"
        android:fromXScale="0.5"
        android:fromYScale="0.5"
        android:repeatCount="infinite"
        android:repeatMode="reverse"
        android:toXScale="1.5"
        android:toYScale="1.5"
        >
    </scale>

    <translate
        android:duration="1000"
        android:fromXDelta="300"
        android:fromYDelta="300"
        android:repeatCount="infinite"
        android:repeatMode="reverse"
        android:toXDelta="0"
        android:toYDelta="0">
    </translate>
</set>

几个公用的属性

糟糕的是,as下不会自动提示或补全这些属性,所以得自己记住。

重复性设置

android:repeatCount="infinite"
android:repeatMode="reverse"

轴心点设置

android:pivotX="10%"
android:pivotY="10%"

image

速率设置 Interpolator

android:interpolator="@android:anim/accelerate_decelerate_interpolator"

间隔时间 startOffset

动画多次执行的间隔时间,如果只执行一次,执行前会暂停这段时间

属性动画

 iv_alpha_cat = (ImageView) findViewById(R.id.iv_alpha_cat);
        ObjectAnimator alphaAnimator = ObjectAnimator.ofFloat(iv_alpha_cat, "alpha", 0, 0.9f);
        alphaAnimator.setDuration(1000);
        alphaAnimator.setRepeatCount(ValueAnimator.INFINITE);
        alphaAnimator.setRepeatMode(ValueAnimator.REVERSE);
        alphaAnimator.start();


        iv_trans_cat = (ImageView) findViewById(R.id.iv_trans_cat);
        ObjectAnimator transAnimator = ObjectAnimator transAnimator = ObjectAnimator.ofFloat(iv_trans_cat, "translationX", 400, 0, 300, 0, 200);
        transAnimator.setDuration(1000);
        transAnimator.setRepeatCount(ValueAnimator.INFINITE);
        transAnimator.setRepeatMode(ValueAnimator.REVERSE);
        transAnimator.start();

如上是实现渐变及平移的代码。
* 有意思的是,在平移的动画操作中,设置多个值的时候,动画会在多个位置值中移动,如上 200->0->400 居然能变成弹跳的效果。

其他及组合实现

 ObjectAnimator alphaAnim = ObjectAnimator.ofFloat(myView, "alpha", 1.0f, 0.5f, 0.8f, 1.0f);
                ObjectAnimator scaleXAnim = ObjectAnimator.ofFloat(myView, "scaleX", 0.0f, 1.0f);
                ObjectAnimator scaleYAnim = ObjectAnimator.ofFloat(myView, "scaleY", 0.0f, 2.0f);
                ObjectAnimator rotateAnim = ObjectAnimator.ofFloat(myView, "rotation", 0, 360);
                ObjectAnimator transXAnim = ObjectAnimator.ofFloat(myView, "translationX", 100, 400);
                ObjectAnimator transYAnim = ObjectAnimator.ofFloat(myView, "tranlsationY", 100, 750);
                AnimatorSet set = new AnimatorSet();
                set.playTogether(alphaAnim, scaleXAnim, scaleYAnim, rotateAnim, transXAnim, transYAnim);
//                set.playSequentially(alphaAnim, scaleXAnim, scaleYAnim, rotateAnim, transXAnim, transYAnim);
                set.setDuration(3000);
                set.start();

属性动画 补间及帧动画 优与劣

  • 从上面两幅图比较可以发现,补间动画中,虽然使用translate将图片移动了,但是点击原来的位置,依旧可以发生点击事件,而属性动画却不是。因此我们可以确定,属性动画才是真正的实现了view的移动,补间动画对view的移动更像是在不同地方绘制了一个影子,实际的对象还是处于原来的地方

  • 当我们把动画的repeatCount设置为无限循环时,如果在Activity退出时没有及时将动画停止,属性动画会导致Activity无法释放而导致内存泄漏,而补间动画却没有问题。因此,使用属性动画时切记在Activity执行 onStop 方法时顺便将动画停止。(对这个怀疑的同学可以自己通过在动画的Update 回调方法打印日志的方式进行验证)。

  • xml 文件实现的补间动画,复用率极高。在Activity切换,窗口弹出时等情景中有着很好的效果。

  • 使用帧动画时需要注意,不要使用过多特别大的图,容易导致内存不足。

详解见:【Android基础】从属性动画看代码设计的艺术

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值