android中的SurfaceView的理解
2014-12-02 21:56
218 查看
1.SurfaceView是继承View的派生类(public class SurfaceView extends View {...}),这个View里内嵌了一个专门用于绘制的Surface,这个可以类似的理解成为一个在View里的Canvas。你可以控制这个Surface的格式和尺寸。Surfaceview类则控制这个Surface在屏幕上的正确位置。
2.在一般情况下,应用程序的View都是在相同的GUI线程中绘制的。这个主应用程序线程同时也用来处理所有的用户交互(例如按钮单击或者文本输入)。
对于一个View的onDraw()方法,不能够满足将其移动到后台线程中去。因为从后台线程修改一个GUI元素会被显式地禁止的,当需要快速地更新View的UI,或者当前渲染代码阻塞GUI线程的时间过长的时候,SurfaceView就是解决上述问题的最佳选择。SurfaceView封装了一个Surface对象,而不是Canvas。这一点很重要,因为Surface可以使用后台线程绘制。对于那些资源敏感的操作,或者那些要求快速更新或者高速帧率的地方,例如使用3D图形,创建游戏,或者实时预览摄像头,这一点特别有用。
3.如何使用使用一个SurfaceView,首先继承SurfaceView并实现SurfaceHolder.Callback接口。因为使用SurfaceView
有一个原则,所有的绘图工作必须得在Surface 被创建之后才能开始。Callback 中的surfaceCreated 和surfaceDestroyed 就成了绘图处理代码的边界。
需要重写的方法
(1)public void surfaceChanged(SurfaceHolder holder,int
format,int width,int height){}
//在surface的大小发生改变时激发
(2)public void surfaceCreated(SurfaceHolder holder){}
//在创建时激发,一般在这里调用画图的线程。
(3)public void surfaceDestroyed(SurfaceHolder holder) {}
//销毁时激发,一般在这里将画图的线程停止、释放。
4.下面举个在网上的一个被我改版的小球运动的例子
a.MyPinBallSurfaceView类
2.在一般情况下,应用程序的View都是在相同的GUI线程中绘制的。这个主应用程序线程同时也用来处理所有的用户交互(例如按钮单击或者文本输入)。
对于一个View的onDraw()方法,不能够满足将其移动到后台线程中去。因为从后台线程修改一个GUI元素会被显式地禁止的,当需要快速地更新View的UI,或者当前渲染代码阻塞GUI线程的时间过长的时候,SurfaceView就是解决上述问题的最佳选择。SurfaceView封装了一个Surface对象,而不是Canvas。这一点很重要,因为Surface可以使用后台线程绘制。对于那些资源敏感的操作,或者那些要求快速更新或者高速帧率的地方,例如使用3D图形,创建游戏,或者实时预览摄像头,这一点特别有用。
3.如何使用使用一个SurfaceView,首先继承SurfaceView并实现SurfaceHolder.Callback接口。因为使用SurfaceView
有一个原则,所有的绘图工作必须得在Surface 被创建之后才能开始。Callback 中的surfaceCreated 和surfaceDestroyed 就成了绘图处理代码的边界。
需要重写的方法
(1)public void surfaceChanged(SurfaceHolder holder,int
format,int width,int height){}
//在surface的大小发生改变时激发
(2)public void surfaceCreated(SurfaceHolder holder){}
//在创建时激发,一般在这里调用画图的线程。
(3)public void surfaceDestroyed(SurfaceHolder holder) {}
//销毁时激发,一般在这里将画图的线程停止、释放。
4.下面举个在网上的一个被我改版的小球运动的例子
a.MyPinBallSurfaceView类
public class MyPinBallSurfaceView extends SurfaceView implements SurfaceHolder.Callback,Runnable{ //桌面的宽度 private int tableWidth; //桌面的高度 private int tableHeight; //球拍的垂直位置 private int racketY; //定义球拍的高度和宽度 private final int RACKET_HEIGHT = 20; private final int RACKET_WIDTH = 70; //小球的大小 private final int BALL_SIZE = 12; //小球纵向的运行速度 private int ySpeed = 10; Random rand = new Random(); //返回一个-0.5~0.5比率,用于控制小球的运行方向 private double xyRate = rand.nextDouble() - 0.5; //小球横向的运行速度 private int xSpeed = (int)(ySpeed * xyRate * 2); //ballX和ballY代表小球坐标 private int ballX = rand.nextInt(200) + 20; private int ballY = rand.nextInt(10) + 20; //racketX代表球拍的水平位置 private int racketX = rand.nextInt(200); //游戏是否结束的旗标 private boolean isLose = false; private SurfaceHolder mSurfaceHolder; private boolean flag;//控制绘图结束的标示 private Thread mThread; float x=0; public MyPinBallSurfaceView(Context context){ super(context); mSurfaceHolder=this.getHolder(); mSurfaceHolder.addCallback(this); //在这里获取屏幕的宽高是为0的。在网上看到说是在这里布局还没有绘制出来获取到的宽高就为0。 // Rect mRect=mSurfaceHolder.getSurfaceFrame(); // mRect.width(); // mRect.height(); } public MyPinBallSurfaceView(Context context, AttributeSet attrs) { super(context, attrs); } @Override public void surfaceCreated(SurfaceHolder holder) { tableWidth=getWidth(); tableHeight=getHeight(); racketY=tableHeight-50; flag=true; start(); mThread=new Thread(this); mThread.start(); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } @Override public void surfaceDestroyed(SurfaceHolder holder) { flag=false; } @Override public boolean onTouchEvent(MotionEvent event) { switch(event.getAction()){ case MotionEvent.ACTION_DOWN: x=event.getX(); break; case MotionEvent.ACTION_MOVE: break; case MotionEvent.ACTION_UP: //点击的位置在挡板的位置右侧则向左移 if(x<=racketX){ if(racketX>0){ racketX-=10; } } //这里判断点击的位置在挡板的右边则向右移 if(x>=(racketX+RACKET_WIDTH)){ if(racketX<tableWidth-RACKET_WIDTH){ racketX+=10; } } break; } return true; } @Override public void run() { while(flag){ myDraw(); } } public void start(){ final Timer mTimer=new Timer(); mTimer.schedule(new TimerTask() { @Override public void run() { //如果小球碰到左边边框 if(ballX <= 0 || ballX >= tableWidth - BALL_SIZE){ xSpeed = -xSpeed; } //如果小球高度超出了球拍位置,且横向不在球拍范围之内,游戏结束 if(ballY >= racketY - BALL_SIZE && (ballX < racketX || ballX > racketX + RACKET_WIDTH)){ mTimer.cancel(); //设置游戏是否结束的旗标为true isLose = true; } //如果小球位于球拍之内,且到达球拍位置,小球反弹 else if(ballY <= 0 || (ballY > racketY - BALL_SIZE && ballX > racketX && ballX <= racketX + RACKET_WIDTH)){ ySpeed = -ySpeed; } //小球坐标增加 ballY += ySpeed; ballX += xSpeed; } },0,700); } /** * 游戏绘图自定义的绘图方法 */ public void myDraw(){ Canvas mCanvas=null; try{ mCanvas=mSurfaceHolder.lockCanvas(); if(mCanvas!=null){ mCanvas.drawColor(Color.TRANSPARENT,Mode.CLEAR); Paint mPaint=new Paint(Paint.ANTI_ALIAS_FLAG); mPaint.setStyle(Paint.Style.FILL); if(isLose){ mPaint.setColor(Color.RED); mCanvas.drawText("游戏结束!",150,200,mPaint); }else{ mPaint.setColor(Color.rgb(240, 240, 80)); mCanvas.drawCircle(ballX,ballY,BALL_SIZE,mPaint); //设置颜色,并绘制挡板 mPaint.setColor(Color.rgb(80, 80, 200)); mCanvas.drawRect(racketX,racketY, racketX + RACKET_WIDTH, racketY+RACKET_HEIGHT,mPaint); } } }catch(Exception e){ e.printStackTrace(); }finally{ if(mCanvas!=null){ mSurfaceHolder.unlockCanvasAndPost(mCanvas); } } try { Thread.sleep(30); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }b.MainActivity类
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE);//去掉标题 getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN); setContentView(new MyPinBallSurfaceView(this)); }
相关文章推荐
- Android中Surface和SurfaceView的一些理解和总结
- Android中Surface和SurfaceView的一些理解和总结
- Android中Surface和SurfaceView的一些理解和总结
- android理解之surfaceview和view的区别
- Android SurfaceView的理解与使用
- Android中Surface和SurfaceView的一些理解和总结
- Android中Surface和SurfaceView的一些理解和总结
- 理解Android的SurfaceView
- Android中Surface和SurfaceView的一些理解和总结
- Android中Surface和SurfaceView的一些理解和总结
- Android中Surface和SurfaceView的一些理解和总结
- android中SurfaceView SurfaceHolder SurfaceHolder.Callback 关系 理解
- Android SurfaceView的总结与理解
- Android SurfaceView 绘图及帧频处理方法修正
- 【Android游戏开发之六】在SurfaceView中添加组件!!!!并且相互交互数据!!!!
- 【Android游戏开发之三】剖析 SurfaceView ! Callback以及SurfaceHolder!!
- Android中SurfaceView的使用示例
- 【Android游戏开发之六】在SurfaceView中添加组件!!!!并且相互交互数据!!!!
- Android SurfaceView 绘图覆盖刷新及脏矩形刷新方法
- 【Android游戏开发之七】(游戏开发中需要的样式)再次剖析游戏开发中对SurfaceView中添加组件方案!