View:对于绘画来说,最重要的步骤是重载 onDraw方法并且修改画布Canvas。
SurfaceView:1,You can control the format of this surface and, if you like, its size;
2,One of the purposes of this class is to provide a surface in which a secondary thread can render into the screen.
SurfaceView 和 View 的主要区别:
1,SurfaceView 可以在主线程和非主线程中更新UI显示,也就是SurfaceView直接控制最顶层屏幕中可见的Canvas.
所以SurfaceView适用于系统自动计算的被动更新,而View适用于需要用户互动的主动更新。
SurfaceHolder 是对SurfaceView对象的控制。比如修改大小,屏幕改变事件等,需要设置SurfaceHolder.Callback接口
2,SurfaceView 更新画面的速度较View快,因为SurfaceView的“画布”surface比View的画布canvas更底层。
下面是两个视图的代码对比:
1 public class MainActivity extends Activity { 2 3 4 private Thread mThread =null; 5 private MogulView mView=null; 6 private MogulSurfaceView mSurfaceView=null; 7 private final int MSG_REFRESH_VIEW =0; 8 @Override 9 protected void onCreate(Bundle savedInstanceState) { 10 super.onCreate(savedInstanceState); 11 //使用surfaceView可以直接在非主线程中更新canvas; 12 // setContentView(new MogulSurfaceView(this)); 13 14 //在非主线程中更新View的时候需要调用到hanler 协助更新View视图 15 mView =new MogulView(this); 16 setContentView(mView); 17 startViewRender(); 18 19 } 20 21 //用于协助其他线程更新View中的Canvas 22 private Handler mHandler =new Handler(){ 23 24 @Override 25 public void handleMessage(Message msg) { 26 if(msg.what ==MSG_REFRESH_VIEW){ 27 //to refresh view 28 if(mView !=null) 29 mView.invalidate(); 30 } 31 } 32 33 }; 34 35 public void startViewRender(){ 37 mThread =new Thread(new Runnable() 38 { 39 40 @Override 41 public void run() { 42 while(true){ 43 try{ 44 // 45 Thread.sleep(1000); 46 } 47 catch(Exception e){ 48 49 } 50 finally{ 51 mHandler.sendEmptyMessage(MSG_REFRESH_VIEW); 52 } 53 } 54 55 } 56 }); 57 mThread.start(); 58 } 59 60 61 class MogulView extends View{ 62 int r =10; 63 public MogulView(Context context) { 64 super(context); 65 // TODO Auto-generated constructor stub 66 } 67 68 //重载View中的canvas 69 @Override 70 protected void onDraw(Canvas canvas) { 71 super.onDraw(canvas); 72 if(r<=100) 73 r+=10; 74 else 75 r =10; 76 Paint paint =new Paint(); 77 paint.setColor(Color.RED); 78 canvas.drawCircle(150, 150, r, paint); 79 } 80 81 82 } 83 84 85 class MogulSurfaceView extends SurfaceView implements SurfaceHolder.Callback{ 86 87 private SurfaceHolder mSurfaceHolder =null; 88 private MogulThread mThread =null; 89 public MogulSurfaceView(Context context) { 90 super(context); 91 mSurfaceHolder =this.getHolder(); 92 mSurfaceHolder.addCallback(this); 93 mThread =new MogulThread(mSurfaceHolder); 94 95 } 96 97 @Override 98 public void surfaceCreated(SurfaceHolder holder) { 99 // TODO Auto-generated method stub 100 mThread.isRun=true; 101 mThread.start(); 102 } 103 104 @Override 105 public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { 106 // TODO Auto-generated method stub 107 108 } 109 110 @Override 111 public void surfaceDestroyed(SurfaceHolder holder) { 112 mThread.isRun=false; 113 mThread.stop(); 114 } 115 116 } 117 class MogulThread extends Thread{ 118 private SurfaceHolder mSurfaceHolder =null; 119 private boolean isRun =false; 120 MogulThread( SurfaceHolder holder){ 121 this.mSurfaceHolder=holder; 122 isRun =true; 123 } 124 //直接在非主线程中更新Canvas 125 @Override 126 public void run() { 127 Canvas canvas=null; 128 int count =0; 129 while(true){ 130 try{ 131 132 synchronized (mSurfaceHolder) { 133 canvas =mSurfaceHolder.lockCanvas(); 134 canvas.drawColor(Color.BLACK); 135 Paint paint=new Paint(); 136 paint.setColor(Color.RED); 137 Rect rect =new Rect(500,200,250,300); 138 canvas.drawRect(rect, paint); 139 canvas.drawText("程序已经运行了:"+count+"秒", 100, 100, paint); 140 Thread.sleep(1000); 141 count++; 142 143 } 144 } 145 catch(Exception e){ 146 e.printStackTrace(); 147 } 148 finally{ 149 if(canvas!=null){ 150 mSurfaceHolder.unlockCanvasAndPost(canvas); 151 } 152 } 153 } 154 } 155 156 157 } 158 159 160 161 162 163 164 }