安卓传统动画的介绍

动画的分类

总的来说,Android动画可以分为两类,最初的传统动画和Android3.0 之后出现的属性动画;
传统动画又包括 帧动画(Frame Animation)和补间动画(Tweened Animation)。

传统动画

帧动画

帧动画很容易理解,其实就是简单的由N张静态图片收集起来,然后通过控制依次显示这些图片,跟放电影的原理一样。
帧动画举例
Android中实现帧动画,一般先在Drawable目录下编写好指定的图片集合,然后代码中设置该Drawable,最后调用start()以及stop()开始或停止播放动画。
编写xml

<?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/a_0"
        android:duration="100" />
    <item
        android:drawable="@mipmap/a_1"
        android:duration="100" />
    <item
        android:drawable="@mipmap/a_2"
        android:duration="100" />
</animation-list>

oneshot属性指的是这个动画的执行次数,true的时候代表的是只执行一次,false无限循环。item里面的drawable设置图片资源,duration设置持续时间。
动画文件有了,接着到我们的布局文件:activity_frame_animation:

<?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/btn_start"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="开始" />

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

    <ImageView
        android:id="@+id/img_show"
        android:layout_width="120dp"
        android:layout_height="120dp"
        android:layout_gravity="center"
        android:background="@drawable/miao_gif" />

</LinearLayout>

最后是FrameAnimation.java,在这里控制动画的开始以及暂停:

public class FrameAnimation extends AppCompatActivity
        implements View.OnClickListener {

    private ImageView img_show;
    //实现帧动画的基本类
    private AnimationDrawable anim;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //设置布局文件
        setContentView(R.layout.activity_frame_animation);
        bindView();
    }

    private void bindView() {
        //绑定控件
        Button btn_start = findViewById(R.id.btn_start);
        Button btn_stop = findViewById(R.id.btn_stop);
        img_show=findViewById(R.id.img_show);
        //设置点击事件
        btn_start.setOnClickListener(this);
        btn_stop.setOnClickListener(this);
        //获取该控件上设置的动画文件
        anim= (AnimationDrawable) img_show.getBackground();
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.btn_start:
                //开始执行动画
                anim.start();
                break;
            case R.id.btn_stop:
                //停止动画
                anim.stop();
                break;
        }
    }
}

除了用xml方式实现,还可以用java代码的方式来实现:

    private ImageView img_show;
    private AnimationDrawable animationDrawable;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_frame_animation);
        bindView();
    }

    private void bindView() {

        Button btn_start = findViewById(R.id.btn_start);
        Button btn_stop = findViewById(R.id.btn_stop);
        img_show=findViewById(R.id.img_show);

        btn_start.setOnClickListener(this);
        btn_stop.setOnClickListener(this);

        //获取资源文件目录下的图片添加到animationDrawable中
        animationDrawable = new AnimationDrawable();
        for (int i = 0; i <= 2; i++) {
            int id = getResources().getIdentifier("a_" + i, "mipmap", getPackageName());
            Drawable drawable = getResources().getDrawable(id);
            animationDrawable.addFrame(drawable, 100);
        }
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.btn_start:
                animationDrawable.setOneShot(false);
                img_show.setBackground(null);
                img_show.setImageDrawable(animationDrawable);

                animationDrawable.start();
                break;
            case R.id.btn_stop:
                animationDrawable.setOneShot(true);
                img_show.setImageDrawable(animationDrawable);
                
                animationDrawable.stop();
                break;
        }
    }

补间动画

补间动画只需指定动画开始,以及动画结束, 而动画变化的"中间帧"则由系统计算并补齐。
补间动画分为四种,分别是AlphaAnimation 透明度渐变,ScaleAnimation 缩放渐变,TranslateAnimation 位移渐变,RotateAnimation 旋转渐变。还有一个是AnimationSet 组合渐变,前面四种的组合。

在说各种动画的用法之前,要先来讲解一个东西:Interpolator(插值器)。它用来控制动画的变化速度,可以理解成动画渲染器。Android中已经为我们提供了几个可供选择的实现类:

