Reader small image

You're reading from  Android Studio 4.1 Development Essentials – Java Edition

Product typeBook
Published inMay 2021
PublisherPackt
ISBN-139781801815161
Edition1st Edition
Right arrow
Author (1)
Neil Smyth
Neil Smyth
author image
Neil Smyth

Neil Smyth has over 25 years of experience in the IT industry, including roles in software development and enterprise-level UNIX and Linux system administration. In addition to a bachelor’s degree in information technology, he also holds A+, Security+, Network+, Project+, and Microsoft Certified Professional certifications and is a CIW Database Design Specialist. Neil is the co-founder and CEO of Payload Media, Inc. (a technical content publishing company), and the author of the Essentials range of programming and system administration books.
Read more about Neil Smyth

Right arrow

29. Implementing Custom Gesture and Pinch Recognition on Android

The previous chapter covered the detection of what are referred to as “common gestures” from within an Android application. In practice, however, a gesture can conceivably involve just about any sequence of touch motions on the display of an Android device. In recognition of this fact, the Android SDK allows custom gestures of just about any nature to be defined by the application developer and used to trigger events when performed by the user. This is a multistage process, the details of which are the topic of this chapter.

29.1 The Android Gesture Builder Application

The Android SDK allows developers to design custom gestures which are then stored in a gesture file bundled with an Android application package. These custom gesture files are most easily created using the Gesture Builder application which is bundled with the samples package supplied as part of the Android SDK. The creation of a gestures file involves launching the Gesture Builder application, either on a physical device or emulator, and “drawing” the gestures that will need to be detected by the application. Once the gestures have been designed, the file containing the gesture data can be pulled off the SD card of the device or emulator and added to the application project. Within the application code, the file is then loaded into an instance of the GestureLibrary class where it can be used to search for matches to any gestures performed by the user on the device display.

29.2 The GestureOverlayView Class

In order to facilitate the detection of gestures within an application, the Android SDK provides the GestureOverlayView class. This is a transparent view that can be placed over other views in the user interface for the sole purpose of detecting gestures.

29.3 Detecting Gestures

Gestures are detected by loading the gestures file created using the Gesture Builder app and then registering a GesturePerformedListener event listener on an instance of the GestureOverlayView class. The enclosing class is then declared to implement both the OnGesturePerformedListener interface and the corresponding onGesturePerformed callback method required by that interface. In the event that a gesture is detected by the listener, a call to the onGesturePerformed callback method is triggered by the Android runtime system.

29.4 Identifying Specific Gestures

When a gesture is detected, the onGesturePerformed callback method is called and passed as arguments a reference to the GestureOverlayView object on which the gesture was detected, together with a Gesture object containing information about the gesture.

With access to the Gesture object, the GestureLibrary can then be used to compare the detected gesture to those contained in the gestures file previously loaded into the application. The GestureLibrary reports the probability that the gesture performed by the user matches an entry in the gestures file by calculating a prediction score for each gesture. A prediction score of 1.0 or greater is generally accepted to be a good match between a gesture stored in the file and that performed by the user on the device display.

29.5 Installing and Running the Gesture Builder Application

The easiest way to create a gestures file is to use an app that will allow gesture motions to be captured and saved. Although Google originally provided an app for this purpose, it has not been maintained adequately for use on more recent versions of Android. Fortunately, an alternative is available in the form of the Gesture Builder app developed by Manan Gandhi which is available from the Google Play Store at the following URL:

https://play.google.com/store/apps/details?id=pack.GestureApp

Note that the app works best on devices or emulators running Android 9.0 (API 28) or older.

29.6 Creating a Gestures File

Once the Gesture Builder application has loaded, click on the Add button located at the bottom of the device screen and, on the subsequent screen, “draw” a gesture using a circular motion on the screen as illustrated in Figure 29-1. Assuming that the gesture appears as required (represented by the yellow line on the device screen), click on the save button to add the gesture to the gestures file, entering “Circle Gesture” when prompted for a name:

Figure 29-1

After the gesture has been saved, return to the main screen where the Gesture Builder app will display a list of currently defined gestures which, at this point, will consist solely of the new Circle Gesture. Before proceeding, use the Test button to verify that the gesture works as intended.

29.7 Creating the Example Project

Select the Create New Project quick start option from the welcome screen and, within the resulting new project dialog, choose the Empty Activity template before clicking on the Next button.

