Android三种动画实现原理及使用

  • Android动画目前分为三种:

    1. Frame Animation 帧动画,通过顺序播放一系列图像从而产生动画效果,。图片过多时容易造成OOM(Out Of Memory内存用完)异常。
    2. Tween Animation 补间动画(又叫view动画),是通过对场景里的对象不断做图像变换(透明度、缩放、平移、旋转)从而产生动画效果,是一种渐进式动画,并且View动画支持自定义。
    3. Accribute Animation 属性动画,这也是在android3.0之后引进的动画,在手机的版本上是android4.0就可以使用这个动 画,通过动态的改变对象的属性从而达到动画效果。

  • 补间动画和属性动画的区别

补间动画只是改变了View的显示效果而已,并不会真正的改变View的属性。而属性动画可以改变View的显示效果和属性。举个例子:例如屏幕左上角有一个Button按钮,使用补间动画将其移动到右下角,此刻你去点击右下角的Button,它是绝对不会响应点击事件的,因此其作用区域依然还在左上角。只不过是补间动画将其绘制在右下角而已,而属性动画则不会。

  • 接下来就来详细了解一下这三种动画效果的用法:

FrameAnimation

帧动画是顺序播放一组预先定义好的图片,类似于电影播放,系统提供了一个类AnimationDrawable来使用帧动画,首先看一下效果演示:


1、首先在drawable里创建一个animation-list类型的xml文件,命名为frame_animation:其中oneshot是设置动画是否重复播放,设置false为确定重复播放。drawable设置不同的图片,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/img0"
        android:duration="50"/>
    <item
        android:drawable="@mipmap/img1"
        android:duration="50"/>
    <item
        android:drawable="@mipmap/img2"
        android:duration="50"/>
    <item
        android:drawable="@mipmap/img3"
        android:duration="50"/>
    <item
        android:drawable="@mipmap/img4"
        android:duration="50"/>
    <item
        android:drawable="@mipmap/img5"
        android:duration="50"/>
    <item
        android:drawable="@mipmap/img6"
        android:duration="50"/>
</animation-list>

2、设置布局文件activity_frame:定义开始播放和停止按钮和显示动画的布局。

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

    <Button
        android:id="@+id/start"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="开始" />

    <Button
        android:id="@+id/stop"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="停止" />

    <ImageView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/view"/>
</LinearLayout>

3、在FrameActivity中实现以下代码:

/**
 * 帧动画
 */
public class FrameActivity extends AppCompatActivity implements View.OnClickListener {
    private Button start;
    private Button stop;
    private ImageView view;
    private AnimationDrawable animationDrawable;//声明AnimationDrawable类

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

    private void initView() {
        start = findViewById(R.id.start);
        stop = findViewById(R.id.stop);
        view = findViewById(R.id.view);

        start.setOnClickListener(this);
        stop.setOnClickListener(this);

        // 通过逐帧动画的资源文件获得AnimationDrawable示例
        animationDrawable=(AnimationDrawable) getResources().getDrawable(R.drawable.frame_animation);
        // 把AnimationDrawable设置为ImageView的背景
        view.setBackgroundDrawable(animationDrawable);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.start:
                start();
                break;
            case R.id.stop:
                stop();
                break;
        }
    }

    protected void start() {
        if (animationDrawable != null && !animationDrawable.isRunning()) {//判断
            animationDrawable.start();
        }
    }

    protected void stop() {
        if (animationDrawable != null && animationDrawable.isRunning()) {
            animationDrawable.stop();
        }
    }
}

4、这样便可实现帧动画了,但帧动画比较容易引起OOM,所以在使用帧动画时,应尽量避免使用尺寸较大的图片。


Tween Animation

补间动画的四种变换效果对应Animation的四个子类:TranslateAnimation、ScaleAnimation、RotateAnimation、AlphaAnimation,这些动画可以通过XML来定义,也可以通过代码动态定义,以下示例通过XML定义的。



1、在res下创建一个anim文件夹,创建alpha类型xml文件用来实现动画透明度:

