android 单点和多点触摸事件

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))不会留有上次绘画的残留


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值