In some cases, you may want to capture custom-defined gestures in your android application. And at the same time, you may also want to detect general gestures ( such as double-tap, long press, scroll, etc) on the special view component. This article will tell you how to combine custom-defined gestures and general gestures together in one android app.
If you do not have a basic gesture coding experience, you can read the article How To Detect Common Android Gestures and Android Implement And Recognize Custom Gesture Example to learn more. This example is based on the above two examples.
1. Combine Custom Defined And General Gestures Example.
If you can not watch the above video, you can see it on the youtube URL https://youtu.be/Rie7rNWZo4A
- There is an ImageView wrapped by GestureOverlayView widget.
- The code implements ImageView‘s long press, double-tap, and scroll gesture.
- And the GestureOverlayView widget detects two user-defined gestures saved in the gesture.txt file. You can read Android Implement And Recognize Custom Gesture Example to learn how to create the custom-defined gesture file.
- When you long-press, double-tap, or scroll on the ImageView, it will pop up a Toast message.
- When you make other uncommon gestures, the GestureOverlayView object will detect and prompt Toast message also.
2. Combine Custom And Common Gestures Example Source Files.
- Below is the example source files list.
D:\WORK\DEV2QA.COM-EXAMPLE-CODE\ANDROIDEXAMPLEPROJECT\COMBINECUSTOMCOMMONGESTURE │ .gitignore │ build.gradle │ gradle.properties │ gradlew │ gradlew.bat │ settings.gradle │ ├─.idea │ gradle.xml │ misc.xml │ modules.xml │ runConfigurations.xml │ ├─app │ │ .gitignore │ │ build.gradle │ │ proguard-rules.pro │ │ │ └─src │ ├─androidTest │ │ └─java │ │ └─com │ │ └─dev2qa │ │ └─android │ │ └─example │ │ └─gestureoverlayviewinterceptevents │ │ ExampleInstrumentedTest.java │ │ │ ├─main │ │ │ AndroidManifest.xml │ │ │ │ │ ├─java │ │ │ └─com │ │ │ └─dev2qa │ │ │ └─android │ │ │ └─example │ │ │ └─gestureoverlayviewinterceptevents │ │ │ CustomGestureListener.java │ │ │ GeneralGestureListener.java │ │ │ MainActivity.java │ │ │ │ │ └─res │ │ ├─drawable │ │ │ green_button.jpg │ │ │ ic_launcher_background.xml │ │ │ │ │ ├─drawable-v24 │ │ │ ic_launcher_foreground.xml │ │ │ │ │ ├─layout │ │ │ activity_main.xml │ │ ├─raw │ │ │ gesture.txt
2.1 Main Activity Java File.
- MainActivity.java
package com.dev2qa.android.example.gestureoverlayviewinterceptevents; import android.gesture.GestureLibraries; import android.gesture.GestureLibrary; import android.gesture.GestureOverlayView; import android.os.Bundle; import android.support.v4.view.GestureDetectorCompat; import android.support.v7.app.AppCompatActivity; import android.view.MotionEvent; import android.view.View; import android.widget.ImageView; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); setTitle("dev2qa.com - GestureOverlayView Intercept Events Example."); addCustomGestureListener(); addGeneralGestureListener(); } /* * Use GestureOverlayView to detect custom gesture saved in gesture library. */ private void addCustomGestureListener() { // Get the GestureOverlayView widget object. final GestureOverlayView gestureOverlayView = (GestureOverlayView)findViewById(R.id.custom_gesture_overlay_view); // Build the custom gesture library with gesture builder created file. GestureLibrary gestureLibrary = GestureLibraries.fromRawResource(getApplicationContext(), R.raw.gesture); // Load custom gestures into library. gestureLibrary.load(); // Create an instance of custom gesture listener. CustomGestureListener myGestureListener = new CustomGestureListener(getApplicationContext(), gestureLibrary); // Add custom gesture listener instance to gesture overlay view to listen custom gesture. gestureOverlayView.addOnGesturePerformedListener(myGestureListener); // You can also set an on touch listener to the gesture overlay view to listen to on touch event. gestureOverlayView.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View view, MotionEvent motionEvent) { //Toast.makeText(getApplicationContext(), "Gesture overlay view on touch event occured.", Toast.LENGTH_LONG).show(); return true; } }); } /* Use GestureDetectorCompat to detect general gesture take place on the image view. */ private void addGeneralGestureListener() { ImageView imageView = (ImageView)findViewById(R.id.general_gesture_imageview); // This gesture listener is used with the image view. GeneralGestureListener imageViewGestureListener = new GeneralGestureListener(getApplicationContext()); // Create image view gesture detector. final GestureDetectorCompat imageViewGestureDetectorCompat = new GestureDetectorCompat(this, imageViewGestureListener); // Set double tap listener. imageViewGestureDetectorCompat.setOnDoubleTapListener(imageViewGestureListener); // Set a new OnTouchListener to image view. imageView.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View view, MotionEvent motionEvent) { // When image view ontouch event occurred, call it's gesture detector's onTouchEvent method. imageViewGestureDetectorCompat.onTouchEvent(motionEvent); // Return true to tell android OS this listener has consumed the event, do not need to pass the event to other listeners. return true; } }); } }
2.2 Custom Defined Gesture Perform Listener.
- CustomGestureListener.java
package com.dev2qa.android.example.gestureoverlayviewinterceptevents; import android.content.Context; import android.gesture.Gesture; import android.gesture.GestureLibrary; import android.gesture.GestureOverlayView; import android.gesture.Prediction; import android.widget.Toast; import java.util.ArrayList; /** */ public class CustomGestureListener implements GestureOverlayView.OnGesturePerformedListener { private Context context = null; private GestureLibrary gLibrary = null; public CustomGestureListener(Context context, GestureLibrary gLibrary) { this.context = context; this.gLibrary = gLibrary; } @Override public void onGesturePerformed(GestureOverlayView gestureOverlayView, Gesture gesture) { // Recognize the gesture and return prediction list. ArrayList<Prediction> pList = gLibrary.recognize(gesture); if(pList.size() > 0) { String message = ""; // Get the first prediction. Prediction fp = pList.get(0); /* Higher score higher gesture match. */ if(fp.score > 5) { String action = fp.name; message = "Your gesture match " + action; }else { message = "Your gesture do not match any predefined gestures."; } Toast.makeText(context, message, Toast.LENGTH_LONG).show(); } } }
2.3 General Gesture Detect Listener.
- GeneralGestureListener.java
package com.dev2qa.android.example.gestureoverlayviewinterceptevents; import android.content.Context; import android.view.GestureDetector; import android.view.MotionEvent; import android.widget.Toast; public class GeneralGestureListener extends GestureDetector.SimpleOnGestureListener { private Context context = null; public GeneralGestureListener(Context context) { this.context = context; } @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { Toast.makeText(context, "Image view on scrolling. ", Toast.LENGTH_LONG).show(); return true; } @Override public boolean onDoubleTap(MotionEvent e) { Toast.makeText(context, "Image view on double tap. ", Toast.LENGTH_LONG).show(); return true; } @Override public void onLongPress(MotionEvent e) { Toast.makeText(context, "Image view on long press. ", Toast.LENGTH_LONG).show(); } }
2.4 Main Activity Layout Xml File.
- Please note the android:fadeOffset=”1000″ attribute, this attribute means the gesture will fade out after 1000 milliseconds when the user completes the gesture operation.
- activity_main.xml
<LinearLayout android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <android.gesture.GestureOverlayView android:id="@+id/custom_gesture_overlay_view" android:layout_width="match_parent" android:layout_height="match_parent" android:gestureColor="@color/colorPrimary" android:uncertainGestureColor="@android:color/holo_red_light" android:gestureStrokeType="multiple" android:eventsInterceptionEnabled="true" android:gestureStrokeLengthThreshold="1" android:fadeEnabled="true" android:fadeOffset="1000"> <ImageView android:id="@+id/general_gesture_imageview" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/green_button" android:layout_gravity="center"> </ImageView> </android.gesture.GestureOverlayView> </LinearLayout>
Reference