LinearInterpolator:动画以均匀的速度改变
AccelerateInterpolator:在动画开始的地方改变速度较慢,然后开始加速
AccelerateDecelerateInterpolator:在动画开始、结束的地方改变速度较慢,中间时加速
DecelerateInterpolator:在动画开始的地方改变速度较快,然后开始减速
AnticipateInterpolator:反向,先向相反方向改变一段再加速播放
AnticipateOvershootInterpolator:开始的时候向后然后向前甩一定值后返回最后的值
BounceInterpolator: 跳跃,快到目的值时值会跳跃,如目的值100,
后面的值可能依次为85,77,70,80,90,100
OvershottInterpolator:回弹,最后超出目的值然后缓慢改变到目的值

这些属性一般是在写动画xml文件时会用到,属性是:android:interpolator, 而上面对应的值是:@android:anim/linear_interpolator,就是驼峰命名法变下划线。

AlphaAnimation(透明度渐变)

anim_alpha.xml:

	<alpha xmlns:android="http://schemas.android.com/apk/res/android"
    android:interpolator="@android:anim/accelerate_decelerate_interpolator"
    android:fromAlpha="1.0"
    android:toAlpha="0.1"
    android:duration="2000"/>  

fromAlpha :起始透明度
toAlpha: 结束透明度
透明度的范围为:0-1,完全透明-完全不透明

新建布局文件activity_tween_animation.xml

<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/btn_alpha"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="透明度渐变" />
        
    <ImageView
        android:id="@+id/img_show"
        android:layout_width="75dp"
        android:layout_height="wrap_content"
        android:layout_gravity="center"
        android:src="@mipmap/img_face" />

</LinearLayout>

回到TweenAnimation.java文件中,绑定控件,开启动画:

//绑定控件
Button btn_alpha = (Button) findViewById(R.id.btn_alpha);

//加载动画文件
animation = AnimationUtils.loadAnimation(this,R.anim.anim_alpha);
//在图片上设置开始动画
img_show.startAnimation(animation);

java实现

 //透明度从1~0.1
 AlphaAnimation alphaAnimation = new AlphaAnimation(1.0f, 0.1f);
 //持续时间
 alphaAnimation.setDuration(2000);
 //开始执行
 img_show.startAnimation(alphaAnimation);

ScaleAnimation(缩放渐变)

anim_scale.xml:

<scale xmlns:android="http://schemas.android.com/apk/res/android"  
    android:interpolator="@android:anim/accelerate_interpolator"  
    android:fromXScale="0.2"  
    android:toXScale="1.5"  
    android:fromYScale="0.2"  
    android:toYScale="1.5"  
    android:pivotX="50%"  
    android:pivotY="50%"  
    android:duration="2000"/>

fromXScale/fromYScale:沿着X轴/Y轴缩放的起始比例
toXScale/toYScale:沿着X轴/Y轴缩放的结束比例
pivotX/pivotY:缩放的中轴点X/Y坐标,即距离自身左边缘的位置,比如50%就是以图像的 中心为中轴点。

xml方式,执行动画

Animation animation = AnimationUtils.loadAnimation(this,R.anim.anim_scale);
img_show.startAnimation(animation);

java方式实现

ScaleAnimation scaleAnimation =
                        new ScaleAnimation(0.2f, 1.5f, 0.2f, 1.5f,
                                Animation.RELATIVE_TO_SELF, 0.5f,
                                Animation.RELATIVE_TO_SELF, 0.5f);
//x轴0.2倍,x轴1.5倍,y轴0.2倍,y轴1.5倍,缩放的中轴点X/Y坐标
scaleAnimation.setDuration(2000);
img_show.startAnimation(scaleAnimation);

TranslateAnimation(位移渐变)

anim_translate.xml:

