android 单点和多点触摸事件
2011-11-27 22:46
253 查看
package cn.m15.xys; import android.app.Activity; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.os.Bundle; import android.util.Log; import android.view.MotionEvent; import android.view.View; public class ViewActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(new MyView(this)); } public class MyView extends View { /** 触摸后绘制的图片 **/ Bitmap mBitmap = null; /** 游戏画笔 **/ Paint mPaint = null; /** 触摸后在屏幕中显示的位置 **/ int mPosX = 0; int mPosY = 0; /**事件触发时间**/ Long mActionTime = 0L; public MyView(Context context) { super(context); /** 设置当前View拥有控制焦点 **/ this.setFocusable(true); /** 设置当前View拥有触摸事件 **/ this.setFocusableInTouchMode(true); /** 加载图片 **/ mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.item); mPaint = new Paint(); mPaint.setColor(Color.WHITE); } @Override protected void onDraw(Canvas canvas) { /** 绘制图片 **/ canvas.drawBitmap(mBitmap, mPosX, mPosY, mPaint); canvas.drawText("当前X坐标:"+mPosX, 0, 20, mPaint); canvas.drawText("当前Y坐标:"+mPosY, 0, 40, mPaint); canvas.drawText("事件触发时间:"+mActionTime, 0, 60, mPaint); super.onDraw(canvas); } @Override public boolean onTouchEvent(MotionEvent event) { int action = event.getAction(); mPosX = (int) event.getX(); mPosY = (int) event.getY(); switch (action) { // 触摸按下的事件 case MotionEvent.ACTION_DOWN: Log.v("test", "ACTION_DOWN"); break; // 触摸移动的事件 case MotionEvent.ACTION_MOVE: Log.v("test", "ACTION_MOVE"); break; // 触摸抬起的事件 case MotionEvent.ACTION_UP: Log.v("test", "ACTION_UP"); break; } /**得到事件触发时间**/ mActionTime = event.getEventTime(); /** 通知UI线程刷新屏幕 **/ postInvalidate(); // return super.onTouchEvent(event); return true; } } }
触摸事件发生时,执行postInvalidate()方法,然后通知ui线程刷新屏幕,(既是执行onDraw方法)。
public class SurfaceViewAcitvity extends Activity { MyView mAnimView = null; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 全屏显示窗口 requestWindowFeature(Window.FEATURE_NO_TITLE); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); // 显示自定义的游戏View mAnimView = new MyView(this); setContentView(mAnimView); } public class MyView extends SurfaceView implements Callback { /** 触摸后绘制的图片 **/ Bitmap mBitmap = null; /** 游戏画笔 **/ Paint mPaint = null; SurfaceHolder mSurfaceHolder = null; /** 控制游戏更新循环 **/ boolean mRunning = false; /** 游戏画布 **/ Canvas mCanvas = null; public MyView(Context context) { super(context); /** 设置当前View拥有控制焦点 **/ this.setFocusable(true); /** 设置当前View拥有触摸事件 **/ this.setFocusableInTouchMode(true); /** 加载图片 **/ mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.item); /** 拿到SurfaceHolder对象 **/ mSurfaceHolder = this.getHolder(); /** 将mSurfaceHolder添加到Callback回调函数中 **/ mSurfaceHolder.addCallback(this); /** 创建画布 **/ mCanvas = new Canvas(); /**创建画笔**/ mPaint = new Paint(); mPaint.setColor(Color.WHITE); } @Override public boolean onTouchEvent(MotionEvent event) { /** 拿到触摸的状态 **/ int action = event.getAction(); /** 控制当触摸抬起时清屏 **/ boolean reset = false; switch (action) { // 触摸按下的事件 case MotionEvent.ACTION_DOWN: Log.v("test", "ACTION_DOWN"); break; // 触摸移动的事件 case MotionEvent.ACTION_MOVE: Log.v("test", "ACTION_MOVE"); break; // 触摸抬起的事件 case MotionEvent.ACTION_UP: Log.v("test", "ACTION_UP"); reset = true; break; } // 在这里加上线程安全锁 synchronized (mSurfaceHolder) { /** 拿到当前画布 然后锁定 **/ mCanvas = mSurfaceHolder.lockCanvas(); /** 清屏 **/ mCanvas.drawColor(Color.BLACK); if (!reset) { /** 在屏幕中拿到同时触碰的点的数量 **/ int pointCount = event.getPointerCount(); /** 使用循环将每个触摸点图片都绘制出来 **/ for (int i = 0; i < pointCount; i++) { /** 根据触摸点的ID 可以讲每个触摸点的X Y坐标拿出来 **/ int x = (int) event.getX(i); int y = (int) event.getY(i); int showX = i * 150; mCanvas.drawBitmap(mBitmap, x, y, mPaint); mCanvas.drawText("当前X坐标:"+x, showX, 20, mPaint); mCanvas.drawText("当前Y坐标:"+y, showX, 40, mPaint); mCanvas.drawText("事件触发时间:"+event.getEventTime(), showX, 60, mPaint); } }else { mCanvas.drawText("请多点触摸当前手机屏幕" ,0, 20, mPaint); } /** 绘制结束后解锁显示在屏幕上 **/ mSurfaceHolder.unlockCanvasAndPost(mCanvas); } // return super.onTouchEvent(event); return true; } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } @Override public void surfaceCreated(SurfaceHolder holder) { } @Override public void surfaceDestroyed(SurfaceHolder holder) { } } }多点触摸事件,根据事件提供的getPointerCount()方法获取触摸点的个数。
使用surfaceView的注意点提示:
![](http://hi.csdn.net/attachment/201011/3/0_12887705085z6p.gif)
![](http://hi.csdn.net/attachment/201011/3/0_1288770532WS4S.gif)
对比上面的左右两图,右图用.lockCanvas(null),而左图用.lockCanvas(new
Rect(oldX, 0, oldX + length,
getWindowManager().getDefaultDisplay().getHeight())),对比一下两个效果,由于左图是按指定Rect绘画,所以效率会比右图的全控件绘画高些,并且在清屏之后(canvas.drawColor(Color.BLACK))不会留有上次绘画的残留
相关文章推荐
- 详解Android 触摸事件处理和传递过程的来龙去脉
- Android触摸事件onScroll和onFling特别重要啊,要区分
- Android 判断触摸点是否在某个view内部,解决子childView与parentView的touch事件冲突
- android触摸事件传递
- Android 手势&触摸事件
- Android 触摸事件监听(Activity层,ViewGroup层,View层)详细介绍
- Android触摸事件分发机制
- Android关于触摸事件跟点击事件两个方法的关系
- [Unity3d for android]屏幕触摸事件
- Android触摸事件传递读书笔记。
- Android 触摸事件传递机制
- 【Android】下拉列表、拖动条、星级评分条与标签文本的触摸事件
- android实现一滴雨(采用onTouchEvent触摸事件和线程)
- android触摸事件传递机制以及onInterceptTouchEvent()和onTouchEvent()总结
- android屏幕触摸事件机制
- android随笔12——toast响应触摸事件以及移动
- android 触摸事件、点击事件的区别,执行流程
- android 触摸事件
- Android触摸事件的应用
- android 控件绘图和触摸事件分发