android之View和SurfaceView

            首先介绍一下View类,View类是android的一个超类,每一个View都有一个用于绘画的画布,这个画布可以进行任意的扩展。有的时候我们需要自定义VIew实现自己想要的视图。view、SurfaceView是游戏开发中经常用到的视图。

        View:显示视图,内置画布,提供图形绘制函数、触屏事件、按键事件函数等;必须在UI主线程内更新画面,速度较慢。

       SurfaceView:基于view视图进行拓展的视图类,更适合2D游戏的开发;是view的子类,类似使用双缓机制,在新的线程中更新画面所以刷新界面速度比view快。

     下面介绍一下View和SurfaceView区别:

      View:必须在UI的主线程中更新画面,用于被动更新画面。

  surfaceView:UI线程和子线程中都可以。在一个新启动的线程中重新绘制画面,主动更新画面。

      

       先实现一个VIew的例子,新建一个MyView类基础View:

      

public class MyView extends View {

	int count=0;     
	public int r=10; //圆的半径
	public MyView(Context context) {
		super(context);
		// TODO Auto-generated constructor stub
	}
	@Override
	protected void onDraw(Canvas canvas) {
		// TODO Auto-generated method stub
		super.onDraw(canvas);
		if(count<=100){
			count++;	
		}else{
			count=0;
		}
		//绘图
		Paint paint=new Paint();
		switch (count % 4) {
		case 0:
			paint.setColor(Color.BLUE);
			break;
		case 1:
			paint.setColor(Color.YELLOW);
			break;
		case 2:
			paint.setColor(Color.GRAY);
			break;
		case 3:
			paint.setColor(Color.RED);
			break;
		default:
			paint.setColor(Color.WHITE);
			break;
		}
		canvas.drawCircle((320+r)/2, (480+r)/2, r, paint);
	}

}
      下面是需要显示它的TestViewActivity类:

invalidate   

public class TestViewActivity extends Activity {

	private MyView myView;
	private int REFRESH;
	private Handler handler=new Handler(){
		public void handleMessage(android.os.Message msg) {
			if(msg.what==REFRESH){
				myView.invalidate();
			}
		};
	};
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		myView=new MyView(this);
		setContentView(myView);
		
		new Thread(new Runnable() {
			
			@Override
			public void run() {
				// TODO Auto-generated method stub
				while(true){
				try {
					Thread.sleep(200);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				handler.sendEmptyMessage(REFRESH);
				//使用postInvalidate可以直接在线程中更新UI界面
				//myView.postInvalidate();
			  }	
			}
		}).start();
	}
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		// TODO Auto-generated method stub
		myView.r+=2;
		return super.onTouchEvent(event);
		
	}
	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		// TODO Auto-generated method stub
		if(keyCode==KeyEvent.KEYCODE_BACK){
			finish();
		}
		return super.onKeyDown(keyCode, event);
	}
}
    注释的部分是可以在线程中更新UI界面,当然也可以在handler中调用invalidate方法更新界面,这样就可以通过线程不断的重画改变小球的颜色,而且点击画面后小球会慢慢变大。

    这是其中的一张截图:

  下面看一下用SurfaceView是怎么实现的,照例创建一个MySurfaceView类:

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

	SurfaceHolder surfaceHolder;
	int count=0;
	int r=10;
	public MySurfaceView(Context context) {
		super(context);
		 //实例化SurfaceHolder对象
		surfaceHolder=this.getHolder();
		//为SurfaceHolder添加一个回调函数
		surfaceHolder.addCallback(this);
		this.setFocusable(true);
	}

	@Override
	public void run() {
		// TODO Auto-generated method stub
		while(true){  //死循环 来不停地画
		try {
			Thread.sleep(200);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		synchronized (surfaceHolder) {
			Draw();
		}
	   }
	}
	//绘图方法
	public void Draw(){
		//锁定画布  得到Canvas
		Canvas canvas=surfaceHolder.lockCanvas();
		if(surfaceHolder==null || canvas==null){
			return ;
		}
		if(count<=100){
			count++;
		}else{
			count=0;
		}
		Paint paint=new Paint();
		switch (count % 4) {
		case 0:
			paint.setColor(Color.BLUE);
			break;
		case 1:
			paint.setColor(Color.YELLOW);
			break;
		case 2:
			paint.setColor(Color.GRAY);
			break;
		case 3:
			paint.setColor(Color.RED);
			break;
		default:
			paint.setColor(Color.WHITE);
			break;
		}
		canvas.drawCircle((320+r)/2, (480+r)/2, r, paint);
		//解锁画布
		surfaceHolder.unlockCanvasAndPost(canvas);
	}
    //在surface大小改变时激发
	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width,
			int height) {
		// TODO Auto-generated method stub
		
	}
    //在surface创建时激发
	@Override
	public void surfaceCreated(SurfaceHolder holder) {
		// TODO Auto-generated method stub
		//开启视图线程
	    new Thread(this).start();
	}
	 //在surface销毁时激发
	@Override
	public void surfaceDestroyed(SurfaceHolder holder) {
		// TODO Auto-generated method stub
		
	}

}
   SurfaceView不需要通过线程来更新视图,但在绘图之前必须使用lockCanvas方法锁定画布,并得到画布,然后在画布上绘制;当绘制完成后,使用unlockCanvasAndPost方法来解锁画布,这样才能显示在屏幕上。

  

public class TestSurfaceViewActivity extends Activity {
	MySurfaceView  mySurfaceView;
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		 mySurfaceView=new MySurfaceView(this);
		setContentView(mySurfaceView);
	}
	@Override
	public boolean onTouchEvent(MotionEvent event) {
		// TODO Auto-generated method stub
		mySurfaceView.r+=2;
		return super.onTouchEvent(event);
	}
	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		// TODO Auto-generated method stub
		if(keyCode==KeyEvent.KEYCODE_BACK){
			finish();
		}
		return super.onKeyDown(keyCode, event);
	}
}

运行效果和上面的一样,就不做演示了。

 

     


  • 14
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值