Download presentation
Presentation is loading. Please wait.
Published byPhillip Adams Modified over 9 years ago
1
1 Mobile Computing Advanced Touching Copyright 2014 by Janson Industries Assg Part1Assg Part1 AssgPart2AssgPart2
2
Copyright 2014 by Janson Industries 2 Objectives ▀ Explain u Motion events u Multi-touch u Gestures u Creating gestures
3
Copyright 2014 by Janson Industries 3 Hardware ▀ The touch screen is constructed to pick up pressure on the screen and convert that to data u Screen coordinates u Pressure u Size of touch u Time ▀ All info stored in a MotionEvent object
4
Copyright 2014 by Janson Industries 4 Motion Sequence Actions ▀ The action property holds value that identifies action type u action = 0 (ACTION_DOWN) is the initial touch u action = 2 (ACTION_MOVE) any up, down, or sideways movement on the screen u action = 1 (ACTION_UP) is when finger is lifted off the screen
5
Copyright 2014 by Janson Industries 5 n onTouch or onTouchEvent method called when motion action occurs u A MotionEvent object passed to these methods n For classes that implement onTouchListener, onTouch called n For subclasses of View, onTouchEvent called Motion Sequence
6
Copyright 2014 by Janson Industries 6 Example n Will create a view subclass called TouchTest n Its onTouchEvent will get info from the MotionEvent object and display in LogCat n Will also use the switch structure
7
Copyright 2014 by Janson Industries 7 Nested if/else if (month == 1) { monthTV.setText(“Jan”);} else {if (month == 2) { monthTV.setText(“Feb”);} else { if (month == 3) { monthTV.setText(“Mar”);} else { if (month == 4) {……… Nested if ▮ Placing an if statement as one of the statements to be executed in an if/else clause
8
Copyright 2014 by Janson Industries 8 Switch switch (Month) { case 1: monthTV.setText(“Jan”); break; case 2: monthTV.setText(“Feb”); break; case 3: monthTV.setText(“Mar”); break; : : : : : default: System.out.println(“Not a valid month!”); } ▮ Instead of complicated nested ifs, can use a switch
9
Copyright 2014 by Janson Industries 9 Switch ▮ Need the break statements because once the condition is true, all subsequent statements are executed ▮ In the example, this means ▮ The label is set to Dec ▮ And the “Not a valid month” message displayed
10
Copyright 2014 by Janson Industries 10 TouchTest n TouchTest (a subclass of View) will: n Check for touches n When a touch occurs, display a variety of info about the touch
11
Copyright 2014 by Janson Industries 11 TouchTest package my.touch.com; import android.content.Context; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; public class TouchTest extends View { public TouchTest(Context context, AttributeSet attrs) { super(context); } n Created new TouchProj project, my.touch.com package and Main activity, then create new class TouchTest
12
Copyright 2014 by Janson Industries 12 TouchTest public boolean onTouchEvent(MotionEvent event) { int action = event.getAction(); switch (action) { case 0: System.out.println("Action: " + event.getAction()); System.out.println("Location: " + event.getX() + " x " + event.getY() + " y"); System.out.println("Pressure: " + event.getPressure()); System.out.println("Size: " + event.getSize()); System.out.println("Down time: " + event.getDownTime() + " ms"); System.out.println("Event time: " + event.getEventTime() + " ms"); System.out.println("Elapsed: " + (event.getEventTime() - event.getDownTime()) + " ms"); break;
13
Copyright 2014 by Janson Industries 13 TouchTest case 1: System.out.println("Action: " + event.getAction()); System.out.println("Location: " + event.getX() + " x " + event.getY() + " y"); System.out.println("Pressure: " + event.getPressure()); System.out.println("Size: " + event.getSize()); System.out.println("Down time: " + event.getDownTime() + " ms"); System.out.println("Event time: " + event.getEventTime() + " ms"); System.out.println("Elapsed: " + (event.getEventTime() - event.getDownTime()) + " ms"); break; } return (true); }
14
Copyright 2014 by Janson Industries 14 main.xml <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <my.touch.com.TouchTest android:id="@+id/tt" android:layout_width="wrap_content" android:layout_height="wrap_content" /> n Change activity_main.xml to add TouchTest to main screen
15
Copyright 2014 by Janson Industries 15 TouchTest n Run n Click & hold n Release
16
Copyright 2014 by Janson Industries 16 Touch Test 02-28 13:42:54.086: I/System.out(18244): Action: 0 02-28 13:42:54.086: I/System.out(18244): Location: 325.0 x 500.0 y 02-28 13:42:54.097: I/System.out(18244): Pressure: 1.0 02-28 13:42:54.097: I/System.out(18244): Size: 0.0 02-28 13:42:54.127: I/System.out(18244): Down time: 684320130 ms 02-28 13:42:54.127: I/System.out(18244): Event time: 684320130 ms 02-28 13:42:54.167: I/System.out(18244): Elapsed: 0 ms 02-28 13:42:56.106: I/System.out(18244): Action: 1 02-28 13:42:56.106: I/System.out(18244): Location: 325.0 x 500.0 y 02-28 13:42:56.117: I/System.out(18244): Pressure: 1.0 02-28 13:42:56.131: I/System.out(18244): Size: 0.0 02-28 13:42:56.131: I/System.out(18244): Down time: 684320130 ms 02-28 13:42:56.131: I/System.out(18244): Event time: 684322150 ms 02-28 13:42:56.131: I/System.out(18244): Elapsed: 2020 ms
17
Copyright 2014 by Janson Industries 17 Touch Test n In emulator, pressure and size will always be 1 and 0 n If you click and drag, a series of move actions (2) will be generated n We’ll add a check for an action 2 in the switch
18
Copyright 2014 by Janson Industries 18 TouchTest n Took out the pressure and size displays n Click and drag quickly to right case 2: System.out.println("Action: " + event.getAction()); System.out.println("Location: " + event.getX() + " x " + event.getY() + " y"); System.out.println("Down time: " + event.getDownTime() + " ms"); System.out.println("Event time: " + event.getEventTime() + " ms"); System.out.println("Elapsed: " + (event.getEventTime() - event.getDownTime()) + " ms");
19
Copyright 2014 by Janson Industries 19 Touch Test 02-28 13:48:09.017: I/System.out(18304): Action: 2 02-28 13:48:09.017: I/System.out(18304): Location: 294.843 x 423.79776 y 02-28 13:48:09.037: I/System.out(18304): Down time: 684633418 ms 02-28 13:48:09.037: I/System.out(18304): Event time: 684635056 ms 02-28 13:48:09.037: I/System.out(18304): Elapsed: 1638 ms 02-28 13:48:09.129: I/System.out(18304): Action: 2 02-28 13:48:09.129: I/System.out(18304): Location: 264.81342 x 436.74582 y 02-28 13:48:09.137: I/System.out(18304): Down time: 684633418 ms 02-28 13:48:09.137: I/System.out(18304): Event time: 684635169 ms 02-28 13:48:09.137: I/System.out(18304): Elapsed: 1751 ms 02-28 13:48:09.150: I/System.out(18304): Action: 2 02-28 13:48:09.157: I/System.out(18304): Location: 262.70416 x 437.40497 y 02-28 13:48:09.157: I/System.out(18304): Down time: 684633418 ms 02-28 13:48:09.157: I/System.out(18304): Event time: 684635179 ms 02-28 13:48:09.169: I/System.out(18304): Elapsed: 1761 ms
20
Copyright 2014 by Janson Industries 20 Implementing Touch n Create a View subclass called Square n When screen touched a square will appear around the touch n If movement, square will follow the movement n When touch lifted square disappears
21
Copyright 2014 by Janson Industries 21 Square package my.touch.com; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; public class Square extends View { private float x = -30; // Set initial location off screen private float y = -30; private Paint myPaint; public Square(Context context, AttributeSet attrs) { super(context, attrs); myPaint = new Paint(); myPaint.setColor(Color.BLUE); }
22
Copyright 2014 by Janson Industries 22 Square public boolean onTouchEvent(MotionEvent event) { int action = event.getAction(); switch (action) { case MotionEvent.ACTION_DOWN: // In both cases these case MotionEvent.ACTION_MOVE: // statements are run x = event.getX(); y = event.getY(); break; case MotionEvent.ACTION_UP: x = -30; // set the location outside the screen area y = -30; break; } return (true); } public void draw(Canvas canvas) { canvas.drawRect(x-15, y-15, x+15, y+15, myPaint); invalidate(); }
23
Copyright 2014 by Janson Industries 23 activity_main.xml <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <my.touch.com.Square android:id="@+id/sq" android:layout_width="wrap_content" android:layout_height="wrap_content" />
24
Copyright 2014 by Janson Industries 24 Click Drag Release
25
Copyright 2014 by Janson Industries 25 Assignment - Part 1 n Create Square such that the square is dragged around (as shown earlier) n But when released, square returns to the original clicked location
26
Copyright 2014 by Janson Industries 26 Velocity n Can measure using a VelocityTracker n VelocityTracker initially obtained then u Specify pixels per time period in milliseconds F Per second means 1000 u Feed the events u Retrieve the x and y speeds
27
Copyright 2014 by Janson Industries 27 VelocityEx package my.touch.com; import android.content.Context; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.VelocityTracker; import android.view.View; public class VelocityEx extends View { private VelocityTracker vTracker = null; public VelocityEx(Context context, AttributeSet attrs) { super(context, attrs); }
28
Copyright 2014 by Janson Industries 28 VelocityEx public boolean onTouchEvent(MotionEvent event) { int action = event.getAction(); switch (action) { case 0: if (vTracker == null) { //Get the VelocityTracker object or clear out old data vTracker = VelocityTracker.obtain(); } else { vTracker.clear(); } //Feed initial click down event to set starting point vTracker.addMovement(event); break;
29
Copyright 2014 by Janson Industries 29 VelocityEx case 2: vTracker.addMovement(event); // Sets speed per second vTracker.computeCurrentVelocity(1000); // Displays the x and y velocity System.out.println("X velocity is " + vTracker.getXVelocity() + " pixels per second"); System.out.println("Y velocity is " + vTracker.getYVelocity() + " pixels per second"); break; } return (true); }}
30
Copyright 2014 by Janson Industries 30 VelocityEx <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <my.touch.com.VelocityEx android:id="@+id/ve" android:layout_width="wrap_content" android:layout_height="wrap_content" /> n Change activity_main.xml to display VelocityEx
31
Copyright 2014 by Janson Industries 31 When run
32
Copyright 2014 by Janson Industries 32 Touch n Can put listener on any view subclass u onTouch method will be invoked n Add a TextView to the layout n Main activity must u Implement onTouchListener u Get the text view and add the listener to it
33
Copyright 2014 by Janson Industries 33 Touch <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <TextView android:layout_height="wrap_content" android:text="Example text in text view" android:id="@+id/tV" android:layout_width="wrap_content" android:textSize="35dp"> <my.touch.com.VelocityEx android:id="@+id/ve" android:layout_width="wrap_content" android:layout_height="wrap_content" /> n New TextView
34
Copyright 2014 by Janson Industries 34 Touch ::: import android.view.MotionEvent; import android.view.View; import android.view.View.OnTouchListener; import android.widget.TextView; public class Main extends ActionBarActivity implements OnTouchListener { TextView tv; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //TextView retrieved and listener added tv = (TextView)this.findViewById(R.id.tV); tv.setOnTouchListener(this); } public boolean onTouch(View v, MotionEvent event) { System.out.println("**** Main's onTouch invoked"); return false; } :::
35
Copyright 2014 by Janson Industries 35 onTouch & onTouchEvent ▀ Must return a Boolean value ▀ If it returns true, it means: u The action has been consumed u No other view needs to be notified ▀ If it returns false, it means: u The action has not been consumed u The method is not interested in any other future events for this action u Other views should be notified
36
Copyright 2014 by Janson Industries 36 onTouch returns false so if we click, drag, and then release on the TextView, only one message printed If clicked again, one message will be displayed because it’s a new action
37
Copyright 2014 by Janson Industries 37 onTouch & onTouchEvent ▀ But specifying true also has implications ▀ We will put a checkbox on the main screen ▀ onTouch returns false and the checkbox works like normal <CheckBox android:id="@+id/sampleCB" android:text="example" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="25dp"/>
38
Copyright 2014 by Janson Industries 38 Clicked and released and two messages are displayed
39
Copyright 2014 by Janson Industries 39 CheckBox is checked
40
Copyright 2014 by Janson Industries 40 Change it to true, click and release, and two messages are displayed
41
Copyright 2014 by Janson Industries 41 But the CheckBox is not checked. True says don’t notify other View methods, in this case, the CheckBox’s onTouchEvent method which displays the green check mark and changes the state
42
Copyright 2014 by Janson Industries public boolean onTouch(View v, MotionEvent event) { tv.setText("Pressure: " + String.valueOf(event.getPressure()) + " Size: " + String.valueOf(event.getSize())); System.out.println("**** Main's onTouch invoked"); return true; } 42 Can sense pressure and size of touch but must run on a device (not emulator)
43
Copyright 2014 by Janson Industries 43
44
Copyright 2014 by Janson Industries 44 Assignment – Part 2 ▀ In Square, make the square size relative to the size and pressure of initial touch ▀ Make sure square is easy to see regardless of size and pressure ► Please, no microscopic squares
45
Copyright 2014 by Janson Industries 45 MultiTouch ▀ Complicated and doesn’t always work the same way on different devices and Android implementations ▀ For example, getPointerCount returns the number of fingers touching the screen u On some devices it only reports some of the fingers!
46
Copyright 2014 by Janson Industries 46 MultiTouch ▀ Assuming getPointerCount returned 3, the three touches are referenced by a pointer index ▀ In this case, the pointer index has pointer ids of 0, 1, and 2 located at index locations 0, 1, and 2 u Calls to get info about a touch must include a pointer index location ► getX(pointerIndex);
47
Copyright 2014 by Janson Industries 47 MultiTouch ▀ In addition when the second finger touch occurs the action code is 261 u A third finger 517 ▀ Android returns the pointer index (1) and action code (5) for an additional touch u A hex 0105 equals 261 ► Third finger is 2 and 5, 0205 = 517.
48
Copyright 2014 by Janson Industries 48 MultiTouch ▀ To prove must create new project with latest build level u 1.6 doesn’t support getPointerCount ▀ Will print out the action code and the count of number of touches u Will touch the screen with 3 fingers one after another
49
Copyright 2014 by Janson Industries 49 Touch package com.example.multitouchproj; import android.content.Context; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; public class MultiTouchTest extends View { int action, count; public MultiTouchTest(Context context, AttributeSet attrs) { super(context); } public boolean onTouchEvent(MotionEvent event) { action = event.getAction(); count = event.getPointerCount(); System.out.println("Action: " + action); System.out.println("Count: " + count); return true; }
50
Copyright 2014 by Janson Industries 50 Initial touch and count 2nd touch and count 3rd touch and count
51
Copyright 2014 by Janson Industries 51 MultiTouch ▀ If the first finger gets removed the pointer ids are shifted left in the index u Index 0 holds pointer id 1 u Index 1 holds pointer id 2 ▀ If the first finger touches again it is assigned pointer id 0 in index 0
52
Copyright 2014 by Janson Industries 52 Touch ::: public class MultiTouchTest extends View { int action, count; float xLoc, yLoc; ::: public boolean onTouchEvent(MotionEvent event) { action = event.getAction(); count = event.getPointerCount(); System.out.println("Action: " + action); System.out.println("Count: " + count); for (int counter = 0; counter < count; counter++){ xLoc = event.getX(counter); yLoc = event.getY(counter); System.out.println("Location of " + counter + " touch x:" + xLoc + " y:" + yLoc); } return true; }
53
Copyright 2014 by Janson Industries 53 MultiTouch ▀ Will touch once then twice and then remove first touch ▀ Notice what index is displayed and what the location is
54
Copyright 2014 by Janson Industries 54 1st 2nd Removed first finger
55
Copyright 2014 by Janson Industries 55 MultiTouch ▀ Keeping track complicated! u Thank the Lord for gestures ▀ Gestures are recognizable motions u Been around a long time
56
Copyright 2014 by Janson Industries 56 Gestures ▀ Pinch not supported until 2.2 ▀ Create a new project (GestureProj), package (my.gestures.c om), and set build target to 2.2
57
Copyright 2014 by Janson Industries 57 Gestures ▀ Specify u Activity name u Layout name
58
Copyright 2014 by Janson Industries 58 Gestures ▀ Recognizable recorded motions ▀ Can be single or multi-stroke ▀ When defining, the order of the strokes make a difference ▀ Creating a T gesture like this Different than this
59
Copyright 2014 by Janson Industries 59 Gestures ▀ Can create new ones with Gestures Builder ▀ Start the emulator and display all applications (center icon) ▀ Double click ▀ A blank screen with two buttons on the bottom will be displayed
60
Copyright 2014 by Janson Industries 60
61
Copyright 2014 by Janson Industries 61 Gestures Builder ▀ If it’s not on your device, download it from ▀ On phone need to change download settings to allow unknown source u Settings, Security, tap “Unknown sources ” http://code.google.com/p/quickdroid/downloads/detail? name=com.android.gesture.builder.apk&can=2&q
62
Copyright 2014 by Janson Industries 62
63
Copyright 2014 by Janson Industries 63 Gestures ▀ Click the Add gesture button and move the cursor in the shape of the gesture you want to create ▀ In the data entry field called name, type in a name for the gesture and click Done u Location where it's stored will be displayed ► mnt/ sdcard/gestures
64
Copyright 2014 by Janson Industries 64
65
Copyright 2014 by Janson Industries 65
66
Copyright 2014 by Janson Industries 66 Gestures ▀ If you don’t like the gesture, click the discard button and try again ▀ You can record many gestures with the same name u That’s how you capture all the different ways of drawing a gesture
67
Copyright 2014 by Janson Industries 67 Once saved the gestures will be listed Click/tap and hold a gesture to see a menu of functions that can be performed against one (delete, rename)
68
Copyright 2014 by Janson Industries 68 Deciphering Gestures ▀ Need a GestureOverlayView on the screen ▀ Class must u Implement OnGesturePerformedListener u Add listener to the GestureOverlayView u Have an onGesturePerformed method ► Will be invoked when a gesture is performed
69
Copyright 2014 by Janson Industries 69 Deciphering Gestures ▀ onGesturePerformed will be passed a Gesture object ▀ Class needs a GestureLibrary u Accepts a gesture object u Compares it to all the recorded gestures u Returns an ArrayList of predictions ► Prediction consists of the gesture name and a score
70
Copyright 2014 by Janson Industries 70 Deciphering Gestures ▀ The array list has the predictions in order from most to least likely ▀ So the gesture in position 0 of the ArrayList is what the system thinks is the correct gesture
71
Copyright 2014 by Janson Industries 71 Gestures <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent"> <TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Draw gestures and I'll guess what they are" /> <android.gesture.GestureOverlayView android:id="@+id/gestureOverlay" android:layout_width="fill_parent" android:layout_height="fill_parent" android:gestureStrokeType="multiple" android:fadeOffset="1000" /> If multi-stroke possible must specify
72
Copyright 2014 by Janson Industries 72 Gestures package my.gestures.com; import java.util.ArrayList; import android.app.Activity; import android.gesture.Gesture; import android.gesture.GestureLibraries; import android.gesture.GestureLibrary; import android.gesture.GestureOverlayView; import android.gesture.Prediction; import android.gesture.GestureOverlayView.OnGesturePerformedListener; import android.os.Bundle; import android.util.Log; import android.widget.Toast; public class GestureProjActivity extends Activity implements OnGesturePerformedListener {
73
Copyright 2014 by Janson Industries 73 Gestures GestureLibrary gestureLib = null; Prediction prediction; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main_gesture); gestureLib = GestureLibraries.fromFile("/sdcard/gestures"); if (!gestureLib.load()) { Toast.makeText(this, "Could not load /sdcard/gestures", Toast.LENGTH_SHORT).show(); finish(); } GestureOverlayView gestureView = (GestureOverlayView) findViewById(R.id.gestureOverlay); gestureView.addOnGesturePerformedListener(this); }
74
Copyright 2014 by Janson Industries 74 Deciphering Gestures ▀ If you want to package the gestures with your app u Create the raw folder in res u Copy the gestures file into raw u Create the GestureLibrary as follows ► Instead of creating it from sdcard gestureLib = GestureLibraries.fromRawResource(this, R.raw.gestures);
75
Copyright 2014 by Janson Industries 75
76
Copyright 2014 by Janson Industries 76
77
Copyright 2014 by Janson Industries 77 Gestures public void onGesturePerformed(GestureOverlayView view, Gesture gesture) { ArrayList predictions = gestureLib.recognize(gesture); if (predictions.size() > 0) { prediction = predictions.get(0); if (prediction.score > 1.0) { Toast.makeText(this, prediction.name, Toast.LENGTH_SHORT).show(); } Toast will display the gesture name
78
Copyright 2014 by Janson Industries 78 Initial screen
79
Copyright 2014 by Janson Industries 79
80
Copyright 2014 by Janson Industries 80
81
Copyright 2014 by Janson Industries 81 Gestures for (int i = 0; i < predictions.size(); i++) { System.out.println("prediction " + predictions.get(i).name + "'s score = " + predictions.get(i).score); } n Too see all the predictions scores, add this after the statement that displays the toast
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.