学必求其得,业必贵其专精。——章学成
我们学习的根本是懂得怎样为人处世,而对于我们的专业一定要坚持不懈的学习让其达到精益求精的地步,这样我们才能在这个技术层出不穷的社会上立足,前进。
接下来就进入正题 如有谬误欢迎批评指正,如有疑问欢迎留言,谢谢。
今天我们就来学习一下Android中的Frame动画,在学习这些基础的东西我们一定要参考谷歌给我们的文档,因为谷歌的文档是最权威的讲解。官网给出的Frame Animation动画的定义
Frame动画:包含一个接一个的将要显示的图片资源,这是一个传统的动画,它创建一个不同的图像序列,有顺序 的播放,就像一卷胶卷,我们称为帧动画。
从官网给出的定义我们不难看出其实Frame 动画就是一系列的图片的按照指定的顺序播放的过程,Frame动画可以被定义在XML中也可以,在代码中来实现。如果定义在XML中我们可以放在res/drawable/filename.xml或者res/anim/finename.xml,如果完全由代码实现的话,就要用到AnimationDrawable对象。
1.将动画定义在XML中官网给出的定义如下
<?xml version="1.0" encoding="utf-8"?> <animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot=["true" | "false"] > <item android:drawable="@[package:]drawable/drawable_resource_name" android:duration="integer" /> </animation-list>标签及属性说明:
<animation-list>必须元素,包含一个或多个<item>元素
.
<item> 一帧动画,必须有一个
<animation-list>父节点.
<? xml version= "1.0" encoding= "utf-8" ?> <animation-list xmlns:android ="http://schemas.android.com/apk/res/android" android:oneshot= "false"> <item android:drawable ="@drawable/qb_tenpay_loading_1" android:duration ="100" /> <item android:drawable ="@drawable/qb_tenpay_loading_2" android:duration ="100" /> <item android:drawable ="@drawable/qb_tenpay_loading_3" android:duration ="100" /> <item android:drawable ="@drawable/qb_tenpay_loading_4" android:duration ="100" /> <item android:drawable ="@drawable/qb_tenpay_loading_5" android:duration ="100" /> <item android:drawable ="@drawable/qb_tenpay_loading_6" android:duration ="100" /> <item android:drawable ="@drawable/qb_tenpay_loading_7" android:duration ="100" /> <item android:drawable ="@drawable/qb_tenpay_loading_8" android:duration ="100" /> <item android:drawable ="@drawable/qb_tenpay_loading_9" android:duration ="100" /> <item android:drawable ="@drawable/qb_tenpay_loading_10" android:duration ="100" /> <item android:drawable ="@drawable/qb_tenpay_loading_11" android:duration ="100" /> <item android:drawable ="@drawable/qb_tenpay_loading_12" android:duration ="100" /> </animation-list>然后布局
<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:orientation= "horizontal" tools:context= ".MainActivity" > <Button android:id= "@+id/btn_play" 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:layout_toRightOf= "@id/btn_play" android:text ="停止动画"/> <ImageView android:id= "@+id/iv_image" android:layout_width= "wrap_content" android:layout_height= "wrap_content" android:layout_centerInParent ="true" android:background= "@anim/frame" /> </RelativeLayout>假如我们把AnimationDrawable.start()方法放在onCreate方法下如下
package com.example.animationpractice; import android.app.Activity; import android.graphics.drawable.AnimationDrawable; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.ImageView; public class MainActivity extends Activity { Button btnPlay; ImageView ivImage; Button btnStop; private AnimationDrawable anim; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout. activity_main); btnPlay=(Button) findViewById(R.id. btn_play); ivImage=(ImageView) findViewById(R.id. iv_image); btnStop=(Button) findViewById(R.id. btn_stop); ivImage.setBackgroundResource(R.anim. frame); anim = (AnimationDrawable) ivImage.getBackground(); anim.start(); setClickListener(); } private void setClickListener() { btnStop.setOnClickListener( new OnClickListener() { @Override public void onClick(View v) { anim.stop(); } }); btnPlay.setOnClickListener( new OnClickListener() { @Override public void onClick(View v) { anim.start(); } }); } }然后运行在Android 2.3.3的模拟器上发现次动画只停留在第一帧,但是当我们点击启动动画按钮时动画会正常的播放(因为此时windows窗口已经完全初始化),然后我们代码不变将此工程运行在高版本上,我是运行在Android 4.1.2的模拟器上的,发现动画是正常播放的(并没有停留在第一帧)。但是为了兼容性更好,更安全我们最好将启动动画的代码写在onWindowFocusChanged方法中,代码如下
package com.example.animationpractice; import android.app.Activity; import android.graphics.drawable.AnimationDrawable; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.ImageView; public class MainActivity extends Activity { Button btnPlay; ImageView ivImage; Button btnStop; private AnimationDrawable anim; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout. activity_main); btnPlay=(Button) findViewById(R.id. btn_play); ivImage=(ImageView) findViewById(R.id. iv_image); btnStop=(Button) findViewById(R.id. btn_stop); setClickListener(); } private void setClickListener() { btnStop.setOnClickListener( new OnClickListener() { @Override public void onClick(View v) { //停止播放动画 anim.stop(); } }); btnPlay.setOnClickListener( new OnClickListener() { @Override public void onClick(View v) { //开始播放动画 anim.start(); } }); } @Override public void onWindowFocusChanged( boolean hasFocus) { super.onWindowFocusChanged(hasFocus); //将背景设置为动画 ivImage.setBackgroundResource(R.anim. frame); anim = (AnimationDrawable) ivImage.getBackground(); //启动动画 anim.start(); } }这样无论在高版本还是低版本动画的播放都是正常的。另外除了将
ivImage.setBackgroundResource(R.anim. frame); anim = (AnimationDrawable) ivImage.getBackground(); anim.start();这些代码放在onWindowFocusChanged方法中之外还有一种解决方法通过开启一个子线程的方式如
ivImage.post( new Runnable() { @Override public void run() { anim.start(); } });此时工程的代码如下
package com.example.animationpractice; import android.app.Activity; import android.graphics.drawable.AnimationDrawable; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.ImageView; public class MainActivity extends Activity { Button btnPlay; ImageView ivImage; Button btnStop; private AnimationDrawable anim; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout. activity_main); btnPlay=(Button) findViewById(R.id. btn_play); ivImage=(ImageView) findViewById(R.id. iv_image); btnStop=(Button) findViewById(R.id. btn_stop); ivImage.setBackgroundResource(R.anim. frame); anim = (AnimationDrawable) ivImage.getBackground(); ivImage.post( new Runnable() { @Override public void run() { anim.start(); } }); setClickListener(); } private void setClickListener() { btnStop.setOnClickListener( new OnClickListener() { @Override public void onClick(View v) { anim.stop(); } }); btnPlay.setOnClickListener( new OnClickListener() { @Override public void onClick(View v) { anim.start(); } }); } }这种可以也可以同时在低和高版本中运行。
package com.example.animationpractice; import android.app.Activity; import android.graphics.drawable.AnimationDrawable; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.ImageView; public class MainActivity extends Activity { Button btnPlay; ImageView ivImage; Button btnStop; private AnimationDrawable anim; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout. activity_main); ivImage=(ImageView) findViewById(R.id. iv_image); anim = new AnimationDrawable(); for ( int i = 1; i <=12; i++) { //根据资源名称和目录获取R.java中对应的资源ID int id = getResources().getIdentifier("qb_tenpay_loading_" + i, "drawable" , getPackageName()); //根据资源ID获取到 Drawable对象 Drawable drawable = getResources().getDrawable(id); //将此帧添加到AnimationDrawable中 anim.addFrame(drawable,100); } //设置循环播放 anim.setOneShot( false); //设置图片的背景为我们的动画 ivImage .setBackgroundDrawable (anim); } @Override public void onWindowFocusChanged( boolean hasFocus) { super.onWindowFocusChanged(hasFocus); //启动动画 anim.start(); } }同样我们需要注意将start()方法不要在窗口初始化的时候调用就行了。