Android Canvas上的动画

当自定义View的时候,可以利用Canvas给View添加一些动画效果。

下面的例子,是在屏幕上绘制一个红色的小方块,这个小方块会在屏幕上面“乱跳”。

知识点

使用到的知识点:

(1) 在View的子类的draw()中调用invalidate(),可以让View对象一直保持重绘状态,从而可以使Canvas一直处于绘画过程中。

(2) Canvas的绘制功能,例如绘制Rect、Circle、Path等。

(3) 小方块碰撞屏幕边缘的算法。

实现

小方块视图。

继承View类,重写onDraw()方法,并提供一些setter和getter方法,用于设置小方块的属性。判断碰撞事件的逻辑在moveTo()方法中。代码如下:

  1 public class Rectangle extends View {
  2     public static final int MAX_SIZE = 40;
  3     private static final int ALPHA = 255;
  4     private int mCoordX = 0;
  5     private int mCoordY = 0;
  6     private int mRealSize = 40;
  7     private int mSpeedX = 3;
  8     private int mSpeedY = 3;
  9
 10     private boolean goRight = true;
 11     private boolean goDown = true;
 12     private DrawView mDrawView;
 13
 14     private Paint mInnerPaint;
 15     private RectF mDrawRect;
 16
 17     public Rectangle(Context context, DrawView drawView) {
 18         super(context);
 19         mDrawView = drawView;
 20
 21         mInnerPaint = new Paint();
 22
 23         mDrawRect = new RectF();
 24
 25         /* Red is default */
 26         mInnerPaint.setARGB(ALPHA, 255, 0, 0);
 27         mInnerPaint.setAntiAlias(true);
 28     }
 29
 30     public void setARGB(int a, int r, int g, int b) {
 31         mInnerPaint.setARGB(a, r, g, b);
 32     }
 33
 34     public void setX(int newValue) {
 35         mCoordX = newValue;
 36     }
 37
 38     public float getX() {
 39         return mCoordX;
 40     }
 41
 42     public void setY(int newValue) {
 43         mCoordY = newValue;
 44     }
 45
 46     public float getY() {
 47         return mCoordY;
 48     }
 49
 50     public void move() {
 51         moveTo(mSpeedX, mSpeedY);
 52     }
 53
 54     private void moveTo(int goX, int goY) {
 55
 56         // check the borders, and set the direction if a border has reached
 57         if (mCoordX > (mDrawView.width - MAX_SIZE)) {
 58             goRight = false;
 59         }
 60
 61         if (mCoordX < 0) {
 62             goRight = true;
 63         }
 64
 65         if (mCoordY > (mDrawView.height - MAX_SIZE)) {
 66             goDown = false;
 67         }
 68         if (mCoordY < 0) {
 69             goDown = true;
 70         }
 71
 72         // move the x and y
 73         if (goRight) {
 74             mCoordX += goX;
 75         } else {
 76             mCoordX -= goX;
 77         }
 78         if (goDown) {
 79             mCoordY += goY;
 80         } else {
 81             mCoordY -= goY;
 82         }
 83
 84     }
 85
 86     public int getSpeedX() {
 87         return mSpeedX;
 88     }
 89
 90     public void setSpeedX(int speedX) {
 91         mSpeedX = speedX;
 92     }
 93
 94     public int getmSpeedY() {
 95         return mSpeedY;
 96     }
 97
 98     public void setSpeedY(int speedY) {
 99         mSpeedY = speedY;
100     }
101
102     @Override
103     protected void onDraw(Canvas canvas) {
104         super.onDraw(canvas);
105
106         mDrawRect.set(mCoordX, mCoordY, mCoordX + mRealSize, mCoordY
107                 + mRealSize);
108         canvas.drawRoundRect(mDrawRect, 0, 0, mInnerPaint);
109
110     }
111
112     public void setSize(int newSize) {
113         mRealSize = newSize;
114     }
115
116     public int getSize() {
117         return mRealSize;
118     }
119 }

外层视图。

