Combination of SurfaceView and Canvas to achieve bubble live wallpaper

Effect display:
 Write the picture description here
In fact, every View has a Canvas that can be used to draw animation, just reload in this View The onDraw() method is fine, but the SurfaceView class is a class specifically used to brake animation.

Canvas (called “canvas” in Chinese), just like the canvas tag in HTML5, can freely draw graphics in a certain area. Compared with the animations such as View Animation and Property Animation, the animations produced by Canvas+SurfaceView are more suitable for a large number of concentrated animations, such as game screens and camera image display.

Because SurfaceView usually redraws the interface continuously in another dedicated thread, it is not like other animations that need to play animation in the main thread (UI thread) while also consuming a certain degree of fluency. To respond to user input.

When using SurfaceView, you need to pay attention to the following points:

1) Each SurfaceView needs a SurfaceHolder object to handle the life cycle of the SurfaceView and obtain the Canvas object of the SurfaceView. Get its SurfaceHolder object by calling the getHolder() method of SurfaceView.

2) When using SurfaceView, it is generally implemented by inheriting SurfaceView. You can implement two interfaces by the way, namely Runnable and SurfaceHolder.Callback. The second interface needs to overload three functions. These three functions are the life cycle of SurfaceView. You can pass in the implemented Callback object through the addCallback() method of the SurfaceHolder object.

3) When using SurfaceView’s Canvas, you must remember to lock and synchronize, because you can’t let the canvas draw multiple patterns at the same time. You can do this by calling lockCanvas() of the SurfaceHolder object of this SurfaceView. After drawing, it can be unlocked and updated by calling the unlockCanvasAndPost() method of the SurfaceHolder object.

The following is an example of using SurfaceView and Canvas to draw animation. Generally, you can directly copy it and run it to see the effect:

Layout file:

<RelativeLayout xmlns:android="http://schemas.android.com/ apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <com.example.surfaceview.MySurfaceview  android:id="@+id/ mysurfaceview" android:layout_width="wrap_content" android:layout_height="wrap_content" />RelativeLayout>

java code:

public class MySurfaceview extends SurfaceView implements SurfaceHolder.Callback{ private MyThread myThread; private Paint paint; private boolean isDraw = true; private int centerX, centerY, radiu; private int CHANGEX, CHANGEY; public MySurfaceview(Context context, AttributeSet attrs) {super(context, attrs ); init();} private void init span>() {//TODO surface controller SurfaceHolder holder = getHolder(); holder.addCallback(this span>); myThread = new MyThread(holder); paint = new Paint(); paint.setAntiAlias (true); paint.setColor(Color.RED); paint.setStyle(Paint.Style.FILL); centerX =  40; centerY = 40; radiu = 40; CHANGEX = 20; CHANGEY = 20;} @Override public void surfaceCreated(SurfaceHolder surfaceHolder) {myThread.start();} @Override  public void surfaceChanged( SurfaceHolder surfaceHolder, int i, int i1, int i2) {} @Override public void span> surfaceDestroyed(SurfaceHolder surfaceHolder) {isDraw = false;} public class  MyThread extends Thread{  private SurfaceHolder holder; public MyThread span>(SurfaceHolder holder){ this.holder= holder;} @Override public void run() {//TODO draws the Surface interface //TODO draws the Surface interface Canvas canvas = null ; while (isDraw) {//Add synchronization to prevent multiple child threads from simultaneously operating surfaceview synchronized (holder) { //Join the try-catch program to run normally try {/ /Lock the canvas and get the canvas object canvas = holder.lockCanvas(); doDraw(canvas); sleep(16);} catch (Exception e) {e.printStackTrace();} finally {if (canvas != null) {//Unlock the canvas holder.unlockCanvasAndPost(canvas);}} }}}} private void doDraw( Canvas c anvas) {//TODO draw a circle canvas.drawColor(Color.BLUE);//Set the background color to the canvas span> canvas.drawCircle(centerX, centerY, radiu, paint); //todo When the x-axis is less than the radius of the ball or the x-axis plus the radius of the ball is greater than the width of the canvas, then Move the position of the ball.  if(centerX-radiu<0|| centerX+radiu>getWidth()){ CHANGEX = -CHANGEX;} if(centerY-radiu<0||centerY+radiu>getHeight() ){ CHANGEY = -CHANGEY;} //TODO achieves animation effects centerX += CHANGEX; centerY += CHANGEY; }}

Effect display:
Write picture description here
In fact, every View has Canvas that can be used to draw animations. You only need to override the onDraw() method in this View. , But the SurfaceView class is a class specifically used to brake animation.

Canvas (called “canvas” in Chinese), just like the canvas tag in HTML5, can freely draw graphics in a certain area. Compared with the animations such as View Animation and Property Animation, the animations produced by Canvas+SurfaceView are more suitable for a large number of concentrated animations, such as game screens and camera image display.

Because SurfaceView usually redraws the interface continuously in another dedicated thread, it is not like other animations that need to play animation in the main thread (UI thread) while also consuming a certain degree of fluency. To respond to user input.

When using SurfaceView, you need to pay attention to the following points:

1) Each SurfaceView needs a SurfaceHolder object to handle the life cycle of the SurfaceView and obtain the Canvas object of the SurfaceView. Get its SurfaceHolder object by calling the getHolder() method of SurfaceView.

2) When using SurfaceView, it is generally implemented by inheriting SurfaceView. You can implement two interfaces by the way, namely Runnable and SurfaceHolder.Callback. The second interface needs to overload three functions. These three functions are the life cycle of SurfaceView. You can pass in the implemented Callback object through the addCallback() method of the SurfaceHolder object.