Enter CustomGestures into the Name field and specify com.ebookfrenzy.customgestures as the package name. Before clicking on the Finish button, change the Minimum API level setting to API 26: Android 8.0 (Oreo) and the Language menu to Java.

Extracting the Gestures File from the SD Card

As each gesture was created within the Gesture Builder application, it was added to a file named gesture.txt located in the storage of the emulator or device on which the app was running. Before this file can be added to an Android Studio project, however, it must first be copied off the device storage and saved to the local file system. This is most easily achieved by using the Android Studio Device File Explorer tool window. Display this tool using the View -> Tool Windows...

29.8 Adding the Gestures File to the Project

Within the Android Studio Project tool window, locate and right-click on the res folder (located under app) and select New -> Directory from the resulting menu. In the New Directory dialog, enter raw as the folder name and click on the OK button. Using the appropriate file explorer utility for your operating system type, locate the gestures file previously pulled from the device storage and copy and paste it into the new raw folder in the Project tool window.

29.9 Designing the User Interface

This example application calls for a user interface consisting of a ConstraintLayout view with a GestureOverlayView layered on top of it to intercept any gestures performed by the user. Locate the app -> res -> layout -> activity_main.xml file, double-click on it to load it into the Layout Editor tool and select and delete the default TextView widget.

Switch the layout editor Code mode and modify the XML so that it reads as follows:

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

<androidx.constraintlayout.widget.ConstraintLayout

    xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:app="http://schemas.android.com/apk/res-auto"

    xmlns:tools="http://schemas.android.com/tools"

    android:layout_width="match_parent"

    android:layout_height...

29.10 Loading the Gestures File

Now that the gestures file has been added to the project, the next step is to write some code so that the file is loaded when the activity starts up. For the purposes of this project, the code to achieve this will be added to the MainActivity class located in the MainActivity.java source file as follows:

package com.ebookfrenzy.customgestures;

 

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;

import android.gesture.GestureLibraries;

import android.gesture.GestureLibrary;

import android.gesture.GestureOverlayView;

import android.gesture.GestureOverlayView.OnGesturePerformedListener;

 

