Analysis of Android multi-touch MultiTouch
Statement:
The following describes how to use the application layer to support multi-touch operations and the onTouchEvent () method for conventional control touch operations. At the same time, I have some knowledge about the parameter MotionEvent OF THE onTouchEvent method.
Body:
Next we will use two application examples to take a preliminary look at the multi-touch in Android.
Example 1 (DemoMultiTouch-Canvas): Core Technology Introduction
In this example, Canvas is used in SurfaceView to show users' multi-touch. However, the core technology is still a common method: onTouchEvent (MotionEvent event)
MotionEvent has the following methods that you need to pay attention to. However, it is a common method, if you use onTouchEvent a lot.
Event. getAction () // obtain touch actions such as ACTION_DOWN
Event. getPointerCount (); // obtain the number of touch points. For example, if 2 is used, two fingers may simultaneously press the screen.
Event. getPointerId (nID); // For the details of each touch point, we can obtain the index by executing the getPointerId method in a loop.
Event. getX (nID); // obtain the x position of the nID touch point
Event. getY (nID); // obtain the y position of the nID point.
Event. getPressure (nID); // LCD can sense the user's finger pressure. Of course, the specific level is determined by the driver and physical hardware.
Event. getDownTime () // Press Start Time
Event. getEventTime () // event end time
Event. getEventTime ()-event. getDownTime (); // it takes a long time to press
Code display:
Public class MTView extends SurfaceView implements SurfaceHolder. callback {private static final int MAX_TOUCHPOINTS = 10; private static final String START_TEXT = "Please touch the screen to test"; private Paint textPaint = new Paint (); private Paint touchPaints [] = new Paint [MAX_TOUCHPOINTS]; private int colors [] = new int [MAX_TOUCHPOINTS]; private int width, height; private float scale = 1.0f; public MTView (Context context) {Super (context); SurfaceHolder holder = getHolder (); holder. addCallback (this); setFocusable (true); // ensure that our View can obtain the input focus setFocusableInTouchMode (true); // ensure that the touch screen event init () is received ();} private void init () {// initialize 10 paint brushes of different colors textPaint. setColor (Color. WHITE); colors [0] = Color. BLUE; colors [1] = Color. RED; colors [2] = Color. GREEN; colors [3] = Color. YELLOW; colors [4] = Color. CYAN; colors [5] = Color. MAGENTA; colors [6] = Color. D KGRAY; colors [7] = Color. WHITE; colors [8] = Color. LTGRAY; colors [9] = Color. GRAY; for (int I = 0; I <MAX_TOUCHPOINTS; I ++) {touchPaints [I] = new Paint (); touchPaints [I]. setColor (colors [I]) ;}/ *** process touch screen events */@ Overridepublic boolean onTouchEvent (MotionEvent event) {// obtain the number of screen contacts int pointerCount = event. getPointerCount (); if (pointerCount> MAX_TOUCHPOINTS) {pointerCount = MAX_TOUCHPOINTS;} // lock the Canvas and start corresponding Canvas c = getHolder (). lockCanvas (); if (c! = Null) {c. drawColor (Color. BLACK); if (event. getAction () = MotionEvent. ACTION_UP) {// clear screen} else {// draw a cross and coordinate information on each contact for (int I = 0; I <pointerCount; I ++) {int id = event. getPointerId (I); int x = (int) event. getX (I); int y = (int) event. getY (I); drawCrosshairsAndText (x, y, touchPaints [id], I, id, c);} // draw a circle for (int I = 0; I <pointerCount; I ++) {int id = event. getPointerId (I); int x = (Int) event. getX (I); int y = (int) event. getY (I); drawCircle (x, y, touchPaints [id], c) ;}// after painting, unlockgetHolder (). unlockCanvasAndPost (c);} return true ;} /*** cross and coordinate information ** @ param x * @ param y * @ param paint * @ param ptr * @ param id * @ param c */private void drawCrosshairsAndText (int x, int y, Paint paint, int ptr, int id, Canvas c) {c. drawLine (0, y, width, y, paint); c. drawLine (x, 0, x, height, paint ); Int textY = (int) (15 + 20 * ptr) * scale); c. drawText ("x" + ptr + "=" + x, 10 * scale, textY, textPaint); c. drawText ("y" + ptr + "=" + y, 70 * scale, textY, textPaint); c. drawText ("id" + ptr + "=" + id, width-55 * scale, textY, textPaint );} /*** circle ** @ param x * @ param y * @ param paint * @ param c */private void drawCircle (int x, int y, Paint paint, Canvas c) {c. drawCircle (x, y, 40 * scale, paint );}/*** When entering the program, the background is painted black, and START_TEXT is written to the screen */public void surfaceChanged (SurfaceHolder holder, int format, int width, int height) {this. width = width; this. height = height; if (width> height) {this. scale = width/480f;} else {this. scale = height/480f;} textPaint. setTextSize (14 * scale); Canvas c = getHolder (). lockCanvas (); if (c! = Null) {c. drawColor (Color. BLACK); float tWidth = textPaint. measureText (START_TEXT); c. drawText (START_TEXT, width/2-tWidth/2, height/2, textPaint); getHolder (). unlockCanvasAndPost (c) ;}} public void surfaceCreated (SurfaceHolder holder) {} public void surfaceDestroyed (SurfaceHolder holder ){}}
So easy to use:
setContentView(new MTView(this));
Run:
Example 2 (DemoMultiTouch-ImageView ):
Using a multi-point touch screen to zoom in or zoom out the image beforeLenght is used to save the distance between two points in the previous time afterLenght is used to save the distance between the two points in the current time
Public void scaleWithFinger (MotionEvent event) {float moveX = event. getX (1)-event. getX (0); float moveY = event. getY (1)-event. getY (0); switch (event. getAction () {case MotionEvent. ACTION_DOWN: beforeLenght = (float) Math. sqrt (moveX * moveX) + (moveY * moveY); break; case MotionEvent. ACTION_MOVE: // get the length of afterLenght = (float) Math between two points. sqrt (moveX * moveX) + (moveY * moveY); float gapLenght = afterLenght-beforeLenght; if (gapLenght = 0) {break ;} // if the distance between the two points in the current time is greater than the distance between the two points in the previous time, 0 is passed; otherwise, 1 If (gapLenght> 0) {this. setScale (scale, 0);} else {this. setScale (scale, 1) ;}beforelenght = afterLenght; break ;}}}
BeforeX and Y are used to save the coordinates of the previous position. afterX and Y are used to save the coordinates of the current position. Their difference is the increase or decrease of the ImageView coordinates.
public void moveWithFinger(MotionEvent event) {switch (event.getAction()) {case MotionEvent.ACTION_DOWN:beforeX = event.getX();beforeY = event.getY();break;case MotionEvent.ACTION_MOVE:afterX = event.getX();afterY = event.getY();this.setLocation((int) (afterX - beforeX),(int) (afterY - beforeY));beforeX = afterX;beforeY = afterY;break;case MotionEvent.ACTION_UP:break;}}
This function is used to zoom in and out the ImageView. Because the image is filled with the ImageView, the effect of flag is 0, which is to zoom in the image and 1 is to zoom out the image.
private void setScale(float temp, int flag) {if (flag == 0) {this.setFrame(this.getLeft() - (int) (temp * this.getWidth()),this.getTop() - (int) (temp * this.getHeight()),this.getRight() + (int) (temp * this.getWidth()),this.getBottom() + (int) (temp * this.getHeight()));} else {this.setFrame(this.getLeft() + (int) (temp * this.getWidth()),this.getTop() + (int) (temp * this.getHeight()),this.getRight() - (int) (temp * this.getWidth()),this.getBottom() - (int) (temp * this.getHeight()));}}
The onTouchEvent event is as follows:
public boolean onTouchEvent(MotionEvent event) {if (inView(imageView, event)) {if (event.getPointerCount() == 2) {imageView.scaleWithFinger(event);} else if (event.getPointerCount() == 1) {imageView.moveWithFinger(event);}}return true;}
Download source code:
Http://download.csdn.net/detail/u013761665/8719349