Mobile Programming Lecture 12 HierarchyViewer, Linkify, Gestures, and Version Control.

Slides:



Advertisements
Similar presentations
ANDROID – GESTURES L. Grewe. What and why  a great way to interact with applications on mobile devices.  With a touch screen, users can easily tap,
Advertisements

All About Android Introduction to Android 1. Creating a New App “These aren’t the droids we’re looking for.” Obi-wan Kenobi 1. Bring up Eclipse. 2. Click.
Hello world Follow steps under the sections “Create an AVD” and “Create a New Android Project” at
Application Fundamentals. See: developer.android.com/guide/developing/building/index.html.
The Android Development Environment.  Getting started on the Android Platform  Installing required libraries  Programming Android using the Eclipse.
Touch & Gestures.  MotionEvents  Touch Handling  Gestures.
Cosc 5/4730 Game Design. A short game design primer. A game or animation is built on an animation loop. – Instance variables of “objects” are updated.
User Interface Android Applications. Activities An activity presents a visual user interface. Each activity is given a default window to draw in. The.
Android Application Development with Java UPenn CS4HS 2011 Chris Murphy
Android Programming. Outline Preparation Create new project Build and Run a project Debug a project Deploy on devices.
Android Application Development 2013 PClassic Chris Murphy 1.
Data Storage: Part 1 (Preferences)
CS378 - Mobile Computing What's Next?. Fragments Added in Android 3.0, a release aimed at tablets A fragment is a portion of the UI in an Activity multiple.
Mobile Programming Lecture 1 Getting Started. Today's Agenda About the Eclipse IDE Hello, World! Project Android Project Structure Intro to Activities,
Android development the first app. Andoid vs iOS which is better? Short answer: neither Proponents on both sides For an iOS side, see this article on.
Android Boot Camp for Developers Using Java, Comprehensive: A Guide to Creating Your First Android Apps Chapter 9: Customize! Navigating with a Master/Detail.
 Understanding an activity  Starting an activity  Passing information between activities  Understanding intents  Understanding the activity lifecycle.
CS5103 Software Engineering Lecture 08 Android Development II.
Mobile Programming Lecture 2 Layouts, Widgets, Toasts, and Event Handling.
Mobile Programming Lecture 16 The Facebook API. Agenda The Setup Hello, Facebook User Facebook Permissions Access Token Logging Out Graph API.
Introduction to Mobile Programming. Slide 2 Overview Fundamentally, it all works the same way You get the SDK for the device (Droid, Windows, Apple) You.
Hello world Follow steps under the sections “Create an AVD” and “Create a New Android Project” at
Understanding Hello Android 1 CS300. Activity  Similar to a form  Base class for the visual, interactive components of your application  Android API.
Mobile Programming Lecture 6
1 Mobile Computing Advanced Touching Copyright 2014 by Janson Industries Assg Part1Assg Part1 AssgPart2AssgPart2.
1 Announcements Homework #2 due Feb 7 at 1:30pm Submit the entire Eclipse project in Blackboard Please fill out the when2meets when your Project Manager.
@2011 Mihail L. Sichitiu1 Android Introduction GUI Menu Many thanks to Jun Bum Lim for his help with this tutorial.
INTRODUCTION TO ANDROID. Slide 2 Application Components An Android application is made of up one or more of the following components Activities We will.
CS378 - Mobile Computing More UI - Part 2. Special Menus Two special application menus – options menu – context menu Options menu replaced by action bar.
Cosc 4730 Android Fragments. Fragments You can think of a fragment as a modular section of an activity, which has its own lifecycle, receives its own.
Announcements Homework #2 will be posted after class due Thursday Feb 7, 1:30pm you may work with one other person No office hours tonight (sorry!) I will.
Android Using Menus Notes are based on: The Busy Coder's Guide to Android Development by Mark L. Murphy Copyright © CommonsWare, LLC. ISBN:
Mobile Programming Lecture 3 Debugging. Lecture 2 Review What widget would you use to allow the user to enter o a yes/no value o a range of values from.
Mobile Programming Lecture 11 Animation and TraceView.
Android View Stuff. TextViews Display text Display images???
Mobile Programming Lecture 7 Dialogs, Menus, and SharedPreferences.
Copyright© Jeffrey Jongko, Ateneo de Manila University Deconstructing HelloWorld.
CS378 - Mobile Computing More UI - Part 2. Special Menus Two special application menus – options menu – context menu Options menu replaced by action bar.
Intoduction to Andriod studio Environment With a hello world program.
© 2016 Cengage Learning®. May not be scanned, copied or duplicated, or posted to a publicly accessible website, in whole or in part. Android Boot Camp.
Events. Slide 2©SoftMoore Consulting Events Events are generated when a user interacts with the view objects of an application. Examples –button clicked–
Basic 2D Graphics in Android. Android Graphics Programming There are many ways to do graphics programming in Android – 2D vs. 3D – static vs. dynamic.
Mobile Programming Lecture 4 Resources, Selection, Activities, Intents.
CHAPTER 7 TouchGestures. Chapter objectives: To code the detection of and response to touch gestures. Patterns of common touches to create touch gestures.
ANDROID LAYOUTS AND WIDGETS. Slide 2 Introduction Parts of the Android screen Sizing widgets and fonts Layouts and their characteristics Buttons, checkboxes.
Java for android Development Nasrullah Khan. Using instanceof in Android Development the classes such as Button, TextView, and CheckBox, which represent.
Cosc 5/4730 Support design library. Support Design library Adds (API 9+) back support to a number of 5.0 lollipop widgets and material design pieces –
User Interaction Radan Ganchev Astea Solutions. Content Basic input events Gestures Drag and drop Sensors.
CMPE419 Mobile Application Development Asst.Prof.Dr.Ahmet Ünveren SPRING Computer Engineering Department Asst.Prof.Dr.Ahmet Ünveren
CS371m - Mobile Computing Gestures. Common Gestures 2.
Lab7 – Appendix.
Introduction to android
Google VR (gvr) CardBoard and DayDream With OpenGL
Android Programming - Features
TUTORIAL ON MULTITOUCH AND SWIPE GESTURES
滑動版面 建國科技大學 資管系 饒瑞佶 2013/7 V1.
Android – Event Handling
ITEC535 – Mobile Programming
Mobile Computing With Android ACST 4550 Android Logs and Gestures
Android Programming Lecture 6
Cannon Game App Android How to Program
CS371m - Mobile Computing Gestures.
Android Developer Fundamentals V2
CIS 470 Mobile App Development
Interactive Graphics in Android
Mobile Programming Gestures in Android.
Mobile Programming Dr. Mohsin Ali Memon.
Activities and Fragments
Preference Activity class
CIS 470 Mobile App Development
Presentation transcript:

