[关闭]
@coder-pig 2015-11-15T13:43:30.000000Z 字数 4799 阅读 2016

Android基础入门教程——8.4.1 Android动画合集之帧动画

Android基础入门教程


本节引言:

从本节开始我们来探究Android中的动画,毕竟在APP中添加上一些动画,会让我们的应用变得
很炫,比如最简单的关开Activity,当然自定义控件动画肯定必不可少啦~而Android中的动画
分为三大类,逐帧动画(Frame)以及补间动画(Tween),还有Android 3.0以后引入的属性动画
(Property),而本节给大家带来的是第一种动画——逐帧动画的一个基本使用~


1.帧动画概念以及用法

帧动画非常容易理解,其实就是简单的由N张静态图片收集起来,然后我们通过控制依次显示
这些图片,因为人眼“视觉残留”的原因,会让我们造成动画的“错觉”,跟放电影的原理一样!
而Android中实现帧动画,一般我们会用到前面讲解到的一个Drawable:AnimationDrawable
先编写好Drawable,然后代码中调用start()以及stop()开始或停止播放动画~
当然我们也可以在Java代码中创建逐帧动画,创建AnimationDrawable对象,然后调用
addFrame(Drawable frame,int duration)向动画中添加帧,接着调用start()和stop()而已~
下面我们来写两个例子体会下帧动画的效果以及熟悉下用法


2.使用示例:

示例一:最简单的例子

运行效果图

代码实现

首先编写我们的动画文件,非常简单,先在res下创建一个anim目录,接着开始撸我们的
动画文件:miao_gif.xml
这里的android:oneshot是设置动画是否只是播放一次,true只播放一次,false循环播放!

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <animation-list xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:oneshot="false">
  4. <item
  5. android:drawable="@mipmap/img_miao1"
  6. android:duration="80" />
  7. <item
  8. android:drawable="@mipmap/img_miao2"
  9. android:duration="80" />
  10. <item
  11. android:drawable="@mipmap/img_miao3"
  12. android:duration="80" />
  13. <!--限于篇幅,省略其他item,自己补上-->
  14. ...
  15. </animation-list>

动画文件有了,接着到我们的布局文件:activity_main.xml

  1. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  2. android:layout_width="match_parent"
  3. android:layout_height="match_parent"
  4. android:orientation="vertical">
  5. <Button
  6. android:id="@+id/btn_start"
  7. android:layout_width="wrap_content"
  8. android:layout_height="wrap_content"
  9. android:text="开始" />
  10. <Button
  11. android:id="@+id/btn_stop"
  12. android:layout_width="wrap_content"
  13. android:layout_height="wrap_content"
  14. android:text="停止" />
  15. <ImageView
  16. android:id="@+id/img_show"
  17. android:layout_width="120dp"
  18. android:layout_height="120dp"
  19. android:layout_gravity="center"
  20. android:background="@anim/miao_gif" />
  21. </LinearLayout>

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

  1. public class MainActivity extends AppCompatActivity implements View.OnClickListener {
  2. private Button btn_start;
  3. private Button btn_stop;
  4. private ImageView img_show;
  5. private AnimationDrawable anim;
  6. @Override
  7. protected void onCreate(Bundle savedInstanceState) {
  8. super.onCreate(savedInstanceState);
  9. setContentView(R.layout.activity_main);
  10. bindViews();
  11. anim = (AnimationDrawable) img_show.getBackground();
  12. }
  13. private void bindViews() {
  14. btn_start = (Button) findViewById(R.id.btn_start);
  15. btn_stop = (Button) findViewById(R.id.btn_stop);
  16. img_show = (ImageView) findViewById(R.id.img_show);
  17. btn_start.setOnClickListener(this);
  18. btn_stop.setOnClickListener(this);
  19. }
  20. @Override
  21. public void onClick(View v) {
  22. switch (v.getId()) {
  23. case R.id.btn_start:
  24. anim.start();
  25. break;
  26. case R.id.btn_stop:
  27. anim.stop();
  28. break;
  29. }
  30. }
  31. }

