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轴正方向,横竖屏切换时亦是如此!通过划定区域的坐标界限来确定触摸点是否在划定区域内!
时间: 2024-10-24 07:14:24