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

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

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

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

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

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




public class SurfaceDraw  extends Activity{
	 private SurfaceView    sf;    
	 private SurfaceHolder  sfh;   //surfaceView的 控制器
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_draw);
		sf = (SurfaceView) this.findViewById(R.id.SurfaceView01);
		//得到控制器
		sfh = sf.getHolder();
		//对 surfaceView 进行操作
		sfh.addCallback(new DoThings());// 自动运行surfaceCreated以及surfaceChanged
	}
	
	
	private class DoThings implements SurfaceHolder.Callback{
		@Override
		public void surfaceChanged(SurfaceHolder holder, int format, int width,
				int height) {
			//在surface的大小发生改变时激发
			System.out.println("surfaceChanged");
		}

		@Override
		public void surfaceCreated(SurfaceHolder holder){
			new Thread(){
				public void run() {
					while(true){
						//1.这里就是核心了, 得到画布 ,然后在你的画布上画出要显示的内容
						Canvas c = sfh.lockCanvas(new Rect(0, 0, 200, 200));
						//2.开画
						Paint  p =new Paint();
						p.setColor(Color.rgb( (int)(Math.random() * 255), 
								(int)(Math.random() * 255) ,  (int)(Math.random() * 255)));
						Rect aa  =  new Rect( (int)(Math.random() * 100) ,
								(int)(Math.random() * 100) 
								,(int)(Math.random() * 500) 
								,(int)(Math.random() * 500) );
						c.drawRect(aa, p);
						//3. 解锁画布   更新提交屏幕显示内容
						sfh.unlockCanvasAndPost(c);
						try {
							Thread.sleep(1000);
							
						} catch (Exception e) {
						}
					}
				};
			}.start();
			
		}

		@Override
		public void surfaceDestroyed(SurfaceHolder holder) {
			   //销毁时激发,一般在这里将画图的线程停止、释放。
			System.out.println("surfaceDestroyed==");	
		}	
	}
}


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


public class Drag extends Activity {
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		    super.onCreate(savedInstanceState);	
		    DragImage view=new DragImage(this); 
	        setContentView(view); 
	}
	
private class DragImage extends SurfaceView implements SurfaceHolder.Callback,Runnable,OnTouchListener{
		private Context context;
		private SurfaceHolder holder;
		private Bitmap icon;
		private Paint paint;
		private boolean running=true;

		public DragImage(Context context) {
			super(context);
			this.context=context;
			holder = this.getHolder();//获取holder  
	        holder.addCallback(this);
	        this.setOnTouchListener(this);	       
		}
		
		@Override
		public void surfaceCreated(SurfaceHolder holder) {
			
			icon = BitmapFactory.decodeResource(context.getResources(),R.drawable.wuranl_1);  
			paint=new Paint();
			running=true;
			new Thread(this).start();
			
		}

		@Override
		public void surfaceChanged(SurfaceHolder holder, int format, int width,
				int height) {
		}
		
		
		@Override
		public void surfaceDestroyed(SurfaceHolder holder) {
			running=false;
		}
		
		@Override
		public void run() {	
			int SLEEP_TIME=100;
			while (running) {
				//开始画的时间    long start=System.currentTimeMillis();
				 Canvas canvas = holder.lockCanvas();//获取画布 
				 canvas.drawColor(Color.BLACK);
				 canvas.drawBitmap(icon, rect.left,rect.top,null);
				 holder.unlockCanvasAndPost(canvas);// 解锁画布,提交画好的图像  
				//结束的时间   long end=System.currentTimeMillis();  
			}
		}

//		Region region=new Region();
		private Point point=new Point();//点击点
		private Rect rect;//图片的rect
		private boolean canDrag=false;//判断是否点击在图片上,否则拖动无效
		private int offsetX=0,offsetY=0;//点击点离图片左上角的距离
		@Override
		public boolean onTouch(View v, MotionEvent event) {
			// TODO Auto-generated method stub
			switch (event.getAction()) {
			
			//手按下的时候
			case MotionEvent.ACTION_DOWN:
				point.x=(int)event.getX();
				point.y=(int)event.getY();
				if(rect.contains(point.x, point.y)){
					canDrag=true;
					offsetX=point.x-rect.left;
					offsetY=point.y-rect.top;
				}
				break;
			
			//移动的时候
			case MotionEvent.ACTION_MOVE:
				if(canDrag){
					rect.left=(int)event.getX()-offsetX;
					rect.top=(int)event.getY()-offsetY;
					rect.right=rect.left+icon.getWidth();
					rect.bottom=rect.top+icon.getHeight();
					if (rect.left < 0) {  
						rect.left = 0;
						rect.right =  rect.left+icon.getWidth();
		            }  
		            if (rect.right >  getMeasuredWidth()) {  
		            	rect.right =  getMeasuredWidth();
		            	rect.left = rect.right-icon.getWidth();
		            }  
		            if (rect.top < 0) {
		            	rect.top = 0;
		            	rect.bottom = rect.top+icon.getHeight();
		            }  
		            if (rect.bottom > getMeasuredHeight()) {
		            	rect.bottom = getMeasuredHeight();
		            	rect.top = rect.bottom-icon.getHeight();
		            }
				}
				break;
			case MotionEvent.ACTION_UP:
				canDrag=false;
				break;

			default:
				break;
			}
			return true;
		}

	}
}

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



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

空白的泡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值