企业🤖AI Agent构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
# 8.4.1 Android动画合集之帧动画 ## 本节引言: > 从本节开始我们来探究Android中的动画,毕竟在APP中添加上一些动画,会让我们的应用变得 很炫,比如最简单的关开Activity,当然自定义控件动画肯定必不可少啦~而Android中的动画 分为三大类,**逐帧动画(Frame)**以及**补间动画(Tween)**,还有Android 3.0以后引入的**属性动画** **(Property)**,而本节给大家带来的是第一种动画——逐帧动画的一个基本使用~ ![](http://www.runoob.com/wp-content/uploads/2015/11/92102498.jpg) ## 1.帧动画概念以及用法 > 帧动画非常容易理解,其实就是简单的由N张静态图片收集起来,然后我们通过控制依次显示 这些图片,因为人眼"视觉残留"的原因,会让我们造成动画的"错觉",跟放电影的原理一样! > > 而Android中实现帧动画,一般我们会用到前面讲解到的一个Drawable:[AnimationDrawable](http://www.runoob.com/w3cnote/android-tutorial-drawable2.html) 先编写好Drawable,然后代码中调用start()以及stop()开始或停止播放动画~ > > 当然我们也可以在Java代码中创建逐帧动画,创建AnimationDrawable对象,然后调用 addFrame(Drawable frame,int duration)向动画中添加帧,接着调用start()和stop()而已~ > > 下面我们来写两个例子体会下帧动画的效果以及熟悉下用法 ## 2.使用示例: ### **示例一:最简单的例子**: **运行效果图**: ![](http://www.runoob.com/wp-content/uploads/2015/11/81922813.jpg) **代码实现**: 首先编写我们的动画文件,非常简单,先在res下创建一个anim目录,接着开始撸我们的 动画文件:**miao_gif.xml**: 这里的android:oneshot是设置动画是否只是播放一次,true只播放一次,false循环播放! ``` <?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/img_miao1" android:duration="80" /> <item android:drawable="@mipmap/img_miao2" android:duration="80" /> <item android:drawable="@mipmap/img_miao3" android:duration="80" /> <!--限于篇幅,省略其他item,自己补上--> ... </animation-list> ``` 动画文件有了,接着到我们的布局文件:**activity_main.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_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="@anim/miao_gif" /> </LinearLayout> ``` 最后是我们的**MainActivity.java**,这里在这里控制动画的开始以及暂停: ``` public class MainActivity extends AppCompatActivity implements View.OnClickListener { private Button btn_start; private Button btn_stop; private ImageView img_show; private AnimationDrawable anim; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); bindViews(); anim = (AnimationDrawable) img_show.getBackground(); } private void bindViews() { btn_start = (Button) findViewById(R.id.btn_start); btn_stop = (Button) findViewById(R.id.btn_stop); img_show = (ImageView) findViewById(R.id.img_show); btn_start.setOnClickListener(this); btn_stop.setOnClickListener(this); } @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; } } } ``` 好的,非常的简单哈~ ### 示例二:在指定地方播放帧动画 **运行效果图**: ![](http://www.runoob.com/wp-content/uploads/2015/11/90866559.jpg) **代码实现**: 依旧是先上我们的动画文件:**anim_zhuan.xml**: ``` <animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="true"> <item android:drawable="@mipmap/img_zhuan1" android:duration="80" /> <item android:drawable="@mipmap/img_zhuan2" android:duration="80" /> <item android:drawable="@mipmap/img_zhuan3" android:duration="80" /> <!--限于篇幅,省略其他item,自己补上--> ... </animation-list> ``` 接着我们来写一个自定义的ImageView:**FrameView.java**,这里通过反射获得当前播放的帧, 然后是否为最后一帧,是的话隐藏控件! ``` /** * Created by Jay on 2015/11/15 0015. */ public class FrameView extends ImageView { private AnimationDrawable anim; public FrameView(Context context) { super(context); } public FrameView(Context context, AttributeSet attrs) { super(context, attrs); } public FrameView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } public void setAnim(AnimationDrawable anim){ this.anim = anim; } public void setLocation(int top,int left){ this.setFrame(left,top,left + 200,top + 200); } @Override protected void onDraw(Canvas canvas) { try{ //反射调用AnimationDrawable里的mCurFrame值 Field field = AnimationDrawable.class .getDeclaredField("mCurFrame"); field.setAccessible(true); int curFrame = field.getInt(anim);// 获取anim动画的当前帧 if (curFrame == anim.getNumberOfFrames() - 1)// 如果已经到了最后一帧 { //让该View隐藏 setVisibility(View.INVISIBLE); } }catch (Exception e){e.printStackTrace();} super.onDraw(canvas); } } ``` 最后是我们的**MainActivity.java**,创建一个FrameLayout,添加View,对触摸事件中按下的 事件做处理,显示控件以及开启动画~ ``` public class MainActivity extends AppCompatActivity { private FrameView fView; private AnimationDrawable anim = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); FrameLayout fly = new FrameLayout(this); setContentView(fly); fView = new FrameView(this); fView.setBackgroundResource(R.anim.anim_zhuan); fView.setVisibility(View.INVISIBLE); anim = (AnimationDrawable) fView.getBackground(); fView.setAnim(anim); fly.addView(fView); fly.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { //设置按下时才产生动画效果 if(event.getAction() == MotionEvent.ACTION_DOWN){ anim.stop(); float x = event.getX(); float y = event.getY(); fView.setLocation((int) y - 40,(int)x-20); //View显示的位置 fView.setVisibility(View.VISIBLE); anim.start(); //开启动画 } return false; } }); } } ``` 好的,同样很简单哈~ ## 3.本节示例代码和Gif帧提取工具下载 [AnimationDemo1.zip](http://static.runoob.com/download/AnimationDemo1.zip) [AnimationDemo2.zip](http://static.runoob.com/download/AnimationDemo2.zip) [Gif帧提取工具](http://static.runoob.com/download/HA_AVD_Animated_GIF_producer_V5.2_FULL_Fix_ata.rar) ## 本节小结: > 好的,本节给大家介绍了一下Android三种动画中最简单的帧动画,实际开发用的并不多 不过学多点东西,以后也多个思路嘛~好的,本节就到这里,谢谢~