Android的SurfaceView使用

Android的大多数控件都是继承自View的,因此在自定义控件时一般也是继承View类,但是对于高效的,游戏级别的绘图,或者是播放器等要求比较高的地方,普通的View类就

有点吃不开了,这个时候就要用到SurfaceView类。
因为比较高级,所以就该装B,单纯一个继承自SurfaceView类是不行的,必须实现一个SurfaceHolder.Callback接口来指明SurfaceView创建、改变、删除时的回调方法,并且

在SurfaceView中通过一个SurfaceHolder对象来控制SurfaceView。
如果将该SurfaceView作为某个Activity的全屏View,则直接调用setContentView(new MyView());就好了;但若是作为屏幕View的一部份,就应该修改对应的layout XML文件

了,添加类似的布局代码:
    <com.android.sv.MyView
    android:id="@+id/sv"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    />
其中com.example.fq.MyView为对应自定义类的全名。
由于默认的XML文件解析方法是调用View的View(Context , AttributeSet )构造函数构造View,因此你的自定义SurfaceView中也应该有一个参数为(Context , AttributeSet )

的构造函数,并且在构造函数中执行父类的对应函数super( Context , AttributeSet )。

在绘图时,必须首先用Canvas c=holder.lockCanvas();锁定并获得画布,随后进行绘制,再调用holder.unlockCanvasAndPost(c);将绘制内容进行呈现

下面是个例子运行图:


主界面:

public class MainActivity extends Activity {
    /** Called when the activity is first created. */
	private MyView mSV=null;
	private Button mBtnOk;
	private Button mBtnCancle;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        mSV=(MyView)findViewById(R.id.sv);
        mSV.setTag(true);
        mBtnOk=(Button)findViewById(R.id.btnok);
        mBtnOk.setOnClickListener(new OnClickListener() {
			
			public void onClick(View arg0) {
				// TODO Auto-generated method stub
				mSV.setTag(true);
			}
		});
        
        mBtnCancle=(Button)findViewById(R.id.btnCancel);
        mBtnCancle.setOnClickListener(new OnClickListener() {
			
			public void onClick(View arg0) {
				// TODO Auto-generated method stub
				mSV.setTag(false);
			}
		});
    }
}

MyTest界面:

public class MyView extends SurfaceView implements SurfaceHolder.Callback{
	private SurfaceHolder holder=null; //控制对象
	private Vector<Float> xs=new Vector<Float>();
	private Vector<Float> ys=new Vector<Float>();
	public MyView(Context context, AttributeSet attrs) {
		super(context, attrs);
		holder=getHolder();
	    holder.addCallback(this);
	}

	public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
		// TODO Auto-generated method stub
		
	}

	public void surfaceCreated(SurfaceHolder arg0) {
		// TODO Auto-generated method stub
		new Thread(new MyLoop()).start();//在 View 中系统不允许主线程外的线程控制 UI .但是 SurfaceView 却可以
	}

	public void surfaceDestroyed(SurfaceHolder arg0) {
		// TODO Auto-generated method stub
		
	}
	public void doDraw(Canvas canvas) {
		   // TODO Auto-generated method stub
		   super.onDraw(canvas);
		   canvas.drawColor(Color.WHITE);//这里是绘制背景
		   Paint p=new Paint(); //笔触
		   p.setAntiAlias(true); //反锯齿
		   p.setColor(Color.BLACK);
		   p.setStyle(Style.STROKE);
		   int a=xs.size();
		   for(int i=0;i<xs.size();i++)
		    canvas.drawCircle(xs.elementAt(i),ys.elementAt(i),10, p);
		}
	
	@Override
	public boolean onTouchEvent(MotionEvent event) {
	   // TODO Auto-generated method stub
	   if(event.getAction()==MotionEvent.ACTION_DOWN){
		   String a=this.getTag().toString();
		    if(a.equals("true")){
		    	 xs.add(event.getX());
		 	     ys.add(event.getY());
		    }
	   }
	   return true;
	}
	
	class MyLoop implements Runnable{
		//熟悉游戏编程的应该很面熟吧,主循环
		   public void run() {
		    // TODO Auto-generated method stub
		    while(true){
		     try{
		      Canvas c=holder.lockCanvas();
		      doDraw(c);
		      holder.unlockCanvasAndPost(c);
		      Thread.sleep(20);
		     }catch(Exception e){
		     
		     }
		    }
		   }
		  
		}
}

main.xml文件:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
    <com.android.sv.MyView
    android:id="@+id/sv"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    />
    <Button android:id="@+id/btnok"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="开启绘图"/>
    <Button android:id="@+id/btnCancel"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_toRightOf="@id/btnok"
            android:text="取消绘图"/>  
</RelativeLayout>





  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值