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.   
  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, 25500);  
  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 int getX() {  
  39.     return mCoordX;  
  40.   }  
  41.   
  42.   public void setY(int newValue) {  
  43.     mCoordY = newValue;  
  44.   }  
  45.   
  46.   public int 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, 00, mInnerPaint);  
  109.   
  110.   }  
  111.   
  112.   public void setSize(int newSize) {  
  113.     mRealSize = newSize;  
  114.   }  
  115.   
  116.   public int getSize() {  
  117.     return mRealSize;  
  118.   }  

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。