zoukankan      html  css  js  c++  java
  • 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上效果也更好呢

  • 相关阅读:
    树状数组
    #135. 二维树状数组 3:区间修改,区间查询
    poj 2155 (二维树状数组 区间修改 求某点值)
    #133. 二维树状数组 1:单点修改,区间查询
    poj 3468 (区间修改 区间查询)
    树状数组 模板
    1535:【例 1】数列操作
    最通俗全面理解application context中的context是什么意思
    牛客哈理工小乐乐下象棋(深度理解bfs好题)
    牛客哈理工小乐乐打游戏(bfs深度理解好题)
  • 原文地址:https://www.cnblogs.com/android100/p/android-surfaceView.html
Copyright © 2011-2022 走看看