关闭

SurfaceView

120人阅读 评论(0) 收藏 举报
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);将绘制内容进行呈现

下面是个例子运行图:


主界面:

 

[java] view plaincopy
  1. public class MainActivity extends Activity  
  2.       
  3.     private MyView mSV=null 
  4.     private Button mBtnOk;  
  5.     private Button mBtnCancle;  
  6.     @Override  
  7.     public void onCreate(Bundle savedInstanceState)  
  8.         super.onCreate(savedInstanceState);  
  9.         setContentView(R.layout.main);  
  10.         mSV=(MyView)findViewById(R.id.sv);  
  11.         mSV.setTag(true);  
  12.         mBtnOk=(Button)findViewById(R.id.btnok);  
  13.         mBtnOk.setOnClickListener(new OnClickListener()  
  14.               
  15.             public void onClick(View arg0)  
  16.                 // TODO Auto-generated method stub  
  17.                 mSV.setTag(true);  
  18.              
  19.         });  
  20.           
  21.         mBtnCancle=(Button)findViewById(R.id.btnCancel);  
  22.         mBtnCancle.setOnClickListener(new OnClickListener()  
  23.               
  24.             public void onClick(View arg0)  
  25.                 // TODO Auto-generated method stub  
  26.                 mSV.setTag(false);  
  27.              
  28.         });  
  29.      
  30.  

MyTest界面:

 

[java] view plaincopy
  1. public class MyView extends SurfaceView implements SurfaceHolder.Callback{  
  2.     private SurfaceHolder holder=null//控制对象  
  3.     private Vector<Float> xs=new Vector<Float>();  
  4.     private Vector<Float> ys=new Vector<Float>();  
  5.     public MyView(Context context, AttributeSet attrs)  
  6.         super(context, attrs);  
  7.         holder=getHolder();  
  8.         holder.addCallback(this);  
  9.      
  10.   
  11.     public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3)  
  12.         // TODO Auto-generated method stub  
  13.           
  14.      
  15.   
  16.     public void surfaceCreated(SurfaceHolder arg0)  
  17.         // TODO Auto-generated method stub  
  18.         new Thread(new MyLoop()).start();//在 View 中系统不允许主线程外的线程控制 UI .但是 SurfaceView 却可以  
  19.      
  20.   
  21.     public void surfaceDestroyed(SurfaceHolder arg0)  
  22.         // TODO Auto-generated method stub  
  23.           
  24.      
  25.     public void doDraw(Canvas canvas)  
  26.            // TODO Auto-generated method stub  
  27.            super.onDraw(canvas);  
  28.            canvas.drawColor(Color.WHITE);//这里是绘制背景  
  29.            Paint p=new Paint(); //笔触  
  30.            p.setAntiAlias(true); //反锯齿  
  31.            p.setColor(Color.BLACK);  
  32.            p.setStyle(Style.STROKE);  
  33.            int a=xs.size();  
  34.            for(int i=0;i<xs.size();i++)  
  35.             canvas.drawCircle(xs.elementAt(i),ys.elementAt(i),10p);  
  36.          
  37.       
  38.     @Override  
  39.     public boolean onTouchEvent(MotionEvent event)  
  40.        // TODO Auto-generated method stub  
  41.        if(event.getAction()==MotionEvent.ACTION_DOWN){  
  42.            String a=this.getTag().toString();  
  43.             if(a.equals("true")){  
  44.                  xs.add(event.getX());  
  45.                  ys.add(event.getY());  
  46.              
  47.         
  48.        return true 
  49.      
  50.       
  51.     class MyLoop implements Runnable{  
  52.         //熟悉游戏编程的应该很面熟吧,主循环  
  53.            public void run()  
  54.             // TODO Auto-generated method stub  
  55.             while(true){  
  56.              try 
  57.               Canvas c=holder.lockCanvas();  
  58.               doDraw(c);  
  59.               holder.unlockCanvasAndPost(c);  
  60.               Thread.sleep(20);  
  61.              }catch(Exception e){  
  62.                
  63.               
  64.              
  65.             
  66.             
  67.          
  68.  

main.xml文件:

 

[java] view plaincopy
  1. < ?xml version="1.0" encoding="utf-8"?>  
  2. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"  
  3.     android:layout_width="fill_parent"  
  4.     android:layout_height="fill_parent"  
  5.      
  6.     <com.android.sv.MyView  
  7.     android:id="@+id/sv"  
  8.     android:layout_width="fill_parent"  
  9.     android:layout_height="fill_parent"  
  10.     />  
  11.     <Button android:id="@+id/btnok"  
  12.             android:layout_width="wrap_content"  
  13.             android:layout_height="wrap_content"  
  14.             android:text="开启绘图"/>  
  15.     <Button android:id="@+id/btnCancel"  
  16.             android:layout_width="wrap_content"  
  17.             android:layout_height="wrap_content"  
  18.             android:layout_toRightOf="@id/btnok"  
  19.             android:text="取消绘图"/>    
  20. </RelativeLayout>  
0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:1210次
    • 积分:48
    • 等级:
    • 排名:千里之外
    • 原创:3篇
    • 转载:5篇
    • 译文:0篇
    • 评论:0条
    文章分类