Mobile Programming Lecture 12 HierarchyViewer, Linkify, Gestures, and Version Control

Lecture 11 Review By default, what happens after an Animation has been completed? How do you prevent the default action from occurring? How do you change the behavior of an Animation?

Lecture 11 Review How do you perform multiple Animations on the same View at the same time? How do you animate Activity transitions? Why is using a tool like TraceView important for building mobile applications?

Agenda HiearchyViewer Linkify Gestures GestureDetector GestureOverlayView Version Control with Git

HierarchyViewer You've heard it said that LinearLayouts may be inefficient. How do you know for sure? How long does it take for the system to draw your UI on the screen

HierarchyViewer The HierarchyViewer tool allows you to debug and optimize your UI. It provides a visual representation of the Layout's View Hierarchy

HierarchyViewer To run this tool /tools/hierarchyviewer you may launch your app either before or after you launch the tool Select your app, then select Load View Hiearchy

HierarchyViewer For your Homework 2, what's the time different between loading your LinearLayout versus your RelativeLayout? See HierarchyViewerExample.tar

HierarchyViewer What's the difference between the HierarchyViewer and TraceView?

Linkify Linkify take a piece of text and a regular expression and turns all of the regex matches in the text into clickable links This is particularly useful for matching things like addresses, web urls, etc. and making them actionable.

Linkify See LinkifyExample.tar

GestureDetector Android can detect various gestures and events by the user The GestureDetector.OnGestureListener callback will notify users when a particular motion event has occurred

GestureDetector To use this class: 1.Create an instance of the GestureDetector for your View 2.In the Activity.onTouchEvent(MotionEvent) method ensure you call GestureDetector.onTouchEvent(MotionEvent) The methods defined in your callback will be executed when the events occur.

