Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Hello.Android.3rd.Edition.pdf
Скачиваний:
33
Добавлен:
02.02.2015
Размер:
3.24 Mб
Скачать

UNDERSTANDING TOUCH EVENTS

225

The entire interface is a big ImageView control that covers the whole screen. The android:src="@drawable/butterfly" value refers to the butterfly image used in the example. You can use any JPG or PNG format image you like; just put it in the res/drawable-nodpi directory. The android:scaleType="matrix" attribute indicates we’re going to use a matrix to control the position and scale of the image. More on that later.

The AndroidManifest.xml file is untouched except for the addition of the android:theme= attribute:

Download Touchv1/AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="org.example.touch"

android:versionCode="1" android:versionName="1.0">

<application android:icon="@drawable/icon" android:label="@string/app_name" android:theme="@android:style/Theme.NoTitleBar.Fullscreen">

<activity android:name=".Touch" android:label="@string/app_name">

<intent-filter>

<action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" />

</intent-filter> </activity>

</application>

<uses-sdk android:minSdkVersion="3" android:targetSdkVersion="8" /> </manifest>

@android:style/Theme.NoTitleBar.Fullscreen, as the name suggests, tells Android to use the entire screen with no title bar or status bar at the top. You can run the application now, and it will simply display the picture.

11.3Understanding Touch Events

Whenever I first learn a new API, I like to first put in some code to dump everything out so I can get a feel for what the methods do and in what order events happen. So let’s start with that. First add a call to the dumpEvent( ) method inside onTouch( ):

Download Touchv1/src/org/example/touch/Touch.java

@Override

public boolean onTouch(View v, MotionEvent event) { // Dump touch event to log

dumpEvent(event);

return true; // indicate event was handled

}

UNDERSTANDING TOUCH EVENTS 226

Note that we need to return true to indicate to Android that the event has been handled. Next, define the dumpEvent( ) method. The only parameter is the event that we want to dump.

Download Touchv1/src/org/example/touch/Touch.java

/** Show an event in the LogCat view, for debugging */ private void dumpEvent(MotionEvent event) {

String names[] = { "DOWN", "UP", "MOVE", "CANCEL", "OUTSIDE", "POINTER_DOWN", "POINTER_UP", "7?", "8?", "9?" };

StringBuilder sb = new StringBuilder(); int action = event.getAction();

int actionCode = action & MotionEvent.ACTION_MASK; sb.append("event ACTION_").append(names[actionCode]); if (actionCode == MotionEvent.ACTION_POINTER_DOWN

|| actionCode == MotionEvent.ACTION_POINTER_UP) { sb.append("(pid ").append(

action >> MotionEvent.ACTION_POINTER_ID_SHIFT); sb.append(")");

}

sb.append("[");

for (int i = 0; i < event.getPointerCount(); i++) { sb.append("#").append(i);

sb.append("(pid ").append(event.getPointerId(i)); sb.append(")=").append((int) event.getX(i)); sb.append(",").append((int) event.getY(i));

if (i + 1 < event.getPointerCount()) sb.append(";");

}

sb.append("]"); Log.d(TAG, sb.toString());

}

Output will go to the Android debug log, which you can see by opening the LogCat view (see Section 3.10, Debugging with Log Messages, on page 69).

The easiest way to understand this code is to run it. Unfortunately, you can’t run this program on the emulator (actually you can, but the emulator doesn’t support multi-touch, so the results won’t be very interesting). Therefore, hook up a real phone to your USB port, and run the sample there (see Section 1.4, Running on a Real Phone, on page 28).

When I tried it on my phone and performed a few quick gestures, I received the following output:

