android surfaceView 的简单使用 画图,拖动效果

前面说到了画图,其实更好的就是使用 surfaceView了。

surfaceView 继承于 View,View里面嵌套了一个专门用于画图的 surface,

对于一个View的onDraw()方法,不能够满足将其移动到后台线程中去。因为从后台线程修改一个GUI元素会被显式地禁止的。当需要快速地更新View的UI,或者当前渲染代码阻塞GUI线程的时间过长的时候,SurfaceView就是解决上述问题的最佳选择。SurfaceView封装了一个Surface对象,而不是Canvas。这一点很重要,因为Surface可以使用后台线程绘制。对于那些资源敏感的操作,或者那些要求快速更新或者高速帧率的地方,例如使用3D图形,创建游戏,或者实时预览摄像头,这一点特别有用。

可以直接从内存或硬件设备比如相机等取得图像数据,是个非常重要的绘图容器。它的特性是:可以在主线程之外的线程中向屏幕绘图。这样可以避免画图任务繁重的时候造成主线程阻塞,从而提高了程序的反应速度。绘制的东西直接复制到显存从而显示出来,这使得显示速度会非常快,而在Surface 被销毁之前必须结束。

 

下面给个简单的例子,就是不停的绘制 ,这样按照前面说的,就可以再 上面绘制各种自己想要的效果了:

 

 
  1. public class SurfaceDraw  extends Activity{  
  2.      private SurfaceView    sf;      
  3.      private SurfaceHolder  sfh;   //surfaceView的 控制器  
  4.       
  5.     @Override  
  6.     protected void onCreate(Bundle savedInstanceState) {  
  7.         // TODO Auto-generated method stub  
  8.         super.onCreate(savedInstanceState);  
  9.         setContentView(R.layout.activity_draw);  
  10.         sf = (SurfaceView) this.findViewById(R.id.SurfaceView01);  
  11.         //得到控制器  
  12.         sfh = sf.getHolder();  
  13.         //对 surfaceView 进行操作  
  14.         sfh.addCallback(new DoThings());// 自动运行surfaceCreated以及surfaceChanged  
  15.     }  
  16.       
  17.       
  18.     private class DoThings implements SurfaceHolder.Callback{  
  19.         @Override  
  20.         public void surfaceChanged(SurfaceHolder holder, int format, int width,  
  21.                 int height) {  
  22.             //在surface的大小发生改变时激发  
  23.             System.out.println("surfaceChanged");  
  24.         }  
  25.   
  26.         @Override  
  27.         public void surfaceCreated(SurfaceHolder holder){  
  28.             new Thread(){  
  29.                 public void run() {  
  30.                     while(true){  
  31.                         //1.这里就是核心了, 得到画布 ,然后在你的画布上画出要显示的内容  
  32.                         Canvas c = sfh.lockCanvas(new Rect(00200200));  
  33.                         //2.开画  
  34.                         Paint  p =new Paint();  
  35.                         p.setColor(Color.rgb( (int)(Math.random() * 255),   
  36.                                 (int)(Math.random() * 255) ,  (int)(Math.random() * 255)));  
  37.                         Rect aa  =  new Rect( (int)(Math.random() * 100) ,  
  38.                                 (int)(Math.random() * 100)   
  39.                                 ,(int)(Math.random() * 500)   
  40.                                 ,(int)(Math.random() * 500) );  
  41.                         c.drawRect(aa, p);  
  42.                         //3. 解锁画布   更新提交屏幕显示内容  
  43.                         sfh.unlockCanvasAndPost(c);  
  44.                         try {  
  45.                             Thread.sleep(1000);  
  46.                               
  47.                         } catch (Exception e) {  
  48.                         }  
  49.                     }  
  50.                 };  
  51.             }.start();  
  52.               
  53.         }  
  54.   
  55.         @Override  
  56.         public void surfaceDestroyed(SurfaceHolder holder) {  
  57.                //销毁时激发,一般在这里将画图的线程停止、释放。  
  58.             System.out.println("surfaceDestroyed==");     
  59.         }     
  60.     }  
  61. }  

