Android之SurfaceView简介(三)
SurfaceView提供直接访问一个可画图的界面,可以控制在界面顶部的子视图层。SurfaceView是提供给需要直接画像素而不是使用
窗体部件的应用使用的。Android图形系统中一个重要的概念和线索是surface。View及其子类(如TextView, Button)要画在surface上。每个surface创建一个Canvas对象(但属性时常改变),用来管理view在surface上的绘图操作,如画点画线。
还要注意的是,使用它的时候,一般都是出现在最顶层的:The view hierarchy will take care of correctly compositing
with the Surface any siblings of the SurfaceView that would normally appear on top of it.
使用SurfaceView的时候,一般情况下还要对其进行创建,销毁,改变时的情况进行监视,这就要用到SurfaceHolder.Callback.
例子1:
public class BBatt extends SurfaceView implements SurfaceHolder.Callback, OnKeyListener { private BFairy bFairy; private DrawThread drawThread; public BBatt(Context context) { super(context); this.setLayoutParams(new ViewGroup.LayoutParams(Global.battlefieldWidth, Global.battlefieldHeight)); this.getHolder().addCallback( this ); this.setFocusable( true ); this.setOnKeyListener( this ); bFairy = new BFairy(this.getContext()); } public void surfaceChanged(SurfaceHolder holder,int format,int width,int height) { drawThread = new DrawThread(holder); drawThread.start(); } public void surfaceDestroyed(SurfaceHolder holder) { if( drawThread != null ) { drawThread.doStop(); while (true) try { drawThread.join(); break ; } catch(Exception ex) {} } } public boolean onKey(View view, int keyCode, KeyEvent event) {}}
实例2: 用线程画一个蓝色的长方形。
public class Test extends Activity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(new MyView(this)); } //内部类 class MyView extends SurfaceView implements SurfaceHolder.Callback{ SurfaceHolder holder; public MyView(Context context) { super(context); holder = this.getHolder();//获取holder holder.addCallback(this); //setFocusable(true); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width,int height) {} @Override public void surfaceCreated(SurfaceHolder holder) { new Thread(new MyThread()).start(); } @Override public void surfaceDestroyed(SurfaceHolder holder) {} //内部类的内部类 class MyThread implements Runnable{ @Override public void run() { Canvas canvas = holder.lockCanvas(null);//获取画布 Paint mPaint = new Paint(); mPaint.setColor(Color.BLUE); canvas.drawRect(new RectF(40,60,80,80), mPaint); holder.unlockCanvasAndPost(canvas);//解锁画布,提交画好的图像 } } }}
访问SurfaceView的底层图形是通过SurfaceHolder接口来实现的,通过getHolder()方法可以得到这个SurfaceHolder对象。你应该实现surfaceCreated(SurfaceHolder)和surfaceDestroyed(SurfaceHolder)方法来知道在这个Surface在窗口的显示和隐藏过程中是什么时候创建和销毁的。
SurfaceView可以在多线程中被访问。
注意:一个SurfaceView只在SurfaceHolder.Callback.surfaceCreated() 和 SurfaceHolder.Callback.surfaceDestroyed()调用之间是可用的,其他时间是得不到它的Canvas对象的(null)。
我的访问过程:
创建一个SurfaceView的子类,实现SurfaceHolder.Callback接口。
得到这个SurfaceView的SurfaceHolder对象holder。
holder.addCallback(callback),也就是实现SurfaceHolder.Callback接口的类对象。
在SurfaceHolder.Callback.surfaceCreated()调用过后holder.lockCanvas()对象就可以得到SurfaceView对象对应的Canvas对象canvas了。
用canvas对象画图。
画图结束后调用holder.unlockCanvasAndPost()就把图画在窗口中了。
SurfaceView可以多线程访问,在多线程中画图。
如何让 SurfaceView 响应事件,当然创建你自己的类时,你还是得extendsSurfaceView and implementsCallback接口,然后在构造函数里设置一个属性this.setLongClickable(true);//这里很重要,它是让你的设备支持长按效果的属性,如果它为false 的时候MotionEvent 只能监听到ACTION_DOWN这个事件。
public class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback { private Context mContext; private SurfaceHolder mHolder; public TouchScreenAdjusterSurfaceView(Context context,) { super(context); mContext = context; mHolder = TouchScreenAdjusterSurfaceView.this.getHolder(); mHolder.addCallback(TouchScreenAdjusterSurfaceView.this); this.setFocusableInTouchMode(true); // to make sure that we can get // touch events and key events,and // "setFocusable()" to make sure we // can get key events } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { // TODO Auto-generated method stub } @Override public void surfaceCreated(SurfaceHolder holder) { //now you can get the Canvas and draw something here } @Override public void surfaceDestroyed(SurfaceHolder holder) { // TODO Auto-generated method stub } public void drawMyShape(PointPostion ps) { mCanvas = mHolder.lockCanvas(); // draw anything you like mHolder.unlockCanvasAndPost(mCanvas); } @Override public boolean onTouchEvent(MotionEvent event){ switch(event.getAction()){ case MotionEvent.ACTION_DOWN: Log.d("MotionEvent", "ACTION_DOWN"); break; case MotionEvent.ACTION_UP: Log.d("MotionEvent", "ACTION_UP"); break; case MotionEvent.ACTION_MOVE: Log.d("MotionEvent", "ACTION_MOVE"); break; } return super.onTouchEvent(event); }
更多相关文章
- Android画图之Matrix
- Android 画图常用类
- Android高手进阶教程(十七)之---Android中Intent传递对象的两种
- Android中将资源文件转为Bitmap对象
- Android graphics画图的点击事件处理
- 面向UDP的Android——PC双向通信(三):在Android客户端和PC服务器端
- Android画图学习总结(一)——类的简介
- Android调用WebService系列之KSoap2对象解析
- Android Application对象必须掌握的七点