Line 1 event ACTION_DOWN[#0(pid 0)=135,179]

-event ACTION_MOVE[#0(pid 0)=135,184]

-event ACTION_MOVE[#0(pid 0)=144,205]

-event ACTION_MOVE[#0(pid 0)=152,227]

5 event ACTION_POINTER_DOWN(pid 1)[#0(pid 0)=153,230;#1(pid 1)=380,538] - event ACTION_MOVE[#0(pid 0)=153,231;#1(pid 1)=380,538]

UNDERSTANDING TOUCH EVENTS 227

-event ACTION_MOVE[#0(pid 0)=155,236;#1(pid 1)=364,512]

-event ACTION_MOVE[#0(pid 0)=157,240;#1(pid 1)=350,498]

-event ACTION_MOVE[#0(pid 0)=158,245;#1(pid 1)=343,494]

10 event ACTION_POINTER_UP(pid 0)[#0(pid 0)=158,247;#1(pid 1)=336,484]

-event ACTION_MOVE[#0(pid 1)=334,481]

-event ACTION_MOVE[#0(pid 1)=328,472]

-event ACTION_UP[#0(pid 1)=327,471]

Here’s how to interpret the events:

On line 1 we see an ACTION_DOWN event, so the user must have pressed one finger on the screen. The finger was positioned at coordinates x=135, y=179, which is near the upper left of the display. You can’t tell yet whether they’re trying to do a tap or a drag.

Next, starting on line 2, there are some ACTION_MOVE events, indicating the user moved their finger around a bit to those coordinates given in the events. (It’s actually very hard to put your finger on the screen and not move it at all, so you’ll get a lot of these.) By the amount moved, you can tell the user is doing a drag gesture.

The next event, ACTION_POINTER_DOWN on line 5, means the user pressed down another finger. “pid 1” means that pointer ID 1 (that is, finger number 1) was pressed. Finger number 0 was already down, so we now have two fingers being tracked on the screen. In theory, the Android API can support up to 256 fingers at once, but the first crop of Android 2.x phones is limited to 2.3 The coordinates for both fingers come back as part of the event. It looks like the user is about to start a pinch zoom gesture.

Here’s where it gets interesting. The next thing we see is a series of ACTION_MOVE events starting on line 6. Unlike before, now we have two fingers moving around. If you look closely at the coordinates, you can see the fingers are moving closer together as part of a pinch zoom.

Then on line 10, we see an ACTION_POINTER_UP on pid 0. This means that finger number 0 was lifted off the screen. Finger number 1 is still there. Naturally, this ends the pinch zoom gesture.

We see a couple more ACTION_MOVE events starting on line 11, indicating the remaining finger is still moving around a little. If you compare these to the earlier move events, you’ll notice a dif-

3.Although the idea of 256 fingers may seem silly outside of Men in Black headquarters, keep in mind that Android is designed for a wide variety of devices, not just phones. If you have a tabletop-sized screen with several people gathered around it, you could easily have more than a handful of fingers on the display.

SETTING UP FOR IMAGE TRANSFORMATION 228

ferent pointer ID is reported. Unfortunately, the touch API is so buggy you can’t always count on that (see the “Warning: Multibugs Ahead” sidebar).

Finally, on line 13, we get an ACTION_UP event as the last finger is removed from the screen.

Now the code for dumpEvent( ) should make a little more sense. The getAction( ) method returns the action being performed (up, down, or move). The lowest 8 bits of the action is the action code itself, and the next 8 bits is the pointer (finger) ID, so we have to use a bitwise AND

(&) and a right shift (>>) to separate them.

Then we call the getPointerCount( ) method to see how many finger positions are included. getX( ) and getY( ) return the X and Y coordinates, respectively. The fingers can appear in any order, so we have to call getPointerId( ) to find out which fingers we’re really talking about.

That covers the raw mouse event data. The trick, as you might imagine, is in interpreting and acting on that data.

11.4Setting Up for Image Transformation

To move and zoom the image, we’ll use a neat little feature on the ImageView class called matrix transformation. Using a matrix we can represent any kind of translation, rotation, or skew that we want to do to the image. We already turned it on by specifying android:scaleType= "matrix" in the res/layout/main.xml file. In the Touch class, we need to declare two matrices as fields (one for the current value and one for the original value before the transformation). We’ll use them in the onTouch( ) method to transform the image. We also need a mode variable to tell whether we’re in the middle of a drag or zoom gesture, and we need the start, mid, and oldDist variables for controlling zooming:

Download Touchv1/src/org/example/touch/Touch.java

public class Touch extends Activity implements OnTouchListener {

//These matrices will be used to move and zoom image Matrix matrix = new Matrix();

Matrix savedMatrix = new Matrix();

//We can be in one of these 3 states

static final int NONE = 0; static final int DRAG = 1; static final int ZOOM = 2; int mode = NONE;

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]