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上效果也更好呢
android surfaceView 的简单使用 画图,拖动效果的更多相关文章
- js实现一个可以兼容PC端和移动端的div拖动效果
前段时间写了一个简单的div拖动效果,不料昨天项目上正好需要一个相差不多的需求,就正好用上了,但是在移动端的时候却碰到了问题,拖动时候用到的三个事件:mousedown.mousemove.mouse ...
- Android使用SurfaceView实现墨迹天气的风车效果
SurfaceView也是继承自View,它和我们以前接触到的View(Button.TextView等)最大的不同是,SurfaceView可以有一个单独的线程进行绘制,这个线程区别于UI线程(主线 ...
- Android 仿 窗帘效果 和 登录界面拖动效果 (Scroller类的应用) 附 2个DEMO及源码
在android学习中,动作交互是软件中重要的一部分,其中的Scroller就是提供了拖动效果的类,在网上,比如说一些Launcher实现滑屏都可以通过这个类去实现.下面要说的就是上次Scroller ...
- Android 仿 窗帘效果 和 登录界面拖动效果 (Scroller类的应用) 附 2个DEMO及源代码
在android学习中,动作交互是软件中重要的一部分.当中的Scroller就是提供了拖动效果的类,在网上.比方说一些Launcher实现滑屏都能够通过这个类去实现.以下要说的就是上次Scroller ...
- 使用jquery实现简单的拖动效果,分享源码
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAkEAAAERCAIAAADzAOSQAAALRklEQVR4nO3dW5LaaAKEUfa/NkfMGu
- 使用jQuery实现简单的拖动效果
转自:http://www.muzilei.com/archives/136 如何实现拖动效果? 浏览DEMO 首先分析下拖动效果原理: 1.当鼠标在被拖动对象上按下鼠标(触发onmousedown事 ...
- Android SurfaceView 绘图覆盖刷新及脏矩形刷新方法
http://www.cnblogs.com/SkyD/archive/2010/11/08/1871423.html Android SurfaceView 绘图覆盖刷新及脏矩形刷新方法 Surfa ...
- Android SurfaceView实战 带你玩转flabby bird (下)
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/43063331,本文出自:[张鸿洋的博客] 1.概述 在Android Surfa ...
- Android SurfaceView实战 带你玩转flabby bird (上)
转载请标明出处:http://blog.csdn.net/lmj623565791/article/details/42965779 ,本文出自:[张鸿洋的博客] 1.概述 哈,记得以前写过Andro ...
随机推荐
- 【树莓派】树莓派上面安装配置teamviewer
访问树莓派桌面,的另一种方式,就是使用Teamviewer. 参考这篇文章做了实验:http://www.linuxdiyf.com/linux/16887.html,对其中部分进行了件要整理和总结. ...
- 转:nginx模块开发——handler(二)
模块上下文结构 这是一个ngx_http_module_t类型的静态变量.这个变量实际上是提供一组回调函数指针,这些函数有在创建存储配置信息的对象的函数,也有在创建前和创建后会调用的函数.这些函数都将 ...
- PPT里面的背景音乐找不到?
ppt,找不到播放器,却有音乐播放!如何实现? 原来是在幻灯片切换处的音效添加的音乐~ 文章来源:刘俊涛的博客 欢迎关注,有问题一起学习欢迎留言.评论
- spring mvc防止表单重复提交的代码片段
1.定义一个token接口 package com.bigbigrain.token; import java.lang.annotation.Documented; import java.lang ...
- oracle的参数文件:pfile和spfile
1.pfile和spfile Oracle中的参数文件是一个包含一系列参数以及参数对应值的操作系统文件.它们是在数据库实例启动时候加载的,决定了数据库的物理 结构.内存.数据库的限制及系统大量的默认值 ...
- spring & java 面试
https://blog.csdn.net/u014079773/article/details/52453002 1.Spring中AOP的应用场景.Aop原理.好处? 答:AOP--Aspect ...
- OpenWrt/LEDE配置OpenVPN Server
安装openvpn不再赘述 准备证书文件主要有以下文件: (服务端)ca.crtdh2048.pemserver.crtserver.key(客户端)ca.crtclient01.keydp-clie ...
- 解决input 有多少个radio绑定change事件,手动触发就会执行多少次问题
如题,相信大家都会遇到这个问题,那么为什么会触发多次呢?其实当你用jquery绑定onchange事件的时候你就无形中给每个radio绑定了事件,所以才会出现执行多少次的问题了,那么如何解决呢,其实这 ...
- fullcalendar 使用教程
$('#calendar') .fullCalendar( { header : { left : 'today prev,next', center : 'title', right : 'mont ...
- 不可不知的mysql 常用技巧总结
不可不知的mysql 常用技巧总结 mysql常用命令 mysqld --启动mysql数据库 show databases; -- 查看数据库 use database; -- 选择数据库 show ...