小方块是一个独立的视图,这里不直接把小方块显示在Actiity中,在它的外面又“包”了一层。代码如下:

 1 public class DrawView extends View {
 2     private Rectangle mRectangle;
 3
 4     public int width;
 5
 6     public int height;
 7
 8     public DrawView(Context context) {
 9         super(context);
10         mRectangle = new Rectangle(context, this);
11         mRectangle.setARGB(255, 255, 0, 0);
12         mRectangle.setSpeedX(3);
13         mRectangle.setSpeedY(3);
14
15     }
16
17     @SuppressLint("WrongCall")
18     @Override
19     protected void onDraw(Canvas canvas) {
20         super.onDraw(canvas);
21         invalidate();
22
23         mRectangle.move();
24         mRectangle.onDraw(canvas);
25
26     }
27
28 }

主界面。

获取屏幕的尺寸,并把相应的尺寸赋值给DrawView对象。最后,显示DrawView对象。代码如下:

 1 public class MainActivity extends Activity {
 2
 3     private DrawView mDrawView;
 4
 5     @Override
 6     protected void onCreate(Bundle savedInstanceState) {
 7         super.onCreate(savedInstanceState);
 8
 9         Display display = getWindowManager().getDefaultDisplay();
10         mDrawView = new DrawView(this);
11         mDrawView.height = display.getHeight();
12         mDrawView.width = display.getWidth();
13         setContentView(mDrawView);
14     }
15
16 }

源码下载:

  1. public class Rectangle extends View {
  2. public static final int MAX_SIZE = 40;
  3. private static final int ALPHA = 255;
  4. private int mCoordX = 0;
  5. private int mCoordY = 0;
  6. private int mRealSize = 40;
  7. private int mSpeedX = 3;
  8. private int mSpeedY = 3;
  9. private boolean goRight = true;
  10. private boolean goDown = true;
  11. private DrawView mDrawView;
  12. private Paint mInnerPaint;
  13. private RectF mDrawRect;
  14. public Rectangle(Context context, DrawView drawView) {
  15. super(context);
  16. mDrawView = drawView;
  17. mInnerPaint = new Paint();
  18. mDrawRect = new RectF();
  19. /* Red is default */
  20. mInnerPaint.setARGB(ALPHA, 255, 0, 0);
  21. mInnerPaint.setAntiAlias(true);
  22. }
  23. public void setARGB(int a, int r, int g, int b) {
  24. mInnerPaint.setARGB(a, r, g, b);
  25. }
  26. public void setX(int newValue) {
  27. mCoordX = newValue;
  28. }
  29. public int getX() {
  30. return mCoordX;
  31. }
  32. public void setY(int newValue) {
  33. mCoordY = newValue;
  34. }
  35. public int getY() {
  36. return mCoordY;
  37. }
  38. public void move() {
  39. moveTo(mSpeedX, mSpeedY);
  40. }
  41. private void moveTo(int goX, int goY) {
  42. // check the borders, and set the direction if a border has reached
  43. if (mCoordX > (mDrawView.width - MAX_SIZE)) {
  44. goRight = false;
  45. }
  46. if (mCoordX < 0) {
  47. goRight = true;
  48. }
  49. if (mCoordY > (mDrawView.height - MAX_SIZE)) {
  50. goDown = false;
  51. }
  52. if (mCoordY < 0) {
  53. goDown = true;
  54. }
  55. // move the x and y
  56. if (goRight) {
  57. mCoordX += goX;
  58. } else {
  59. mCoordX -= goX;
  60. }
  61. if (goDown) {
  62. mCoordY += goY;
  63. } else {
  64. mCoordY -= goY;
  65. }
  66. }
  67. public int getSpeedX() {
  68. return mSpeedX;
  69. }
  70. public void setSpeedX(int speedX) {
  71. mSpeedX = speedX;
  72. }
  73. public int getmSpeedY() {
  74. return mSpeedY;
  75. }
  76. public void setSpeedY(int speedY) {
  77. mSpeedY = speedY;
  78. }
  79. @Override
  80. protected void onDraw(Canvas canvas) {
  81. super.onDraw(canvas);
  82. mDrawRect.set(mCoordX, mCoordY, mCoordX + mRealSize, mCoordY
  83. + mRealSize);
  84. canvas.drawRoundRect(mDrawRect, 0, 0, mInnerPaint);
  85. }
  86. public void setSize(int newSize) {
  87. mRealSize = newSize;
  88. }
  89. public int getSize() {
  90. return mRealSize;
  91. }
  92. }
时间: 2024-08-08 22:10:09

Android Canvas上的动画的相关文章

Android中使用SurfaceView和Canvas来绘制动画