GestureDetector public class SimpleGestureDetectorExample extends Activity { GestureDetector detector; class MyGestureDetector extends SimpleOnGestureListener public boolean onDoubleTap(MotionEvent e) { Toast.makeText(getApplicationContext(), "You double tapped", Toast.LENGTH_SHORT).show(); return true; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); detector = new GestureDetector(this, new MyGestureDetector()); public boolean onTouchEvent(MotionEvent event) { if (detector.onTouchEvent(event)) return true; else return false; }

GestureDetector public class SimpleGestureDetectorExample extends Activity { GestureDetector detector; class MyGestureDetector extends SimpleOnGestureListener public boolean onDoubleTap(MotionEvent e) { Toast.makeText(getApplicationContext(), "You double tapped", Toast.LENGTH_SHORT).show(); return true; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); detector = new GestureDetector(this, new MyGestureDetector()); public boolean onTouchEvent(MotionEvent event) { if (detector.onTouchEvent(event)) return true; else return false; } 1. Create an instance of GestureDetector for your View

GestureDetector public class SimpleGestureDetectorExample extends Activity { GestureDetector detector; class MyGestureDetector extends SimpleOnGestureListener public boolean onDoubleTap(MotionEvent e) { Toast.makeText(getApplicationContext(), "You double tapped", Toast.LENGTH_SHORT).show(); return true; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); detector = new GestureDetector(this, new MyGestureDetector()); public boolean onTouchEvent(MotionEvent event) { if (detector.onTouchEvent(event)) return true; else return false; } 2. In the Activity.onTouchEvent(MotionEvent) method, ensure you call GestureDetector.onTouchEvent(MotionEvent)

GestureDetector public class SimpleGestureDetectorExample extends Activity { GestureDetector detector; class MyGestureDetector extends SimpleOnGestureListener public boolean onDoubleTap(MotionEvent e) { Toast.makeText(getApplicationContext(), "You double tapped", Toast.LENGTH_SHORT).show(); return true; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); detector = new GestureDetector(this, new MyGestureDetector()); public boolean onTouchEvent(MotionEvent event) { if (detector.onTouchEvent(event)) return true; else return false; } We extend SimpleOnGestureListener, which is a convenience class when you don't want to implement all of the gesture methods

GestureDetector public class SimpleGestureDetectorExample extends Activity { GestureDetector detector; class MyGestureDetector extends SimpleOnGestureListener public boolean onDoubleTap(MotionEvent e) { Toast.makeText(getApplicationContext(), "You double tapped", Toast.LENGTH_SHORT).show(); return true; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); detector = new GestureDetector(this, new MyGestureDetector()); public boolean onTouchEvent(MotionEvent event) { if (detector.onTouchEvent(event)) return true; else return false; } The one we do choose to implement in this example, is onDoubleTap(), although there are many more events that we can implementthere are many more events that we can implement

GestureDetector public class SimpleGestureDetectorExample extends Activity { GestureDetector detector; class MyGestureDetector extends SimpleOnGestureListener public boolean onDoubleTap(MotionEvent e) { Toast.makeText(getApplicationContext(), "You double tapped", Toast.LENGTH_SHORT).show(); return true; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); detector = new GestureDetector(this, new MyGestureDetector()); public boolean onTouchEvent(MotionEvent event) { if (detector.onTouchEvent(event)) return true; else return false; } When our detector detects a double tap, we make a Toast

GestureDetector public class SimpleGestureDetectorExample extends Activity { GestureDetector detector; class MyGestureDetector extends SimpleOnGestureListener public boolean onDoubleTap(MotionEvent e) { Toast.makeText(getApplicationContext(), "You double tapped", Toast.LENGTH_SHORT).show(); return true; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); detector = new GestureDetector(this, new MyGestureDetector()); public boolean onTouchEvent(MotionEvent event) { if (detector.onTouchEvent(event)) return true; else return false; } Return true if you don't want any further processing for this event to occur

GestureDetector public class SimpleGestureDetectorExample extends Activity { GestureDetector detector; class MyGestureDetector extends SimpleOnGestureListener public boolean onDoubleTap(MotionEvent e) { Toast.makeText(getApplicationContext(), "You double tapped", Toast.LENGTH_SHORT).show(); return true; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); detector = new GestureDetector(this, new MyGestureDetector()); public boolean onTouchEvent(MotionEvent event) { if (detector.onTouchEvent(event)) return true; else return false; } Create an instance of MyGestureDetector, that we will use later

GestureDetector public class SimpleGestureDetectorExample extends Activity { GestureDetector detector; class MyGestureDetector extends SimpleOnGestureListener public boolean onDoubleTap(MotionEvent e) { Toast.makeText(getApplicationContext(), "You double tapped", Toast.LENGTH_SHORT).show(); return true; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); detector = new GestureDetector(this, new MyGestureDetector()); public boolean onTouchEvent(MotionEvent event) { if (detector.onTouchEvent(event)) return true; else return false; } This is a callback method for the Activity class, we override onTouchEvent, which may contain a gesture

GestureDetector public class SimpleGestureDetectorExample extends Activity { GestureDetector detector; class MyGestureDetector extends SimpleOnGestureListener public boolean onDoubleTap(MotionEvent e) { Toast.makeText(getApplicationContext(), "You double tapped", Toast.LENGTH_SHORT).show(); return true; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); detector = new GestureDetector(this, new MyGestureDetector()); public boolean onTouchEvent(MotionEvent event) { if (detector.onTouchEvent(event)) return true; else return false; } Our instance of MyGestureDetector will determine if this touch event contains a gesture...

GestureDetector public class SimpleGestureDetectorExample extends Activity { GestureDetector detector; class MyGestureDetector extends SimpleOnGestureListener public boolean onDoubleTap(MotionEvent e) { Toast.makeText(getApplicationContext(), "You double tapped", Toast.LENGTH_SHORT).show(); return true; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); detector = new GestureDetector(this, new MyGestureDetector()); public boolean onTouchEvent(MotionEvent event) { if (detector.onTouchEvent(event)) return true; else return false; } If it does, it checks whether you implemented the callback method for the given gesture

GestureDetector public class SimpleGestureDetectorExample extends Activity { GestureDetector detector; class MyGestureDetector extends SimpleOnGestureListener public boolean onDoubleTap(MotionEvent e) { Toast.makeText(getApplicationContext(), "You double tapped", Toast.LENGTH_SHORT).show(); return true; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); detector = new GestureDetector(this, new MyGestureDetector()); public boolean onTouchEvent(MotionEvent event) { if (detector.onTouchEvent(event)) return true; else return false; } So if the touch event is a double tap, this code will be executed

GestureDetector Another example, implementing the onFling() method of SimpleGestureDetector

GestureDetector class MyGestureDetector extends SimpleOnGestureListener public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { if (Math.abs(e1.getY() - e2.getY()) > 250) return false; if (e1.getX() - e2.getX() > 120 && Math.abs(velocityX) > 200) { Toast.makeText(getApplicationContext(), "You swiped right to left", Toast.LENGTH_SHORT).show(); } else if (e2.getX() - e1.getX() > 120 && Math.abs(velocityX) > 200) { Toast.makeText(getApplicationContext(), "You swiped left to right", Toast.LENGTH_SHORT).show(); } return false; }

GestureDetector class MyGestureDetector extends SimpleOnGestureListener public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { if (Math.abs(e1.getY() - e2.getY()) > 250) return false; if (e1.getX() - e2.getX() > 120 && Math.abs(velocityX) > 200) { Toast.makeText(getApplicationContext(), "You swiped right to left", Toast.LENGTH_SHORT).show(); } else if (e2.getX() - e1.getX() > 120 && Math.abs(velocityX) > 200) { Toast.makeText(getApplicationContext(), "You swiped left to right", Toast.LENGTH_SHORT).show(); } return false; } Override onFling

GestureDetector class MyGestureDetector extends SimpleOnGestureListener public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { if (Math.abs(e1.getY() - e2.getY()) > 250) return false; if (e1.getX() - e2.getX() > 120 && Math.abs(velocityX) > 200) { Toast.makeText(getApplicationContext(), "You swiped right to left", Toast.LENGTH_SHORT).show(); } else if (e2.getX() - e1.getX() > 120 && Math.abs(velocityX) > 200) { Toast.makeText(getApplicationContext(), "You swiped left to right", Toast.LENGTH_SHORT).show(); } return false; } First 2 args are MotionEvent objects, which are used to report some kind of movement, so they store information about an event involving movement

GestureDetector class MyGestureDetector extends SimpleOnGestureListener public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { if (Math.abs(e1.getY() - e2.getY()) > 250) return false; if (e1.getX() - e2.getX() > 120 && Math.abs(velocityX) > 200) { Toast.makeText(getApplicationContext(), "You swiped right to left", Toast.LENGTH_SHORT).show(); } else if (e2.getX() - e1.getX() > 120 && Math.abs(velocityX) > 200) { Toast.makeText(getApplicationContext(), "You swiped left to right", Toast.LENGTH_SHORT).show(); } return false; } e1 stores information about the beginning of the movement, e2 stores the same for the end of the movement

GestureDetector class MyGestureDetector extends SimpleOnGestureListener public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { if (Math.abs(e1.getY() - e2.getY()) > 250) return false; if (e1.getX() - e2.getX() > 120 && Math.abs(velocityX) > 200) { Toast.makeText(getApplicationContext(), "You swiped right to left", Toast.LENGTH_SHORT).show(); } else if (e2.getX() - e1.getX() > 120 && Math.abs(velocityX) > 200) { Toast.makeText(getApplicationContext(), "You swiped left to right", Toast.LENGTH_SHORT).show(); } return false; } velocityX is the speed in the X direction, velocityY is the speed in the Y direction

GestureDetector class MyGestureDetector extends SimpleOnGestureListener public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { if (Math.abs(e1.getY() - e2.getY()) > 250) return false; if (e1.getX() - e2.getX() > 120 && Math.abs(velocityX) > 200) { Toast.makeText(getApplicationContext(), "You swiped right to left", Toast.LENGTH_SHORT).show(); } else if (e2.getX() - e1.getX() > 120 && Math.abs(velocityX) > 200) { Toast.makeText(getApplicationContext(), "You swiped left to right", Toast.LENGTH_SHORT).show(); } return false; } We try to filter out swipes that may be vertical swipes. It's up to you how you want to filter this out

GestureDetector class MyGestureDetector extends SimpleOnGestureListener public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { if (Math.abs(e1.getY() - e2.getY()) > 250) return false; if (e1.getX() - e2.getX() > 120 && Math.abs(velocityX) > 200) { Toast.makeText(getApplicationContext(), "You swiped right to left", Toast.LENGTH_SHORT).show(); } else if (e2.getX() - e1.getX() > 120 && Math.abs(velocityX) > 200) { Toast.makeText(getApplicationContext(), "You swiped left to right", Toast.LENGTH_SHORT).show(); } return false; } Checking for right-to-left swipe. Did the user swipe "long enough"? "Long enough" is arbitrary

GestureDetector class MyGestureDetector extends SimpleOnGestureListener public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { if (Math.abs(e1.getY() - e2.getY()) > 250) return false; if (e1.getX() - e2.getX() > 120 && Math.abs(velocityX) > 200) { Toast.makeText(getApplicationContext(), "You swiped right to left", Toast.LENGTH_SHORT).show(); } else if (e2.getX() - e1.getX() > 120 && Math.abs(velocityX) > 200) { Toast.makeText(getApplicationContext(), "You swiped left to right", Toast.LENGTH_SHORT).show(); } return false; } Checking for right-to-left swipe. Did the user swipe "fast enough"? "Fast enough" is also arbitrary

GestureDetector class MyGestureDetector extends SimpleOnGestureListener public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { if (Math.abs(e1.getY() - e2.getY()) > 250) return false; if (e1.getX() - e2.getX() > 120 && Math.abs(velocityX) > 200) { Toast.makeText(getApplicationContext(), "You swiped right to left", Toast.LENGTH_SHORT).show(); } else if (e2.getX() - e1.getX() > 120 && Math.abs(velocityX) > 200) { Toast.makeText(getApplicationContext(), "You swiped left to right", Toast.LENGTH_SHORT).show(); } return false; } Check for left-to-right swipe

GestureDetector See SimipleGestureDetectorExample.tar

GestureDetector These are gestures anywhere on the Activity itself You may want to check for gestures on a single View or several Views You would need to setup the onTouch events for the individual Views instead

GestureDetector public class GestureDetectorOnViewExampleActivity extends Activity { GestureDetector detector; class MyGestureDetector extends SimpleOnGestureListener public boolean onDoubleTap(MotionEvent e) { Toast.makeText(getApplicationContext(), "You double tapped", Toast.LENGTH_SHORT).show(); return true; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); final TextView tv = (TextView) findViewById(R.id.textView1); tv.setOnTouchListener(new OnTouchListener() public boolean onTouch(View v, MotionEvent event) { detector.onTouchEvent(event); return true; } }); detector = new GestureDetector(this, new MyGestureDetector()); }

GestureDetector public class GestureDetectorOnViewExampleActivity extends Activity { GestureDetector detector; class MyGestureDetector extends SimpleOnGestureListener public boolean onDoubleTap(MotionEvent e) { Toast.makeText(getApplicationContext(), "You double tapped", Toast.LENGTH_SHORT).show(); return true; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); final TextView tv = (TextView) findViewById(R.id.textView1); tv.setOnTouchListener(new OnTouchListener() public boolean onTouch(View v, MotionEvent event) { detector.onTouchEvent(event); return true; } }); detector = new GestureDetector(this, new MyGestureDetector()); } We will setup a double tap event for this TextView

GestureDetector public class GestureDetectorOnViewExampleActivity extends Activity { GestureDetector detector; class MyGestureDetector extends SimpleOnGestureListener public boolean onDoubleTap(MotionEvent e) { Toast.makeText(getApplicationContext(), "You double tapped", Toast.LENGTH_SHORT).show(); return true; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); final TextView tv = (TextView) findViewById(R.id.textView1); tv.setOnTouchListener(new OnTouchListener() public boolean onTouch(View v, MotionEvent event) { detector.onTouchEvent(event); return true; } }); detector = new GestureDetector(this, new MyGestureDetector()); } To do that, we need to know when it is touched

GestureDetector public class GestureDetectorOnViewExampleActivity extends Activity { GestureDetector detector; class MyGestureDetector extends SimpleOnGestureListener public boolean onDoubleTap(MotionEvent e) { Toast.makeText(getApplicationContext(), "You double tapped", Toast.LENGTH_SHORT).show(); return true; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); final TextView tv = (TextView) findViewById(R.id.textView1); tv.setOnTouchListener(new OnTouchListener() public boolean onTouch(View v, MotionEvent event) { detector.onTouchEvent(event); return true; } }); detector = new GestureDetector(this, new MyGestureDetector()); } Similar to the previous example, we call onTouchEvent on the GestureDetector

GestureDetector public class GestureDetectorOnViewExampleActivity extends Activity { GestureDetector detector; class MyGestureDetector extends SimpleOnGestureListener public boolean onDoubleTap(MotionEvent e) { Toast.makeText(getApplicationContext(), "You double tapped", Toast.LENGTH_SHORT).show(); return true; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); final TextView tv = (TextView) findViewById(R.id.textView1); tv.setOnTouchListener(new OnTouchListener() public boolean onTouch(View v, MotionEvent event) { detector.onTouchEvent(event); return true; } }); detector = new GestureDetector(this, new MyGestureDetector()); } If you don't return true here, the double tap will not work. We turn true to indicate that you will handle these touch events yourself

GestureDetector See GestureDetectorOnViewExample.tar See GestureDetectorExample.tar

Custom Gestures How do you recognize a more complex Gesture? GestureDetector won't be able to recognize those for you.

Custom Gestures You can build your own custom gestures using the Gestures Builder app, which is pre- installed on your emulator

Custom Gestures

You may want to add multiple gestures with the same name in order to get it right After adding gestures to the Gestures Builder app, you will need to copy the gestures file over to your res/raw directory

Custom Gestures Open the DDMS Perspective in Eclipse o Window > Show Perspective > Other > DDMS Show the Devices View o Window > Show View > Devices Show the File Explorer View o Window > Show View > File Explorer Select your emulator in the Devices view Browse mnt/sdcard/ Select the gestures file Select the pull a file from device icon Save the file locally Place the file into your res/raw directory

Custom Gestures Now you need to add a GestureOverlayView item onto your canvas Open your Layout XML file In the Palette, open the Advanced Tab Drag a GestureOverlayView onto the canvas and give it an id You should have something like the XML file on the following slide

Custom Gestures <android.gesture.GestureOverlayView xmlns:android=" android:layout_width="fill_parent" android:layout_height="fill_parent" > <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent" >

Custom Gestures The Java code follows

Custom Gestures public class GestureExampleActivity extends Activity implements OnGesturePerformedListener{ GestureOverlayView mOverlay; GestureLibrary public void onCreate(Bundle savedInstanceState) { public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture) { } }

Custom Gestures public class GestureExampleActivity extends Activity implements OnGesturePerformedListener { GestureOverlayView mOverlay; GestureLibrary public void onCreate(Bundle savedInstanceState) { public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture) { } } We implement OnGesturePerformedListene r

Custom Gestures public class GestureExampleActivity extends Activity implements OnGesturePerformedListener { GestureOverlayView mOverlay; GestureLibrary public void onCreate(Bundle savedInstanceState) { public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture) { } } Which forces us to add the onGesturePerformed() callback method, which we show on the next slides

Custom Gestures public class GestureExampleActivity extends Activity implements OnGesturePerformedListener { GestureOverlayView mOverlay; GestureLibrary public void onCreate(Bundle savedInstanceState) { public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture) { } } Note these fields, which we will use later

Custom Gestures GestureOverlayView mOverlay; GestureLibrary public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mOverlay = (GestureOverlayView) findViewById(R.id.gestures); mOverlay.addOnGesturePerformedListener(this); gestureLib = GestureLibraries.fromRawResource(this, R.raw.gestures); if(!gestureLib.load()) Toast.makeText(this, "Couldn't load Gesture Library", Toast.LENGTH_SHORT).show(); public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture) { ArrayList predictions = gestureLib.recognize(gesture); for(Prediction prediction : predictions) { if(prediction.score > 1.0) Toast.makeText(getApplicationContext(), prediction.name, Toast.LENGTH_SHORT).show(); }

Custom Gestures GestureOverlayView mOverlay; GestureLibrary public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mOverlay = (GestureOverlayView) findViewById(R.id.gestures); mOverlay.addOnGesturePerformedListener(this); gestureLib = GestureLibraries.fromRawResource(this, R.raw.gestures); if(!gestureLib.load()) Toast.makeText(this, "Couldn't load Gesture Library", Toast.LENGTH_SHORT).show(); public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture) { ArrayList predictions = gestureLib.recognize(gesture); for(Prediction prediction : predictions) { if(prediction.score > 1.0) Toast.makeText(getApplicationContext(), prediction.name, Toast.LENGTH_SHORT).show(); } The GestureOverlay is a View, so we get a handle on it the usual way

Custom Gestures GestureOverlayView mOverlay; GestureLibrary public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mOverlay = (GestureOverlayView) findViewById(R.id.gestures); mOverlay.addOnGesturePerformedListener(this); gestureLib = GestureLibraries.fromRawResource(this, R.raw.gestures); if(!gestureLib.load()) Toast.makeText(this, "Couldn't load Gesture Library", Toast.LENGTH_SHORT).show(); public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture) { ArrayList predictions = gestureLib.recognize(gesture); for(Prediction prediction : predictions) { if(prediction.score > 1.0) Toast.makeText(getApplicationContext(), prediction.name, Toast.LENGTH_SHORT).show(); } Since our Activity implements onGesturePerformedListener, we set this Activity as the OnGesturePerformedListener

Custom Gestures GestureOverlayView mOverlay; GestureLibrary public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mOverlay = (GestureOverlayView) findViewById(R.id.gestures); mOverlay.addOnGesturePerformedListener(this); gestureLib = GestureLibraries.fromRawResource(this, R.raw.gestures); if(!gestureLib.load()) Toast.makeText(this, "Couldn't load Gesture Library", Toast.LENGTH_SHORT).show(); public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture) { ArrayList predictions = gestureLib.recognize(gesture); for(Prediction prediction : predictions) { if(prediction.score > 1.0) Toast.makeText(getApplicationContext(), prediction.name, Toast.LENGTH_SHORT).show(); } Alternatively, you can create an Anonymous inner class and say mOverlay.addOnGesturePerformedListener(new OnGesturePerformedListener() {...});

Custom Gestures GestureOverlayView mOverlay; GestureLibrary public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mOverlay = (GestureOverlayView) findViewById(R.id.gestures); mOverlay.addOnGesturePerformedListener(this); gestureLib = GestureLibraries.fromRawResource(this, R.raw.gestures); if(!gestureLib.load()) Toast.makeText(this, "Couldn't load Gesture Library", Toast.LENGTH_SHORT).show(); public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture) { ArrayList predictions = gestureLib.recognize(gesture); for(Prediction prediction : predictions) { if(prediction.score > 1.0) Toast.makeText(getApplicationContext(), prediction.name, Toast.LENGTH_SHORT).show(); } GestureLibraries simply allows us to open gesture files

Custom Gestures GestureOverlayView mOverlay; GestureLibrary public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mOverlay = (GestureOverlayView) findViewById(R.id.gestures); mOverlay.addOnGesturePerformedListener(this); gestureLib = GestureLibraries.fromRawResource(this, R.raw.gestures); if(!gestureLib.load()) Toast.makeText(this, "Couldn't load Gesture Library", Toast.LENGTH_SHORT).show(); public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture) { ArrayList predictions = gestureLib.recognize(gesture); for(Prediction prediction : predictions) { if(prediction.score > 1.0) Toast.makeText(getApplicationContext(), prediction.name, Toast.LENGTH_SHORT).show(); } by calling fromRawResource()

Custom Gestures GestureOverlayView mOverlay; GestureLibrary public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mOverlay = (GestureOverlayView) findViewById(R.id.gestures); mOverlay.addOnGesturePerformedListener(this); gestureLib = GestureLibraries.fromRawResource(this, R.raw.gestures); if(!gestureLib.load()) Toast.makeText(this, "Couldn't load Gesture Library", Toast.LENGTH_SHORT).show(); public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture) { ArrayList predictions = gestureLib.recognize(gesture); for(Prediction prediction : predictions) { if(prediction.score > 1.0) Toast.makeText(getApplicationContext(), prediction.name, Toast.LENGTH_SHORT).show(); } and passing the Context and our gestures file as arguments

Custom Gestures GestureOverlayView mOverlay; GestureLibrary public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mOverlay = (GestureOverlayView) findViewById(R.id.gestures); mOverlay.addOnGesturePerformedListener(this); gestureLib = GestureLibraries.fromRawResource(this, R.raw.gestures); if(!gestureLib.load()) Toast.makeText(this, "Couldn't load Gesture Library", Toast.LENGTH_SHORT).show(); public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture) { ArrayList predictions = gestureLib.recognize(gesture); for(Prediction prediction : predictions) { if(prediction.score > 1.0) Toast.makeText(getApplicationContext(), prediction.name, Toast.LENGTH_SHORT).show(); } Try to load the gestures

Custom Gestures GestureOverlayView mOverlay; GestureLibrary public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mOverlay = (GestureOverlayView) findViewById(R.id.gestures); mOverlay.addOnGesturePerformedListener(this); gestureLib = GestureLibraries.fromRawResource(this, R.raw.gestures); if(!gestureLib.load()) Toast.makeText(this, "Couldn't load Gesture Library", Toast.LENGTH_SHORT).show(); public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture) { ArrayList predictions = gestureLib.recognize(gesture); for(Prediction prediction : predictions) { if(prediction.score > 1.0) Toast.makeText(getApplicationContext(), prediction.name, Toast.LENGTH_SHORT).show(); } Now whenever the user performs some gesture, we need to determine if it's one of our predefined gestures

Custom Gestures GestureOverlayView mOverlay; GestureLibrary public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mOverlay = (GestureOverlayView) findViewById(R.id.gestures); mOverlay.addOnGesturePerformedListener(this); gestureLib = GestureLibraries.fromRawResource(this, R.raw.gestures); if(!gestureLib.load()) Toast.makeText(this, "Couldn't load Gesture Library", Toast.LENGTH_SHORT).show(); public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture) { ArrayList predictions = gestureLib.recognize(gesture); for(Prediction prediction : predictions) { if(prediction.score > 1.0) Toast.makeText(getApplicationContext(), prediction.name, Toast.LENGTH_SHORT).show(); } We are provided with our GestureOverlayView, which we defined in our XML Layout file

Custom Gestures GestureOverlayView mOverlay; GestureLibrary public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mOverlay = (GestureOverlayView) findViewById(R.id.gestures); mOverlay.addOnGesturePerformedListener(this); gestureLib = GestureLibraries.fromRawResource(this, R.raw.gestures); if(!gestureLib.load()) Toast.makeText(this, "Couldn't load Gesture Library", Toast.LENGTH_SHORT).show(); public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture) { ArrayList predictions = gestureLib.recognize(gesture); for(Prediction prediction : predictions) { if(prediction.score > 1.0) Toast.makeText(getApplicationContext(), prediction.name, Toast.LENGTH_SHORT).show(); } As well as the Gesture itself. This Object contains information about the shape that was drawn on the overlay

Custom Gestures GestureOverlayView mOverlay; GestureLibrary public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mOverlay = (GestureOverlayView) findViewById(R.id.gestures); mOverlay.addOnGesturePerformedListener(this); gestureLib = GestureLibraries.fromRawResource(this, R.raw.gestures); if(!gestureLib.load()) Toast.makeText(this, "Couldn't load Gesture Library", Toast.LENGTH_SHORT).show(); public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture) { ArrayList predictions = gestureLib.recognize(gesture); for(Prediction prediction : predictions) { if(prediction.score > 1.0) Toast.makeText(getApplicationContext(), prediction.name, Toast.LENGTH_SHORT).show(); } Remember we loaded our gestures into gestureLib. Now we use our GestureLibrary gestureLib to try and recognize the shape that was drawn on the screen

Custom Gestures GestureOverlayView mOverlay; GestureLibrary public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mOverlay = (GestureOverlayView) findViewById(R.id.gestures); mOverlay.addOnGesturePerformedListener(this); gestureLib = GestureLibraries.fromRawResource(this, R.raw.gestures); if(!gestureLib.load()) Toast.makeText(this, "Couldn't load Gesture Library", Toast.LENGTH_SHORT).show(); public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture) { ArrayList predictions = gestureLib.recognize(gesture); for(Prediction prediction : predictions) { if(prediction.score > 1.0) Toast.makeText(getApplicationContext(), prediction.name, Toast.LENGTH_SHORT).show(); } Since it is possible to recognize more than one gesture, we need to store the results in a List

Custom Gestures GestureOverlayView mOverlay; GestureLibrary public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mOverlay = (GestureOverlayView) findViewById(R.id.gestures); mOverlay.addOnGesturePerformedListener(this); gestureLib = GestureLibraries.fromRawResource(this, R.raw.gestures); if(!gestureLib.load()) Toast.makeText(this, "Couldn't load Gesture Library", Toast.LENGTH_SHORT).show(); public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture) { ArrayList predictions = gestureLib.recognize(gesture); for(Prediction prediction : predictions) { if(prediction.score > 1.0) Toast.makeText(getApplicationContext(), prediction.name, Toast.LENGTH_SHORT).show(); } We have a List of Predictions. A Prediction contains a name, which we gave to our Gesture when we used the GesturesBuilder app, and a score, which is the confidence in the prediction

Custom Gestures GestureOverlayView mOverlay; GestureLibrary public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mOverlay = (GestureOverlayView) findViewById(R.id.gestures); mOverlay.addOnGesturePerformedListener(this); gestureLib = GestureLibraries.fromRawResource(this, R.raw.gestures); if(!gestureLib.load()) Toast.makeText(this, "Couldn't load Gesture Library", Toast.LENGTH_SHORT).show(); public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture) { ArrayList predictions = gestureLib.recognize(gesture); for(Prediction prediction : predictions) { if(prediction.score > 1.0) Toast.makeText(getApplicationContext(), prediction.name, Toast.LENGTH_SHORT).show(); } This is a shortcut technique for iterating through the List

Custom Gestures GestureOverlayView mOverlay; GestureLibrary public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mOverlay = (GestureOverlayView) findViewById(R.id.gestures); mOverlay.addOnGesturePerformedListener(this); gestureLib = GestureLibraries.fromRawResource(this, R.raw.gestures); if(!gestureLib.load()) Toast.makeText(this, "Couldn't load Gesture Library", Toast.LENGTH_SHORT).show(); public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture) { ArrayList predictions = gestureLib.recognize(gesture); for(Prediction prediction : predictions) { if(prediction.score > 1.0) Toast.makeText(getApplicationContext(), prediction.name, Toast.LENGTH_SHORT).show(); } Only recognize this as a valid gesture if we have some kind of confidence in the prediction

Custom Gestures GestureOverlayView mOverlay; GestureLibrary public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); mOverlay = (GestureOverlayView) findViewById(R.id.gestures); mOverlay.addOnGesturePerformedListener(this); gestureLib = GestureLibraries.fromRawResource(this, R.raw.gestures); if(!gestureLib.load()) Toast.makeText(this, "Couldn't load Gesture Library", Toast.LENGTH_SHORT).show(); public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture) { ArrayList predictions = gestureLib.recognize(gesture); for(Prediction prediction : predictions) { if(prediction.score > 1.0) Toast.makeText(getApplicationContext(), prediction.name, Toast.LENGTH_SHORT).show(); } To find out which gesture was made, use the name field in the Prediction instance

Custom Gestures See GestureBuilderExample.tar

Version Control For your group projects, you surely don't want to be ing source files to one another whenever you have an update You should use some version control software when working on these kinds of projects

Version Control You will be using Git, and your projects will be hosted on the Mobile Lab servers I will create your projects for you, but you will manage them You and your team members will need to become familiar with Git

Git Quick Start Cloning, committing, and pushing to a remote repo $ git clone git://github.com/git/hello-world.git $ cd hello-world $ (edit files) $ git add (files) $ git commit -m 'Explain what I changed‘ $ git push git://github.com/git/hello-world.git

Git Quick Start Git cheat sheet 1 Git cheat sheet 2

References The Busy Coder's Guide to Android Development - Mark Murphy The Busy Coder's Guide to Android Development - Mark Murphy Android Developers The Mobile Lab at Florida State University