<translate xmlns:android="http://schemas.android.com/apk/res/android"  
    android:interpolator="@android:anim/accelerate_decelerate_interpolator"  
    android:fromXDelta="0"  
    android:toXDelta="320"  
    android:fromYDelta="0"  
    android:toYDelta="0"  
    android:duration="2000"/>

fromXDelta/fromYDelta:动画起始位置的X/Y坐标
toXDelta/toYDelta:动画结束位置的X/Y坐标

xml方式,执行动画

Animation  animation = AnimationUtils.loadAnimation(this, R.anim.anim_translate);
img_show.startAnimation(animation);

java方式实现

TranslateAnimation translateAnimation =
                        new TranslateAnimation(0, 320, 0, 0);
//起始x轴,最终x轴,起始y轴,最终y轴
translateAnimation.setDuration(2000);
img_show.startAnimation(translateAnimation);

RotateAnimation(旋转渐变)

anim_rotate.xml:

<rotate xmlns:android="http://schemas.android.com/apk/res/android"  
    android:interpolator="@android:anim/accelerate_decelerate_interpolator"  
    android:fromDegrees="0"  
    android:toDegrees="360"  
    android:duration="1000"  
    android:repeatCount="1"  
    android:repeatMode="reverse"/> 

fromDegrees/toDegrees:旋转的起始/结束角度
repeatCount:旋转的次数,默认值为0,代表一次,假如是其他值,比如3,则旋转4次 另外,值为-1或者infinite时,表示动画永不停止
repeatMode:设置重复模式,默认restart,但只有当repeatCount大于0或者infinite或-1时 才有效。还可以设置成reverse,表示偶数次显示动画时会做方向相反的运动。

xml方式,执行动画

Animation  animation = AnimationUtils.loadAnimation(this,R.anim.anim_rotate);
img_show.startAnimation(animation);

java方式实现

RotateAnimation rotateAnimation = new RotateAnimation(
                        0, 360, Animation.RELATIVE_TO_SELF,
                        0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
//旋转起始角度,旋转结束角度,相对与自身,x轴方向的一半,相对于自身,y轴方向的一半
rotateAnimation.setDuration(1000);
rotateAnimation.setRepeatCount(1);
rotateAnimation.setRepeatMode(Animation.REVERSE);
img_show.startAnimation(rotateAnimation);

AnimationSet(组合渐变)

anim_set.xml:

<set xmlns:android="http://schemas.android.com/apk/res/android"  
    android:interpolator="@android:anim/decelerate_interpolator"  
    android:shareInterpolator="true" >  
  
    <scale  
        android:duration="2000"  
        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="1000"  
        android:fromDegrees="0"  
        android:repeatCount="1"  
        android:repeatMode="reverse"  
        android:toDegrees="360" />  
  
    <translate  
        android:duration="2000"  
        android:fromXDelta="0"  
        android:fromYDelta="0"  
        android:toXDelta="320"  
        android:toYDelta="0" />  
  
    <alpha  
        android:duration="2000"  
        android:fromAlpha="1.0"  
        android:toAlpha="0.1" />  

</set> 

java方式实现

AnimationSet animationSet = new AnimationSet(true);
                animationSet.setDuration(1000);

AlphaAnimation alpha = new AlphaAnimation(0, 1);
alpha.setDuration(1000);
animationSet.addAnimation(alpha);

TranslateAnimation translate= new TranslateAnimation(0, 80, 0, 80);
translate.setDuration(1000);
animationSet.addAnimation(translate);

img_show.startAnimation(animationSet);

登陆注册按钮从底部弹出动画效果

首先是布局文件:activity_main.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:background="#DDE2E3">

    <LinearLayout
        android:id="@+id/start_ctrl"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:orientation="vertical"
        android:visibility="gone">

        <Button
            android:id="@+id/start_login"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="#F26968"
            android:gravity="center"
            android:paddingTop="15dp"
            android:paddingBottom="15dp"
            android:text="登陆"
            android:textColor="#FFFFFF"
            android:textSize="18sp" />

        <Button
            android:id="@+id/start_register"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="#323339"
            android:gravity="center"
            android:paddingTop="15dp"
            android:paddingBottom="15dp"
            android:text="注册"
            android:textColor="#FFFFFF"
            android:textSize="18sp" />
    </LinearLayout>

</RelativeLayout>

接着是LoginActivity.java:

public class LoginActivity extends AppCompatActivity {
    private LinearLayout start_ctrl;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);

        start_ctrl = (LinearLayout) findViewById(R.id.start_ctrl);
        //设置动画,从自身位置的最下端向上滑动了自身的高度,持续时间为500ms
        final TranslateAnimation ctrlAnimation = new TranslateAnimation(
                TranslateAnimation.RELATIVE_TO_SELF, 0, TranslateAnimation.RELATIVE_TO_SELF, 0,
                TranslateAnimation.RELATIVE_TO_SELF, 1, TranslateAnimation.RELATIVE_TO_SELF, 0);
        //设置动画的过渡时间
        ctrlAnimation.setDuration(1000L);    
        start_ctrl.postDelayed(new Runnable() {
            @Override
            public void run() {
                start_ctrl.setVisibility(View.VISIBLE);
                start_ctrl.startAnimation(ctrlAnimation);
            }
        }, 1000);

    }
}