3) When using SurfaceView’s Canvas, you must remember to lock and synchronize, because you can’t let the canvas draw multiple patterns at the same time. You can do this by calling lockCanvas() of the SurfaceHolder object of this SurfaceView. After drawing, it can be unlocked and updated by calling the unlockCanvasAndPost() method of the SurfaceHolder object.

The following is an example of using SurfaceView and Canvas to draw animation. Generally, you can directly copy it and run it to see the effect:

Layout file:

<RelativeLayout xmlns:android="http://schemas.android.com/ apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" > <com.example.surfaceview.MySurfaceview  android:id="@+id/ mysurfaceview" android:layout_width="wrap_content" android:layout_height="wrap_content" />RelativeLayout>

java code:

public class MySurfaceview extends SurfaceView  implements SurfaceHolder.Callback{ private MyThread myThread; private Paint paint; private boolean isDraw = true; private  int centerX, centerY, radiu; private int CHANGEX, CHANGEY; public MySurfaceview(Context context, AttributeSet attrs) {super(context, attrs ); init();} private void init span>() {//TODO surface controller SurfaceHolder holder = getHolder(); holder.addCallback(this span>); myThread = new MyThread(holder); paint = new Paint(); paint.setAntiAlias (true); paint.setColor(Color.RED); paint.setStyle(Paint.Style.FILL); centerX =  40; centerY = 40; radiu = 40; CHANGEX = 20; CHANGEY = 20;} @Override public void surfaceCreated(SurfaceHolder surfaceHolder) {myThread.start();} @Override  public void surfaceChanged( SurfaceHolder surfaceHolder, int i, int i1, int i2) {} @Override public void span> surfaceDestroyed(SurfaceHolder surfaceHolder) {isDraw = false;} public class MyThread extends Thread{ private SurfaceHolder holder; public MyThread (SurfaceHolder holder){ this.holder= holder;} @Override public void run() { //TODO draws the Surface interface //TODO draws the Surface interface Canvas canvas = null; < span class="hljs-keyword">while (isDraw) {//Add synchronization to prevent multiple child threads from simultaneously operating surfaceview synchronized (holder) { //Join the try-catch program to run normally try {/ /Lock the canvas and get the canvas object canvas = holder.lockCanvas(); doDraw(canvas); sleep(16);} catch (Exception e) {e.printStackTrace();} finally {if (canvas != null) {//Unlock the canvas holder.unlockCanvasAndPost(canvas);}} }}}} private void doDraw( Canvas canvas ) {//TODO draw a circle canvas.drawColor(Color.BLUE);//Set the background color to the canvas canvas.drawCircle(centerX, centerY, radiu, paint); //todo When the x-axis is less than the radius of the ball or the x-axis plus the radius of the ball is greater than the width of the canvas, then move The position of the ball.  if(centerX-radiu<0|| centerX+radiu>getWidth()){ CHANGEX = -CHANGEX;} if(centerY-radiu<0||centerY+radiu>getHeight() ){ CHANGEY = -CHANGEY;} //TODO achieves animation effects centerX += CHANGEX; centerY += CHANGEY; }}

Leave a Comment

Your email address will not be published.