Expert的View——SurfaceView

来源:互联网 发布:网络舆论特性 编辑:程序博客网 时间:2024/06/01 21:46

SurfaceView 用于要求界面更新迅速的UI,能够更自主的定义界面!通常作为2D游戏开发的首选。它与View有相似地方,但也有区别!


SurfaceView的基本用法:

 1。为了实现代码的方便管理且不混乱,最好继承SurfaceView并且实现SurfaceHolder.Callback接口,如下

public class MySurfView extends SurfaceView implements SurfaceHolder.Callback {    public MySurfView(Context context) {        super(context);        init(context);    }    public MySurfView(Context context, AttributeSet attrs) {        super(context, attrs);        init(context);    }    public MySurfView(Context context, AttributeSet attrs, int defStyle) {        super(context, attrs, defStyle);        init(context);    }    @TargetApi(Build.VERSION_CODES.LOLLIPOP)    public MySurfView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {        super(context, attrs, defStyleAttr, defStyleRes);        init(context);    }    private SurfaceHolder surfaceHolder;    private Paint paint;    private Context context;    private void init(Context context){      surfaceHolder=this.getHolder();        surfaceHolder.addCallback(this);       paint=new Paint();        this.context=context;        paint.setColor(Color.BLUE);    }   //<span style="font-family: Arial, Helvetica, sans-serif;">实现SurfaceView界面的绘制</span><span style="font-family: Arial, Helvetica, sans-serif;"> </span>
<span style="font-family: Arial, Helvetica, sans-serif;">  private void drawCanvas(){</span>
    }    @Override    public void surfaceCreated(SurfaceHolder holder) {    drawCanvas();    }    @Override    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {    }    @Override    public void surfaceDestroyed(SurfaceHolder holder) {    }<span style="font-family: Arial, Helvetica, sans-serif;">   </span>
<span style="font-family: Arial, Helvetica, sans-serif;">//通过MotionEvent获取x,y的坐标,实现SurfaceView界面的区域点击事件</span>
   
<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">@Override public boolean onTouchEvent(MotionEvent event) { return true; }}</span>
2.还可以通过实例化一个SurfaceView,并且获取该SurfaceView的SurfaceHolder对象,之后给该SurfaceView赋值SurfaceHolder.CallBack,如下:
   private SurfaceView surfaceView;    private SurfaceHolder surfaceHolder;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(new MySurfView(this));        surfaceView= (SurfaceView) findViewById(R.id.surfaceView);        surfaceHolder=surfaceView.getHolder();        surfaceHolder.addCallback(new SurfaceHolder.Callback() {            @Override            public void surfaceCreated(SurfaceHolder holder) {            }            @Override            public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {            }            @Override            public void surfaceDestroyed(SurfaceHolder holder) {            }        });    }

SurfaceView如何绘制:

前面提到过SurfaceView的界面绘制是从surfaceCreated(SurfaceHolder holder)方法开始进行的,通过SurfaceHolder获取Canvas对象,绘制完成后释放并提交该对象,如下代码:

 private void oneTest(){        Canvas canvas=surfaceHolder.lockCanvas();//获取SurfaceView的画布        // 这部分代码为   画布的绘制部分
     surfaceHolder.unlockCanvasAndPost(canvas);//绘制完成后,释放画布Canvas</span>
    }

SurfaceView的事件监听:

SurfaceView类是继承MockView的子类,MockView继承了TextView,因此SurfaceView也拥有View的事件,但SurfaceView也会有它自己的事件特性,如果想监听SurfaceView的某一块区域点击事件,首先需要判断该触摸点是否在该区域中,如果在则触发该区域的事件!如下所示:

    private         Region region=new Region();    @Override    public boolean onTouchEvent(MotionEvent event) {        /**         * 点击事件         */        if (region.contains( (int)event.getX(), (int)event.getY())){            Toast.makeText(context,"区域部分",Toast.LENGTH_SHORT).show();        }else {            Toast.makeText(context,"not  区域部分",Toast.LENGTH_SHORT).show();        }        return true;    }
上面示例的Region在绘制SurfaceView时必须设定其区域范围,区域范围的定制问题立马探讨!

SurfaceView的区域定制:

 1.使用Region来确定区域:下述代码是绘制一个矩形,设定Region的范围

      region.op(new Rect(0,0,300,100), Re     gion.Op.XOR);        canvas.clipRegion(region);

2,使用坐标来进行计算,设备的左上角为(0,0)起点,向右为x轴正方向,向下为Y轴正方向,横竖屏切换时亦是如此!通过划定区域的坐标界限来确定触摸点是否在划定区域内!


0 0