public class MainActivity extends AppCompatActivity

        implements OnGesturePerformedListener {

 

 private GestureLibrary gLibrary;

 

    @Override

    protected void onCreate(Bundle savedInstanceState...

29.11 Registering the Event Listener

In order for the activity to receive notification that the user has performed a gesture on the screen, it is necessary to register the OnGesturePerformedListener event listener on the gLayout view, a reference to which can be obtained using the findViewById method as outlined in the following code fragment:

private void gestureSetup() {

    gLibrary =

            GestureLibraries.fromRawResource(this,

                    R.raw.gestures);

    if (!gLibrary.load()) {

        finish();

    }

 

    GestureOverlayView gOverlay = findViewById(R.id.gOverlay);

    gOverlay.addOnGesturePerformedListener(this);

}

29.12 Implementing the onGesturePerformed Method

All that remains before an initial test run of the application can be performed is to implement the OnGesturePerformed callback method. This is the method which will be called when a gesture is performed on the GestureOverlayView instance:

package com.ebookfrenzy.customgestures;

 

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;

import android.gesture.GestureLibraries;

import android.gesture.GestureLibrary;

import android.gesture.GestureOverlayView;

import android.gesture.GestureOverlayView.OnGesturePerformedListener;

import android.gesture.Prediction;

import android.widget.Toast;

import android.gesture.Gesture;

import java.util.ArrayList;

 

public class MainActivity extends AppCompatActivity implements OnGesturePerformedListener {

 

    private GestureLibrary gLibrary;

.

.

    public void onGesturePerformed...

29.13 Testing the Application

Build and run the application on either an emulator or a physical Android device and perform the circle gesture on the display. When performed, the toast notification should appear containing the name of the detected gesture. Note that when a gesture is recognized, it is outlined on the display with a bright yellow line while gestures about which the overlay is uncertain appear as a faded yellow line. While useful during development, this is probably not ideal for a real world application. Clearly, therefore, there is still some more configuration work to do.

29.14 Configuring the GestureOverlayView

By default, the GestureOverlayView is configured to display yellow lines during gestures. The color used to draw recognized and unrecognized gestures can be defined via the android:gestureColor and android:uncertainGestureColor attributes. For example, to hide the gesture lines, modify the activity_main.xml file in the example project as follows:

<android.gesture.GestureOverlayView

    android:id="@+id/gOverlay"

    android:layout_width="0dp"

    android:layout_height="0dp"

    app:layout_constraintBottom_toBottomOf="parent"

    app:layout_constraintEnd_toEndOf="parent"

    app:layout_constraintStart_toStartOf="parent"

    app:layout_constraintTop_toTopOf="parent"

    android:gestureColor...

29.15 Intercepting Gestures

The GestureOverlayView is, as previously described, a transparent overlay that may be positioned over the top of other views. This leads to the question as to whether events intercepted by the gesture overlay should then be passed on to the underlying views when a gesture has been recognized. This is controlled via the android:eventsInterceptionEnabled property of the GestureOverlayView instance. When set to true, the gesture events are not passed to the underlying views when a gesture is recognized. This can be a particularly useful setting when gestures are being performed over a view that might be configured to scroll in response to certain gestures. Setting this property to true will avoid gestures also being interpreted as instructions to the underlying view to scroll in a particular direction.

29.16 Detecting Pinch Gestures

Before moving on from touch handling in general and gesture recognition in particular, the last topic of this chapter is that of handling pinch gestures. While it is possible to create and detect a wide range of gestures using the steps outlined in the previous sections of this chapter it is, in fact, not possible to detect a pinching gesture (where two fingers are used in a stretching and pinching motion, typically to zoom in and out of a view or image) using the techniques discussed so far.

The simplest method for detecting pinch gestures is to use the Android ScaleGestureDetector class. In general terms, detecting pinch gestures involves the following three steps:

1. Declaration of a new class which implements the SimpleOnScaleGestureListener interface including the required onScale(), onScaleBegin() and onScaleEnd() callback methods.

2. Creation of an instance of the ScaleGestureDetector class, passing through an instance of the class created...

29.17 A Pinch Gesture Example Project

Select the Create New Project quick start option from the welcome screen and, within the resulting new project dialog, choose the Empty Activity template before clicking on the Next button.

Enter PinchExample into the Name field and specify com.ebookfrenzy.pinchexample as the package name. Before clicking on the Finish button, change the Minimum API level setting to API 26: Android 8.0 (Oreo) and the Language menu to Java.

Within the activity_main.xml file, select the default TextView object and use the Attributes tool window to set the ID to myTextView.

Locate and load the MainActivity.java file into the Android Studio editor and modify the file as follows:

package com.ebookfrenzy.pinchexample;

 

import androidx.appcompat.app.AppCompatActivity;

import android.os.Bundle;

import android.view.MotionEvent;

import android.view.ScaleGestureDetector;

import android.view.ScaleGestureDetector.SimpleOnScaleGestureListener...

29.18 Summary

A gesture is essentially the motion of points of contact on a touch screen involving one or more strokes and can be used as a method of communication between user and application. Android allows gestures to be designed using the Gesture Builder application. Once created, gestures can be saved to a gestures file and loaded into an activity at application runtime using the GestureLibrary.

Gestures can be detected on areas of the display by overlaying existing views with instances of the transparent GestureOverlayView class and implementing an OnGesturePerformedListener event listener. Using the GestureLibrary, a ranked list of matches between a gesture performed by the user and the gestures stored in a gestures file may be generated, using a prediction score to decide whether a gesture is a close enough match.

Pinch gestures may be detected through the implementation of the ScaleGestureDetector class, an example of which was also provided in this chapter.

...
lock icon
The rest of the chapter is locked
You have been reading a chapter from
Android Studio 4.1 Development Essentials – Java Edition
Published in: May 2021Publisher: PacktISBN-13: 9781801815161
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
undefined
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at £13.99/month. Cancel anytime

Author (1)

author image
Neil Smyth

Neil Smyth has over 25 years of experience in the IT industry, including roles in software development and enterprise-level UNIX and Linux system administration. In addition to a bachelor’s degree in information technology, he also holds A+, Security+, Network+, Project+, and Microsoft Certified Professional certifications and is a CIW Database Design Specialist. Neil is the co-founder and CEO of Payload Media, Inc. (a technical content publishing company), and the author of the Essentials range of programming and system administration books.
Read more about Neil Smyth