SurfaceView与Canvas的结合实现简单的图形绘制与动画效果

   SurfaceView是Android中的经典,它能实现二维动画所须要的全部功能,喜欢动画的朋友们能够深刻学习,今天这一篇咱们就先进入一个开头,初步了解SurfaceView的动画效果。
java


1.一个简单的小例子:android

(1)MySurfaceView.javacanvas

package com.example.l0904_surfaceview;
/**
 * 使用SurfaceView与Canvas的结合完成
 * 简单的动画效果
 */
import java.util.Timer;
import java.util.TimerTask;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
//继承SurfaceView父类并实现SurfaceView.Callback接口
public class MySurfaceView extends SurfaceView implements
        SurfaceHolder.Callback {
    //建立画笔对象
    private Paint paint = new Paint();
    //定义计时器Timer定时器工具,用来在一个后台线程计划执行指定任务。它能够计划执行一个任务一次或反复屡次。
    private Timer timer;
    //TimerTask一个抽象类,它的子类表明一个能够被Timer计划的任务
    private TimerTask task;
    //定义并初始化要绘的图形的坐标
    private float x = 0;
    private float y = 0;
    private float speedx = 50;
    private float speedy = 50;
    //定义并初始化坐标移动的变化量
    private float addx = 2;
    private float addy = 2;
    /**
     * SurfaceView的构造方法
     * 在其中要初始化画笔的颜色
     * @param context
     */
    public MySurfaceView(Context context) {
        super(context);
        paint.setColor(Color.BLUE);
        getHolder().addCallback(this);
    }
    /**
     * 绘图方法,在其中完成具体的过程
     */
    public void draw() {
        // 锁定画布
        Canvas canvas = getHolder().lockCanvas();
        // 初始化画布
        canvas.drawColor(Color.WHITE);
        //绘制图形,这里画个矩形
        canvas.drawRect(x, y, speedx + x, speedy + y, paint);
        x += addx;
        y += addy;
        //下面是矩形的移动路径
        if (x < 0) {
            //若是图形左边界坐标超出左屏幕则向右移动
            addx = Math.abs(addx);
        }
        if (x > getWidth() - speedx) {
            //若是图形右边界坐标超出屏幕的宽度则向左移动
            addx = -Math.abs(addx);
        }
        if (y < 0) {
            addy = Math.abs(addy);
        }
        if (y > getHeight() - speedy) {
            addy = -Math.abs(addy);
        }
        // 解锁画布
        getHolder().unlockCanvasAndPost(canvas);
    }
    /**
     * 启动定时器后台线程
     */
    public void startTimer() {
        timer = new Timer();
        task = new TimerTask() {
            @Override
            public void run() {
                //在定时器线程中调用绘图方法
                draw();
            }
        };
        //设置定时器每隔0.1秒启动这个task,实现动画效果
        timer.schedule(task, 100, 100);
    }
    /**
     * 中止定时器线程的方法
     */
    public void stopTimer() {
        timer.cancel();
    }
    /**
     * 下面是必需要重写的方法
     */
    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        //必定要在SurfaceView建立以后启动线程
        startTimer();
    }
    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width,
            int height) {
    }
    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        //必定要在SurfaceView销毁以前结束线程
        stopTimer();
    }
}

(2)MainActivity.javaapp

package com.example.l0904_surfaceview;
import android.app.Activity;
import android.os.Bundle;
public class MainActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //设置视图
        setContentView(new MySurfaceView(this));
    }
}

(3)运行效果截图:dom

这样看效果不明显,咱们能够跟踪一下图形某一点的坐标:ide

   .
工具

   .
学习

   .
动画


2.进一步使用SurfaceView,完成屏幕的一个咱们熟知的屏幕保护效果——随机气泡this

(1)MySurfaceView.java

package com.example.l0904_collection;
import java.util.Timer;
import java.util.TimerTask;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class MySurfaceView extends SurfaceView implements
        SurfaceHolder.Callback {
    private Paint paint = new Paint();
    private Timer timer;
    private TimerTask task;
    private Bolls bolls;
    public MySurfaceView(Context context) {
        super(context);
        paint.setColor(Color.YELLOW);
        getHolder().addCallback(this);
    }
    public void draw() {
        Canvas canvas = getHolder().lockCanvas();// 锁定画布
        // 绘制图形
        canvas.drawColor(Color.WHITE);// 初始化画布
        for(int i=0;i<20;i++){
            bolls=new Bolls(this);
            canvas.drawCircle(bolls.getCx(), bolls.getCy(), bolls.getRadius(), paint);
            bolls.draw();
        }
                                                 
        getHolder().unlockCanvasAndPost(canvas);// 解锁画布
    }
    public void startTimer() {
        timer = new Timer();
        task = new TimerTask() {
            @Override
            public void run() {
                draw();
            }
        };
        timer.schedule(task, 100, 100);
    }
    public void stopTimer() {
        timer.cancel();
    }
    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        startTimer();
    }
    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width,
            int height) {
    }
    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        stopTimer();
    }
}

(2)Bolls.java

package com.example.l0904_collection;
public class Bolls {
    private float cx;
    private float cy;
    private float radius;
    private int addx;
    private int addy;
    private int addRadius;
    MySurfaceView view;
                                      
    public Bolls(MySurfaceView view){
        this.view=view;
        cx=(float) (Math.random()*300);
        cy=(float) (Math.random()*450);
        radius=(float) (Math.random()*30);
        addx=(int) (Math.random()*10);
        addy=(int) (Math.random()*10);
        addRadius=(int) (Math.random()*10);
    }
                                      
    public float getCx() {
        return cx;
    }
    public void setCx(float cx) {
        this.cx = cx;
    }
    public float getCy() {
        return cy;
    }
    public void setCy(float cy) {
        this.cy = cy;
    }
    public float getRadius() {
        return radius;
    }
    public void setRadius(float radius) {
        this.radius = radius;
    }
    public void draw(){
        cx += addx;
        cy += addy;
        radius+=addRadius;
        if (cx < radius) {
            addx = Math.abs(addx);
        }
        if (cx > view.getWidth() - radius) {
            addx = -Math.abs(addx);
        }
        if (cy < radius) {
            addy = Math.abs(addy);
        }
        if (cy > view.getHeight() -radius) {
            addy = -Math.abs(addy);
        }
    }
}

(3)MainActivity.java

package com.example.l0904_collection;
import android.app.Activity;
import android.os.Bundle;
public class MainActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(new MySurfaceView(this));
    }
}

(4)运行效果