其实每个View中都有Canvas可以用来绘制动画,只需要在这个View中重载onDraw()方法就可以,但是SurfaceView类是一个专门用来制动动画的类. Canvas(中文叫做"画布")就和HTML5中的canvas标签一样可以在一定区域内自由绘制图形.Canvas+SurfaceView制作的动画与View Animation和Property Animation这类动画比起来更加适合大量的集中播放的动画,比如游戏画面.相机的图像显示等. 因为SurfaceView通常会在

Android自定义水波纹动画Layout

Android自定义水波纹动画Layout 源码是双11的时候就写好了,但是我觉得当天发不太好,所以推迟了几天,没想到过了双11女友就变成了前女友,桑心.唉不说了,来看看代码吧. 展示效果 Hi前辈 话不多说,我们先来看看效果: 这一张是<Hi前辈>的搜索预览图,你可以在这里下载这个APP查看更多效果:http://www.wandoujia.com/apps/com.superlity.hiqianbei LSearchView 这是一个MD风格的搜索框,集成了ripple动画以及searc

android canvas变形,移动,旋转

public class testView extends View {     private Bitmap mBitmap = null;     private Bitmap nBitmap = null;     private float scaleX = 1.0f;     private float scaleY = 1.0f;     private float step = 0.0001f;          public testView(Context context, A

用Canvas和属性动画造一只萌蠢的“小鬼”

最近没事的时候想自己写一个支持下拉刷新,上拉加载的自定义View.写着写着,就觉得最常见的"一个圈转啊转"的进度条太普通了. 于是,就想看看有没有更有趣的一点的加载效果.在GitHub上以"android loading"为关键字一搜索,就发现有作者开源了这么一个库: 库的地址是:https://github.com/ldoublem/LoadingView.里面提供了很多有趣的加载动画(非常棒),个人对其中如下一个效果产生了兴趣: 那么,开源的好处就来了,立刻打开

Android Canvas的常用方法

我们可以把这个Canvas理解成系统提供给我们的一块内存区域(但实际上它只是一套画图的API,真正的内存是下面的Bitmap),而且它还提供了一整套对这个内存区域进行操作的方法,所有的这些操作都是画图API.也就是说在这种方式下我们已经能一笔一划或者使用Graphic来画我们所需要的东西了,要画什么要显示什么都由我们自己控制. 这种方式根据环境还分为两种:一种就是使用普通View的canvas画图,还有一种就是使用专门的SurfaceView的canvas来画图.两种的主要是区别就是可以在Sur

android canvas

canvas 这个类相当于一个画布,你可以在里面画很多东西: 我们可以把这个Canvas理解成系统提供给我们的一块内存区域(但实际上它只是一套画图的API,真正的内存是下面的Bitmap),而且它还提供了一整套对这个内存区域进行操作的方法,所有的这些操作都是画图API.也就是说在这种方式下我们已经能一笔一划或者使用Graphic来画我们所需要的东西了,要画什么要显示什么都由我们自己控制. 这种方式根据环境还分为两种:一种就是使用普通View的canvas画图,还有一种就是使用专门的Surface

【转】Android Canvas绘图详解(图文)

转自:http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2012/1212/703.html Android Canvas绘图详解(图文) 泡在网上的日子 发表于 2012-12-12 20:29 第 63165 次阅读 Canvas,android 15 Android中使用图形处理引擎,2D部分是android SDK内部自己提供,3D部分是用Open GL ES 1.0.今天我们主要要了解的是2D相关的,如果你想看3D的话那么可以跳

android canvas与图层的关系

在自定义view中可以通过canvas在屏幕上绘制一些文字,图片,图形之类的效果,canvas这个类给我们提供了很多绘制的方法,比如绘制一段文字在屏幕上: package com.example.customview; import android.content.Context; import android.graphics.Canvas; import android.graphics.Paint; import android.util.AttributeSet; import andr

在低版本android系统上实现Material设计应用

?Material Design真的很好看,动画效果真的很实用.前面也写了一些文章介绍如何编写Material风格的程序,但是很多都是一些新的api,低版本上面没有这些api,我们没办法使用.但是不用气馁,google官方,以及一些大牛,给我们提供了一些程序,让我们在低版本上面可以实现Material风格的程序,这里就给大家介绍一下. 妹子图截屏 使用support library 使用support library最新的版本,appcomt21,可以在较低版本上面实现部分风格,在之前的文章我已