您的位置:首页 > 移动开发 > Android开发

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的注意点提示:





对比上面的左右两图,右图用.lockCanvas(null),而左图用.lockCanvas(new
Rect(oldX, 0, oldX + length,

getWindowManager().getDefaultDisplay().getHeight())),对比一下两个效果,由于左图是按指定Rect绘画,所以效率会比右图的全控件绘画高些,并且在清屏之后(canvas.drawColor(Color.BLACK))不会留有上次绘画的残留
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: