[Android]开发App,你得知道这些4——动画

0.前言

  • 上一篇文章中,我们讲解了Android的触摸事件
    有兴趣的可以去看一看

准备工作

在读本文前,你最好有以下准备:

  • (1)安装Android Stuido(以下简称AS
  • (2)有一定的Java基础
  • (3)有一台安卓机
    (可以用模拟器来代替,包括AS自带的以及网上的一些著名模拟器)
  • 若想要了解有关Java的文章等其他主要知识,可以去看前面的文章

(不会使用AS的读者可以参考下面这篇文章中的例子)
[Java]开发安卓,你得掌握的Java知识2

1.本文内容简介

  • 关键帧动画

  • 补间动画

  • 属性动画

2.基础知识讲解

关键帧动画

  • 关键帧动画属于最无脑,最简单,又是最费美工功夫的动画

  • 所谓关键帧动画,就是事先准备好动画的每一帧的图片,然后将这些图片按顺序连起来播放,就会达成动画的效果。如下:

  • 这个动画就是通过准备好每一帧的火焰动画,连起来播放形成的

  • 无论是通过xml添加关键帧动画,还是通过java代码添加关键帧动画,都需要将动画的每一帧的图片加载一次

  • 具体如何操作,看第3部分

补间动画

  • 补间动画一般分为四个种:
    (1)平移translate
    (2)缩放 scale
    (3)旋转 rotate
    (4)透明度变换 alpha
  • 注意:补间动画只是一个效果,没有真正地改变属性的值(x与y坐标不变)。它只是一个视觉效果,这会影响到点击事件的触发
    如:

属性动画(ObjectAnimator)

  • Animator
         |----ValueAnimator
                   |-------ObjectAnimator
                   |-------TimeAnimator
    所有属性都可以做动画(包括系统属性与自定义属性)
    系统属性:alpha,scale,translation,Rotate(scale和translation只有X和Y和Z)
  • 属性动画也一般分为四个种:
    (1)平移translate
    (2)缩放 scale
    (3)旋转 rotate
    (4)透明度变换 alpha
  • 注意:属性动画不是一个效果,而是确实地改变了控件的对应属性(其视觉效果和补间动画一样)

3.具体操作

准备工作:


把这个地方改成Android,方便操作

关键帧动画(xml方法)

↓这里面是素材
https://pan.baidu.com/s/1Iruz9r0R4_omVAQE7zkYew
提取码:rc1z

第一步 导入动画的每一帧图片

把这些图片拖到drawable文件夹下


第二步 在drawable文件夹下创建xml文件
  • drawable处右键 --> New --> Drawable resource file


  • File name里面填上名字,其他基本不用管,然后点击确定



    最后会得到:



第三步 把selector改了
  • 将selector改为animation-list



第四步 加载每一帧的图片(加载所以图片)
  • 方法:在<animation-list></animation-list>里面,添加<item>
    如:
    <item android:drawable="@drawable/campfire01" android:duration="100"/>
    先输入<item,然后空格,选择drawable,然后选择对应的图片

  • 后面的android:duration表示该图片在动画中的持续时间(单位是毫秒)

  • 要将每一张图片都写进来



第五步 在layout文件中使用这个动画
  • 在layout中的activity_main这个xml文件中创建一个ImageView使用这个动画的xml(为了方便可以改成RelativeLayout)




第六步 在java代码中启动动画(具体代码下面黑框有)
  • 在java文件夹中的MainActivity文件中,找到上面的那个ImageView
    ImageView iv = findViewById(R.id.iv_animation);
  • 然后创建onTouchEvent(对控件添加监听器也行,这里直接对整个界面添加点击事件)
  • 通过id找到这个ImageView后,
    AnimationDrawable anim = (AnimationDrawable) iv.getDrawable();
  • 最后启动动画anim.start();
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            //1.获取动画的控件
            ImageView iv = findViewById(R.id.iv_animation);

            //2.通过控件获取动画
            AnimationDrawable anim = (AnimationDrawable) iv.getDrawable();

            //3.启动动画
            anim.start();
        }
        return true;
    }