// 实现拖拽效果,也就是动态的绘制

 
  1. public class Drag extends Activity {  
  2.       
  3.     @Override  
  4.     protected void onCreate(Bundle savedInstanceState) {  
  5.             super.onCreate(savedInstanceState);   
  6.             DragImage view=new DragImage(this);   
  7.             setContentView(view);   
  8.     }  
  9.       
  10. private class DragImage extends SurfaceView implements SurfaceHolder.Callback,Runnable,OnTouchListener{  
  11.         private Context context;  
  12.         private SurfaceHolder holder;  
  13.         private Bitmap icon;  
  14.         private Paint paint;  
  15.         private boolean running=true;  
  16.   
  17.         public DragImage(Context context) {  
  18.             super(context);  
  19.             this.context=context;  
  20.             holder = this.getHolder();//获取holder    
  21.             holder.addCallback(this);  
  22.             this.setOnTouchListener(this);           
  23.         }  
  24.           
  25.         @Override  
  26.         public void surfaceCreated(SurfaceHolder holder) {  
  27.               
  28.             icon = BitmapFactory.decodeResource(context.getResources(),R.drawable.wuranl_1);    
  29.             paint=new Paint();  
  30.             running=true;  
  31.             new Thread(this).start();  
  32.               
  33.         }  
  34.   
  35.         @Override  
  36.         public void surfaceChanged(SurfaceHolder holder, int format, int width,  
  37.                 int height) {  
  38.         }  
  39.           
  40.           
  41.         @Override  
  42.         public void surfaceDestroyed(SurfaceHolder holder) {  
  43.             running=false;  
  44.         }  
  45.           
  46.         @Override  
  47.         public void run() {   
  48.             int SLEEP_TIME=100;  
  49.             while (running) {  
  50.                 //开始画的时间    long start=System.currentTimeMillis();  
  51.                  Canvas canvas = holder.lockCanvas();//获取画布   
  52.                  canvas.drawColor(Color.BLACK);  
  53.                  canvas.drawBitmap(icon, rect.left,rect.top,null);  
  54.                  holder.unlockCanvasAndPost(canvas);// 解锁画布,提交画好的图像    
  55.                 //结束的时间   long end=System.currentTimeMillis();    
  56.             }  
  57.         }  
  58.   
  59. //      Region region=new Region();  
  60.         private Point point=new Point();//点击点  
  61.         private Rect rect;//图片的rect  
  62.         private boolean canDrag=false;//判断是否点击在图片上,否则拖动无效  
  63.         private int offsetX=0,offsetY=0;//点击点离图片左上角的距离  
  64.         @Override  
  65.         public boolean onTouch(View v, MotionEvent event) {  
  66.             // TODO Auto-generated method stub  
  67.             switch (event.getAction()) {  
  68.               
  69.             //手按下的时候  
  70.             case MotionEvent.ACTION_DOWN:  
  71.                 point.x=(int)event.getX();  
  72.                 point.y=(int)event.getY();  
  73.                 if(rect.contains(point.x, point.y)){  
  74.                     canDrag=true;  
  75.                     offsetX=point.x-rect.left;  
  76.                     offsetY=point.y-rect.top;  
  77.                 }  
  78.                 break;  
  79.               
  80.             //移动的时候  
  81.             case MotionEvent.ACTION_MOVE:  
  82.                 if(canDrag){  
  83.                     rect.left=(int)event.getX()-offsetX;  
  84.                     rect.top=(int)event.getY()-offsetY;  
  85.                     rect.right=rect.left+icon.getWidth();  
  86.                     rect.bottom=rect.top+icon.getHeight();  
  87.                     if (rect.left < 0) {    
  88.                         rect.left = 0;  
  89.                         rect.right =  rect.left+icon.getWidth();  
  90.                     }    
  91.                     if (rect.right >  getMeasuredWidth()) {    
  92.                         rect.right =  getMeasuredWidth();  
  93.                         rect.left = rect.right-icon.getWidth();  
  94.                     }    
  95.                     if (rect.top < 0) {  
  96.                         rect.top = 0;  
  97.                         rect.bottom = rect.top+icon.getHeight();  
  98.                     }    
  99.                     if (rect.bottom > getMeasuredHeight()) {  
  100.                         rect.bottom = getMeasuredHeight();  
  101.                         rect.top = rect.bottom-icon.getHeight();  
  102.                     }  
  103.                 }  
  104.                 break;  
  105.             case MotionEvent.ACTION_UP:  
  106.                 canDrag=false;  
  107.                 break;  
  108.   
  109.             default:  
  110.                 break;  
  111.             }  
  112.             return true;  
  113.         }  
  114.   
  115.     }  
  116. }  


还有前面在 View上面绘制的动态折线图,在surfaceView上效果也更好呢

posted @ 2013-11-10 16:30  安卓吧  阅读(28207)  评论(0编辑  收藏  举报