Android SurfaceView学习笔记

最近一直在找一些关于SurfaceView绘制图像的按例,咱是初学,刚开始压根儿不知道如何入手绘制图形在SurfaceView上,最后学习了一下视频教程,然后将学习过程的笔记加以整理发布如下,在此说明,以下两个View都是继承自SurfaceView,是自定义的一两个View,大家在查看效果的时候,自己可以创建一个Activity,然后在Activity的onCreate方法中加以引用, 即在setContentView(new GameView());或者setContentView(new GameView1);
com.thinkive.ziyouxing.views;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.KeyEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import com.thinkive.adf.log.Logger;

/**
 * 文件名: com.thinkive.ziyouxing.views.GameView
 * 作者:  熊杰
 * 日期: 14-4-14
 * 时间: 13:40
 * 开发工具: IntelliJ IDEA 12.0.4
 * 开发语言: Java,Android
 * 开发框架:
 * 版本: v0.1
 * <strong>说明</strong>
 * <p></p>
 */

public class GameView extends SurfaceView implements SurfaceHolder.Callback, Runnable {


    private SurfaceHolder surfaceHolder;
    private Canvas canvas;
    private Paint paint;
    //默认情况下是一直在运行的
    private boolean isRunning = true;
    //半径增加
    private int x = 0;

    public GameView(Context context) {
        super(context);

        surfaceHolder = this.getHolder();

        surfaceHolder.addCallback(this);
    }


    @Override
    public void surfaceCreated(SurfaceHolder surfaceHolder) {
        new Thread(this).start();
    }

    @Override
    public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i2, int i3) {

    }

    /**
     * 当SurfaceView消毁时执行,当应用程序退出时,当前SurfaceView就消毁掉了,子线程在运行过程中还在往界面上进行绘制,
     * View都没有了,怎么能往上面进行绘制呢?所以在运行过程中会出异常。
     * <p/>
     * 当View消毁的时候就记线程不要再进行绘制了。
     *
     * @param surfaceHolder
     */

    @Override
    public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
        isRunning = false;
    }

    @Override
    public void run() {
        while (isRunning) {
            try {
                drawView();
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 用线程画图
     * <p/>
     * 在做游戏开发的时候,我们要定期的对屏幕进行刷新.即在线程里面每隔100毫秒,屏幕会绘制一遍。线程什么时候启动呢?
     * <p/>
     * SurfaceView创建成功之后,有界面了,创建一个启动线程线程一启动,每过100毫秒就绘制一遍界面。
     * <p/>
     * 只画边界,而不填充里面的颜色,该如何做呢?
     * <p/>
     * paint.setStyle(Paint.Style.STROKE);
     * 界面被消毁的时候,首先是Canvas被消毁,然后SurfaceHolder才会被消毁
     */
    private void drawView() {

        try {
            if (null != surfaceHolder) {
                canvas = surfaceHolder.lockCanvas();
                paint = new Paint();
                paint.setColor(Color.RED);
                paint.setStyle(Paint.Style.STROKE);
                paint.setStrokeWidth(3);
                canvas.drawCircle(200, 200, x++, paint);
            }
        } catch (Exception e) {
            Logger.info(this.getClass(), "画图异常", e);
        } finally {
            if (null != canvas) {
                surfaceHolder.unlockCanvasAndPost(canvas);
            }
        }

    }

    /**
     * 让子线程提前结束,当按键的时候,首先按件事件被响应,这个响应完了之后,界面才退出。也就是从事件开始执行,到界面消毁中间还有那么一段时间,如果在此方法中就让线程终止运行
     * 当界面真正消毁的时候,子线程已经结束了。
     * @param keyCode
     * @param event
     * @return
     */
//    @Override
//    public boolean onKeyDown(int keyCode, KeyEvent event) {
//        if(keyCode == KeyEvent.KEYCODE_BACK){
//            isRunning = false;
//        }
//        return true;
//    }
}



package com.thinkive.ziyouxing.views;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

/**
 * 文件名: com.thinkive.ziyouxing.views.GameView
 * 作者:  熊杰
 * 日期: 14-4-14
 * 时间: 13:40
 * 开发工具: IntelliJ IDEA 12.0.4
 * 开发语言: Java,Android
 * 开发框架:
 * 版本: v0.1
 * <strong>说明</strong>
 * <p></p>
 */

public class GameView1 extends SurfaceView{

    //可以理解为指向SurfaceView的一个指针,可以类比成控制电视机的摇控器,而SurfaceView则是电视机,以后如果要控制电视机,
    //则只需操作摇控器就可以了。
    private SurfaceHolder surfaceHolder;
    //面板对象
    private  Canvas canvas;

    //画笔
    private Paint paint;

    /**
     * 当我对象创建成功之后,构造器就会获得执行,但是构造器执行的时候,界面并没有显示出来。对象是有了,但是界面并没有真正的画上去,我们应该等当前屏幕画上去了,
     * 我再通过屏幕锁定,我获得一个面板,面板再画才可以,因为现在对象刚刚创建成功,界面还没有出来,获取到的面板是空的,所以也就不能进行绘制了,那么现在我怎么确定执行画图的时候,
     * 这个View界面已经创建成功了呢?
     * SurfaceView里面有一个辅助类,sh.addCallBack()这个回调类似于注册监听,比如说按钮的单击监听,还有触摸监听,按键监听等等。
     * 也就是说在SurfaceHolder上面注册一个监听,当SurfaceHolder状态改变的时候,监听里面的方法会自动执行。
     * 说SurfaceHolder状态改变,实际上也就是SurfaceView的一个状态的改变,
     * 我们再写事件监听的时候,基本上所有的事件监听,所涉及到的那些方法,都是回调方法。
     *
     * 什么是回调方法呢?
     *
     * 也就是这些方法不是我去调用的,而是系统去调用的。
     * @param context
     */
    public GameView1(Context context) {
        super(context);

        surfaceHolder = this.getHolder();

        surfaceHolder.addCallback(new GameViewCallBack());



    }

    class GameViewCallBack implements SurfaceHolder.Callback{

        //当SurfaceView创建成功了执行
        @Override
        public void surfaceCreated(SurfaceHolder surfaceHolder) {

            //锁定面板之后,会得到一个Canvas,将面板锁定之后,我就可以进行绘画了,比如画圆,画直线...
            Canvas canvas = surfaceHolder.lockCanvas();

            paint = new Paint();
            paint.setColor(Color.RED);


            canvas.drawLine(0,0,100,100,paint);

            //绘制结束之后,解除面板锁定,并且发送,把当前已经画好的面板,发送到屏幕界面上。把面板发送,发送到哪儿呢?发送到界面上进行显示。我们说它自带二级缓存,这个地方就体现了二级缓存,
            //是我先锁定,不操作先锁定,整个画完之后,显示就可以了。
            surfaceHolder.unlockCanvasAndPost(canvas);
        }

        @Override
        public void surfaceChanged(SurfaceHolder surfaceHolder, int format, int width, int height ) {

        }

        @Override
        public void surfaceDestroyed(SurfaceHolder surfaceHolder) {

        }
    }

}


Android SurfaceView学习笔记,布布扣,bubuko.com

Android SurfaceView学习笔记

上一篇:Android智能指针分析(sp、wp)


下一篇:Android利用Gallery和ImageSwitcher实现在线相册图片预览功能(异步加载图片)