添加购物车动画

anim_shop.xml:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <set>
        <!--第一阶段,先放大1.4倍再恢复原大小
        startOffset 延迟执行 -->
        <scale
            android:duration="300"
            android:fromXScale="1.0"
            android:fromYScale="1.0"
            android:pivotX="50.0%"
            android:pivotY="50.0%"
            android:toXScale="1.4"
            android:toYScale="1.4" />
        <scale
            android:duration="300"
            android:fromXScale="1.4"
            android:fromYScale="1.4"
            android:pivotX="50.0%"
            android:pivotY="50.0%"
            android:startOffset="300"
            android:toXScale="1.0"
            android:toYScale="1.0" />
    </set>
    <set>
        <!--第二阶段,位移到屏幕的右上角,在第一阶段执行结束之后开始执行
         100.0%p 是相对于父布局的x轴上的距离
         在位移的同时进行缩放跟透明度渐变的动画-->
        <translate
            android:duration="700"
            android:fromXDelta="0.0"
            android:fromYDelta="0.0"
            android:startOffset="600"
            android:toXDelta="100.0%p"
            android:toYDelta="-110%p" />

        <alpha
            android:duration="700"
            android:fromAlpha="1.0"
            android:startOffset="600"
            android:toAlpha="0.1" />

        <scale
            android:duration="700"
            android:fromXScale="1.0"
            android:fromYScale="1.0"
            android:pivotX="50.0%"
            android:pivotY="50.0%"
            android:startOffset="600"
            android:toXScale="0.4"
            android:toYScale="0.4" />
    </set>
</set>

布局文件 activity_shop_car.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@mipmap/shoppingcar"
    tools:context=".ShoppingCarActivity">

    <ImageView
        android:id="@+id/iv_show"
        android:layout_width="45dp"
        android:layout_height="45dp"
        android:layout_centerInParent="true"
        android:background="@mipmap/shopping_icon"
        android:visibility="gone">

    </ImageView>

    <Button
        android:id="@+id/btn_add"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:text="加入购物车"></Button>

</RelativeLayout>

ShoppingCarActivity.java:

public class ShoppingCarActivity extends AppCompatActivity {
    private Animation animation = null;
    private ImageView img_show;

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

        setContentView(R.layout.activity_shopping_car);

        img_show = findViewById(R.id.iv_show);

        findViewById(R.id.btn_add).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //缩略图控件设置可见
                img_show.setVisibility(View.VISIBLE);
                //开始执行动画
                animation = AnimationUtils.loadAnimation(ShoppingCarActivity.this,
                        R.anim.anim_shop);
                img_show.startAnimation(animation);
                //延迟执行
                new Handler().postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        animation.cancel();
                        img_show.setVisibility(View.GONE);
                    }
                }, 1300);

            }
        });

    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值