(onTouchEvent记得写在onCreate()外面,即与onCreate()并排)
点击画面后,就会有动画效果了(跟上面一样,就不放图了)

关键帧动画(java代码方法)


//(1)创建一个动画资源(AnimationDrawable)
 AnimationDrawable anim = new AnimationDrawable();

 //(2)添加每一帧的动画
int[] resID = {R.drawable.campfire01,R.drawable.campfire02,R.drawable.campfire03,R.drawable.campfire04,R.drawable.campfire05,R.drawable.campfire06
        ,R.drawable.campfire07,R.drawable.campfire08,R.drawable.campfire09,R.drawable.campfire10,R.drawable.campfire11,R.drawable.campfire12,R.drawable.campfire13
        ,R.drawable.campfire14,R.drawable.campfire15,R.drawable.campfire16,R.drawable.campfire17};
for (int i = 0; i < 16; i++) {
            anim.addFrame(getResources().getDrawable(resID[i],null),100);
        }

//(3)使用这个动画资源
ImageView iv = findViewById(R.id.iv_animation);
iv.setImageDrawable(anim);


//(4)启动动画
anim.start();

  • 这里大概说一下思路
    (因为关键帧动画用得不多,毕竟很费美工功夫)
  • (1)先创建一个AnimationDrawable对象anim
  • (2)用一个数组将drawable里面的每一帧动画都装进去
  • (3) anim.addFrame()来加载每一帧图片
  • (4)创建一个新的ImageView控件,设置它的ImageDrawable为上面那个anim
  • (5)anim.start()启动动画

补间动画

  • 补间动画也有两种处理方式,一种是通过xml,一种是java代码
  • 前者适合于一些定死的动画
  • 后者的话,在java代码中可以进行计算、表达式书写等,因此比较灵活

补间动画(java代码方式)

第一步 先通过id找到对应控件

ImageView rightArm = findViewById(R.id.iv_right_arm);
(记得现在xml里面添加id,不知道如何添加的同学,可以去看以前的文章)

第二步 创建(对应的)动画的对象

RotateAnimation rightRoAnimation = new RotateAnimation(0,180,0f,0f);

  • 如果是平移,则使用TranslateAnimation
    调整透明度用AlphaAnimation
    缩放变化用ScaleAnimation
    如:
    TranslateAnimation tr = new TranslateAnimation(0,100,0,100);
  • 每一种变化的参数都是不一样的,可以通过alt+p来确认参数
第三步 设置动画属性

rightRoAnimation.setDuration(1000);
rightRoAnimation.setFillAfter(true);
setDuration指设置动画演出持续时间
setFillAfter指设置动画结束后,控件是否停留在结束的地方(为真时,则停留),毕竟补间动画不会真正改变控件的属性

第四步 开始动画

rightArm.startAnimation(rightRoAnimation);
(这一步可以考虑放在onTouchEvent里面,这样子就可以点击的时候触发一次动画)

ImageView rightArm = findViewById(R.id.iv_right_arm);
RotateAnimation rightRoAnimation = new RotateAnimation(0,180,0f,0f);
rightRoAnimation.setDuration(1000);
rightRoAnimation.setFillAfter(true);
rightArm.startAnimation(rightRoAnimation);

补间动画(xml文件方法)

第一步 修改项目浏览方式
  • 首先将Android改为project




第二步 找到对应文件夹
  • 找到项目名下面的app --> src


  • 找到src --> main --> res
    在res文件夹下创建一个anim文件夹




第三步 在anim文件夹上,

右键-->New-->Animation resource File,然后起名





第四步 更改set为对应的动画名字
  • 如将set改为平移动画
    <translate xmlns:android="http://schemas.android.com/apk/res/android"> </translate>
第五步 添加动画属性
<translate xmlns:android="http://schemas.android.com/apk/res/android"
    android:fromYDelta="100"
    android:toYDelta="0"
    android:fillAfter="true"
    android:duration="500">