好的,非常的简单哈~


示例二:在指定地方播放帧动画

运行效果图

代码实现

依旧是先上我们的动画文件:anim_zhuan.xml

  1. <animation-list xmlns:android="http://schemas.android.com/apk/res/android"
  2. android:oneshot="true">
  3. <item
  4. android:drawable="@mipmap/img_zhuan1"
  5. android:duration="80" />
  6. <item
  7. android:drawable="@mipmap/img_zhuan2"
  8. android:duration="80" />
  9. <item
  10. android:drawable="@mipmap/img_zhuan3"
  11. android:duration="80" />
  12. <!--限于篇幅,省略其他item,自己补上-->
  13. ...
  14. </animation-list>

接着我们来写一个自定义的ImageView:FrameView.java,这里通过反射获得当前播放的帧,
然后是否为最后一帧,是的话隐藏控件!

  1. /**
  2. * Created by Jay on 2015/11/15 0015.
  3. */
  4. public class FrameView extends ImageView {
  5. private AnimationDrawable anim;
  6. public FrameView(Context context) {
  7. super(context);
  8. }
  9. public FrameView(Context context, AttributeSet attrs) {
  10. super(context, attrs);
  11. }
  12. public FrameView(Context context, AttributeSet attrs, int defStyleAttr) {
  13. super(context, attrs, defStyleAttr);
  14. }
  15. public void setAnim(AnimationDrawable anim){
  16. this.anim = anim;
  17. }
  18. public void setLocation(int top,int left){
  19. this.setFrame(left,top,left + 200,top + 200);
  20. }
  21. @Override
  22. protected void onDraw(Canvas canvas) {
  23. try{
  24. //反射调用AnimationDrawable里的mCurFrame值
  25. Field field = AnimationDrawable.class
  26. .getDeclaredField("mCurFrame");
  27. field.setAccessible(true);
  28. int curFrame = field.getInt(anim);// 获取anim动画的当前帧
  29. if (curFrame == anim.getNumberOfFrames() - 1)// 如果已经到了最后一帧
  30. {
  31. //让该View隐藏
  32. setVisibility(View.INVISIBLE);
  33. }
  34. }catch (Exception e){e.printStackTrace();}
  35. super.onDraw(canvas);
  36. }
  37. }

最后是我们的MainActivity.java,创建一个FrameLayout,添加View,对触摸事件中按下的
事件做处理,显示控件以及开启动画~

  1. public class MainActivity extends AppCompatActivity {
  2. private FrameView fView;
  3. private AnimationDrawable anim = null;
  4. @Override
  5. protected void onCreate(Bundle savedInstanceState) {
  6. super.onCreate(savedInstanceState);
  7. FrameLayout fly = new FrameLayout(this);
  8. setContentView(fly);
  9. fView = new FrameView(this);
  10. fView.setBackgroundResource(R.anim.anim_zhuan);
  11. fView.setVisibility(View.INVISIBLE);
  12. anim = (AnimationDrawable) fView.getBackground();
  13. fView.setAnim(anim);
  14. fly.addView(fView);
  15. fly.setOnTouchListener(new View.OnTouchListener() {
  16. @Override
  17. public boolean onTouch(View v, MotionEvent event) {
  18. //设置按下时才产生动画效果
  19. if(event.getAction() == MotionEvent.ACTION_DOWN){
  20. anim.stop();
  21. float x = event.getX();
  22. float y = event.getY();
  23. fView.setLocation((int) y - 40,(int)x-20); //View显示的位置
  24. fView.setVisibility(View.VISIBLE);
  25. anim.start(); //开启动画
  26. }
  27. return false;
  28. }
  29. });
  30. }
  31. }

好的,同样很简单哈~


3.本节示例代码和Gif帧提取工具下载

AnimationDemo1.zip
AnimationDemo2.zip
Gif帧提取工具


本节小结:

好的,本节给大家介绍了一下Android三种动画中最简单的帧动画,实际开发用的并不多
不过学多点东西,以后也多个思路嘛~好的,本节就到这里,谢谢~

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注