<?xml version="1.0" encoding="utf-8"?>
<alpha xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/accelerate_decelerate_interpolator"
    android:fromAlpha="1"//动画起始透明度
    android:toAlpha="0"//结束透明度
    android:duration="4000" />

2、创建scal类型xml文件用来实现缩放动画:

<?xml version="1.0" encoding="utf-8"?>
<scale xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/accelerate_decelerate_interpolator"
    android:duration="4000"
    android:fromXScale="0"//动画开始时的x坐标的伸缩尺寸
    android:fromYScale="0"
    android:toXScale="1.5"//动画结束时x坐标上的伸缩尺寸
    android:toYScale="1.5"
    android:pivotX="50%"//表示缩放起点x坐标,可以是整数值,百分数或者小数三种样式
    android:pivotY="0%"
    >
</scale>
3、创建scal类型xml文件用来实现位移动画:
<?xml version="1.0" encoding="utf-8"?>
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/accelerate_decelerate_interpolator"
    android:duration="4000"
    android:fromXDelta="0%"//动画起始时 X坐标上的位置 
    android:fromYDelta="100%"
    android:toXDelta="0%"//动画结束时 X坐标上的位置
    android:toYDelta="0%"
    >
</translate>

4、创建rotate类型xml文件用来实现旋转动画:    

<?xml version="1.0" encoding="utf-8"?>
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/accelerate_decelerate_interpolator"
    android:duration="4000"
    android:fromDegrees="0"//动画起始时物件的角度
    android:toDegrees="90"//动画结束时物件旋转的角度 可以大于360度
    android:pivotX="50%"//动画相对于物件的X坐标的开始位置
    android:pivotY="50%"
    >
</rotate>

5、创建set类型xml文件用来实现组合动画:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/decelerate_interpolator"
    android:shareInterpolator="true" >
    <scale
        android:duration="4000"
        android:fromXScale="0.2"
        android:fromYScale="0.2"
        android:pivotX="50%"
        android:pivotY="50%"
        android:toXScale="1.5"
        android:toYScale="1.5" />
    <rotate
        android:duration="4000"
        android:fromDegrees="0"
        android:pivotY="50%"
        android:pivotX="50%"
        android:toDegrees="360" />
    <translate
        android:duration="4000"
        android:fromXDelta="0"
        android:fromYDelta="0"
        android:toXDelta="320"
        android:toYDelta="0" />
    <alpha
        android:duration="4000"
        android:fromAlpha="1.0"
        android:toAlpha="0.1" />
</set>

6、创建布局文件

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

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="OnAlpha"
        android:text="透明度渐变AlphaAnimation" />

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:onClick="OnScale"
        android:text="缩放动画ScaleAnimation" />
    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:onClick="OnTranslate"
        android:text="位移动画TranslateAnimation" />
    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:onClick="OnRotate"
        android:text="旋转动画RotateAnimation" />
    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:onClick="OnSet"
        android:text="组合动画SetAnimation" />

    <ImageView
        android:id="@+id/tween_img"
        android:layout_gravity="center"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@mipmap/img"/>
</LinearLayout>

7、实现TweenActivityde中的代码

/**
 * Created by CXB on 2018/6/6.
 */

public class TweenActivity extends AppCompatActivity {
    private ImageView img;
    private Animation animation;//声明Animation类

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_tween);
        img = findViewById(R.id.tween_img);
    }

    /**
     * 透明度渐变
     *
     * @param view
     */
    public void OnAlpha(View view) {
        animation = AnimationUtils.loadAnimation(TweenActivity.this, R.anim.tween_alpha);
        img.startAnimation(animation);
    }

    /**
     * 缩放渐变
     *
     * @param view
     */
    public void OnScale(View view) {
        animation = AnimationUtils.loadAnimation(TweenActivity.this, R.anim.tween_scale);
        img.startAnimation(animation);
    }

    /**
     * 位移动画
     *
     * @param view
     */
    public void OnTranslate(View view) {
        animation = AnimationUtils.loadAnimation(TweenActivity.this, R.anim.tween_translate);
        img.startAnimation(animation);
    }

    /**
     * 旋转动画
     *
     * @param view
     */
    public void OnRotate(View view) {
        animation = AnimationUtils.loadAnimation(TweenActivity.this, R.anim.tween_rotate);
        img.startAnimation(animation);
    }

    /**
     * 组合动画
     *
     * @param view
     */
    public void OnSet(View view) {
        animation = AnimationUtils.loadAnimation(TweenActivity.this, R.anim.tween_set);
        img.startAnimation(animation);
    }
}