</translate>
  • 注意,这些属性是添加在前面一个标签的两个<>中的,而不是添加在两个<translate></translate>标签中
  • 另外,其他动画的话就不是translate,而是:
    <alpha
    <scale
    <rotate
    分别对应透明度、缩放、旋转


第六步 在java代码中加载xml文件中的补间动画
//(1)创建ImageView对象
ImageView leftHand = findViewById(R.id.iv_left_hand);
ImageView rightHand = findViewById(R.id.iv_right_hand);

//(2)通过AnimationUtils创建对应的动画对象
TranslateAnimation up = (TranslateAnimation) AnimationUtils.loadAnimation(this,R.anim.hand_up_anim);

//(3)通过AnimationUtils创建对应的动画对象
leftHand.startAnimation(up);
rightHand.startAnimation(up);

补间动画总结:

(1)java代码方式(灵活一些)

①创建动画对象(构造函数里设置基础属性)
②通过动画对象的setXXX()来设置一些其他属性(如setDuration())
③通过id(等方法)找到控件,然后startAnimation(动画对象);来开启动画

(2)xml方式(死板一些,但是便于多次调用)

①在对应的地方(app-->src-->main-->res)中创建anim文件夹,然后在anim文件夹中,创建Animation resource File(xml文件)
②把set改为对应动画名字(当然如果是多个动画,可以把set保留,然后在set里面写多个不同的动画标签)
③在前一个标签里面添加属性
④在MainActivity中,通过AnimationUtils创建对应的动画对象
⑤通过id(等方法)找到控件,然后startAnimation(动画对象);来开启动画

属性动画(只能通过java代码)

第一步 在MainActivity中创建属性动画对象

ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(参数);

  • ofFloat还是ofDouble什么的,看改变的属性的参数的类型,上面讲的那些系统提供的属性(平移、缩放等),参数都是float类型的
特别注意:ofFloat()的括号内的参数的顺序为:

target、propertyName、......values
(1)target需要动画的控件
(2)propertyName 动画的哪个属性(这个可以通过控件.get动画名(),因为控件必须实现动画名的getter,setter
(3)...values 变化的值

注意:

  • (2)里面的意思是,可以先输入控件对象,然后输入一个点".",然后输入对应set+动画的前面一部分,就可以看到完整的名字了,这个名字,就是propertyName需要填写的
  • 比如需要scale方面的,就那么,propertyName中就写"ScaleX"或者"ScaleY"(必须打上引号,这个参数是String)


  • 如果propertyName中名字写错了,会报错
  • (3)中的values为具体的值(比如从多少变化为多少),一般第一个参数为初始值,第二个为变化后的值
  • 如果values里面只填一个参数,那么就是“变化到多少”
第二步 通过属性动画对象设置别的属性(如持续时间)

objectAnimator.setDuration(1000);

第三步 开启动画

objectAnimator.start();

public void testTranslate(){
        ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(v_v,"TranslationX",v_v.getTranslationX()+100f);
        objectAnimator.setDuration(1000);
        objectAnimator.start();
    }
  • 全部代码:
    //声明控件变量
    private View v_v;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

       //通过findViewById找到对应控件
        v_v = findViewById(R.id.v_v);

       //为控件添加监听器
        v_v.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                testTranslate();
            }
        });
    }

     /*
     * 这是一个平移的属性的动画
     */
     public void testTranslate(){
     //ofFloat()中的参数意思:v_v为控件名 
     //"TranslationX"为动画名(必须带引号)
     //v_v.getTranslationX()+100f为移动到哪里(这么写是为了可以每次点击都能继续移动)
        ObjectAnimator objectAnimator = ObjectAnimator.ofFloat(v_v,"TranslationX",v_v.getTranslationX()+100f);
        objectAnimator.setDuration(1000);
        objectAnimator.start();
    }

3.总结

(1)关键帧动画其实比较少用,重点要掌握补间动画和属性动画
(2)补间动画只是视觉效果,无论怎么看起来怎么样,控件的实际位置、大小、透明度等都没有变化
(3)以上说的例子都是很基础的动画,熟练掌握之后,将各种动画糅合在一起,也可以达成一些不错的效果

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342

推荐阅读更多精彩内容