Attribute Animation

属性动画和View动画不同,它对作用对象进行了扩展,属性动画可以对任何对象做动画,动画的效果也也得到了加强,可以实现更加绚丽的动画效果。



1、设置布局文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/attri_root"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="OnAlpha"
        android:text="透明度渐变" />

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="OnScale"
        android:text="缩放" />

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="OnTranslate"
        android:text="位移" />

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="OnRotate"
        android:text="旋转" />

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="OnSet"
        android:text="组合动画" />

    <Button
        android:id="@+id/attri_show"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:text="属性动画的效果显示" />
</LinearLayout>

2、实现AttributeActivity中的代码:

/**
 * Created by CXB on 2018/6/7.
 */

public class AttributeActivity extends AppCompatActivity {
    private Button btn_show;
    private ObjectAnimator objectAnimator;//声明ObjectAimator类
    private LinearLayout ll_root;
    private float rotateDu = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_attribute);
        btn_show = findViewById(R.id.attri_show);
        ll_root = findViewById(R.id.attri_root);

    }

    /**
     * 透明度渐变
     *
     * @param view
     */
    public void OnAlpha(View view) {
        objectAnimator = ObjectAnimator.ofFloat(btn_show, "alpha", 1f, 0.8f, 0.7f, 0.2f, 0.1f);//布局,类型,渐变程度
        objectAnimator.setDuration(4000);
        objectAnimator.start();

    }

    /**
     * 缩放
     *
     * @param view
     */
    public void OnScale(View view) {
        objectAnimator = ObjectAnimator.ofFloat(btn_show, "scaleY", 1f, 2f, 3f, 4f, 3f, 2f, 1f);
        objectAnimator.setDuration(4000);
        objectAnimator.start();

    }

    /**
     * 位移
     *
     * @param view
     */
    public void OnTranslate(View view) {
        float width = ll_root.getWidth();//获取当前手机的的屏幕宽高
        objectAnimator = ObjectAnimator.ofFloat(btn_show, "translationX", width / 10, width / 9, width / 4, width / 3, width / 2, width);
        objectAnimator.setDuration(4000);
        objectAnimator.start();

    }

    /**
     * 旋转
     *
     * @param view
     */
    public void OnRotate(View view) {
        objectAnimator = ObjectAnimator.ofFloat(btn_show, "rotation", rotateDu, 360);
        objectAnimator.setDuration(2000);
        objectAnimator.setRepeatCount(100);//设置动画重复次数
        objectAnimator.setRepeatMode(ValueAnimator.RESTART);//动画重复模式
        objectAnimator.start();
    }

    /**
     * 组合动画
     *
     * @param view
     */
    public void OnSet(View view) {
        float height = ll_root.getHeight();
        ObjectAnimator objectAnimatorRotate = ObjectAnimator.ofFloat(btn_show, "rotation", rotateDu, 360);
        ObjectAnimator objectAnimatorTr = ObjectAnimator.ofFloat(btn_show, "translationY", height, height / 2, height / 3, height / 4, height / 5, height / 6);
        AnimatorSet animatorSet = new AnimatorSet();
        animatorSet.setDuration(4000);
        animatorSet.play(objectAnimatorRotate).with(objectAnimatorTr);
        animatorSet.start();
    }
}


源码下载:https://download.csdn.net/download/weixin_39001306/10465643

发布了4 篇原创文章 · 获赞 5 · 访问量 8568
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览