• After 15+ years, we've made a big change: Android Forums is now Early Bird Club. Learn more here.

Apps Multiple gesture detector with specific actions on button

qwisatz

Lurker
I have a button that has onTouchListener that uses android_gesture_detector.
I'm trying to get something simple working with the gesture detector.
The whole xml basically has a textView called "topText" on it.
I gave the textView a listener so "topText.setOnTouchListener".

The conditions I've setted are
1. If single tap then topText.setText("tap Press")
2. else if onScroll then topText.setText("scroll Press")
3. else if doubleTap then topText.setText("Double Tap")

Code:
        topText.setOnTouchListener(new View.OnTouchListener()
        {
            @Override
            public boolean onTouch(View view, MotionEvent e) {

                //IF SHORT PRESS
                if(android_gesture_detector.onSingleTapConfirmed(e)){
                    topText.setText("TAP PRESS");

                } else if (android_gesture_detector.onScroll(e,  e,  100 , 50)){
                    //ON SCROLL TOUCH
                    topText.setText("THIS IS A DRAG");
                } else if (android_gesture_detector.onDoubleTap(e)){
                    //ON DOUBLE TAP
                    topText.setText("THIS IS A DOUBLE TAP");
                }
                return false;
            }
        });

just some simple conditions to test if it works.

In the Logcat, it detects all the touch gestures. The problem is it only runs the first condition from my if statement in my "topText.setOnTouchListener" so the app on does "tap Press" and double tapping the textView doesn't change the text to "Double Tap". How do I enable the other conditions to work? It ignores all my other else if statements.

My full Main Activity Code:
Code:
package com.example.qwisatz.androidgestures;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {
    //GestureDetector OBJECT
    private GestureDetector mGestureDetector;
    TextView topText;
    Button button;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        topText = (TextView) findViewById(R.id.topText);
        button = (Button) findViewById(R.id.button);


        // Create an object of the Android_Gesture_Detector  Class
        final Android_Gesture_Detector  android_gesture_detector  =  new Android_Gesture_Detector();
        // Create a GestureDetector
        mGestureDetector = new GestureDetector(this, android_gesture_detector); //android_gesture_detector =  GestureDetector.OnGestureListener


        topText.setOnTouchListener(new View.OnTouchListener()
        {
            @Override
            public boolean onTouch(View view, MotionEvent e) {

                //IF SHORT PRESS
                if(android_gesture_detector.onSingleTapConfirmed(e)){
                    topText.setText("TAP PRESS");

                } else if (android_gesture_detector.onScroll(e,  e,  100 , 50)){
                    //ON SCROLL TOUCH
                    topText.setText("THIS IS A DRAG");
                } else if (android_gesture_detector.onDoubleTap(e)){
                    //ON DOUBLE TAP
                    topText.setText("THIS IS A DOUBLE TAP");
                }
                return false;
            }
        });

    }

    //INTERCEPT ALL BASIC GESTURES IMPLEMENTED IN IT
    //REROUTES THEM TO THE Android_Gesture_Detector CLASS
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        mGestureDetector.onTouchEvent(event);
        return super.onTouchEvent(event);
        // Return true if you have consumed the event, false if you haven't.
        // The default implementation always returns false.
    }
}

class Android_Gesture_Detector implements GestureDetector.OnGestureListener,
        GestureDetector.OnDoubleTapListener {

    //DRAGGING BOOLEAN


    @Override
    public boolean onDown(MotionEvent e) {
        Log.d("Gesture ", " onDown");
        return true;
    }

    @Override
    public boolean onSingleTapConfirmed(MotionEvent e) {
        Log.d("Gesture ", " onSingleTapConfirmed");
        return true;
    }

    @Override
    public boolean onSingleTapUp(MotionEvent e) {
        Log.d("Gesture ", " onSingleTapUp");
        return true;
    }

    @Override
    public void onShowPress(MotionEvent e) {
        Log.d("Gesture ", " onShowPress");

    }

    @Override
    public boolean onDoubleTap(MotionEvent e) {
        Log.d("Gesture ", " onDoubleTap");
        return true;
    }

    @Override
    public boolean onDoubleTapEvent(MotionEvent e) {
        Log.d("Gesture ", " onDoubleTapEvent");
        return true;
    }

    @Override
    public void onLongPress(MotionEvent e) {
        Log.d("Gesture ", " onLongPress");
    }

    @Override
    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {

        Log.d("Gesture ", " onScroll");
        if (e1.getY() < e2.getY()){
            Log.d("Gesture ", " Scroll Down");
        }
        if(e1.getY() > e2.getY()){
            Log.d("Gesture ", " Scroll Up");
        }
        return true;
    }

    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
        if (e1.getX() < e2.getX()) {
            Log.d("Gesture ", "Left to Right swipe: "+ e1.getX() + " - " + e2.getX());
            Log.d("Speed ", String.valueOf(velocityX) + " pixels/second");
        }
        if (e1.getX() > e2.getX()) {
            Log.d("Gesture ", "Right to Left swipe: "+ e1.getX() + " - " + e2.getX());
            Log.d("Speed ", String.valueOf(velocityX) + " pixels/second");
        }
        if (e1.getY() < e2.getY()) {
            Log.d("Gesture ", "Up to Down swipe: " + e1.getX() + " - " + e2.getX());
            Log.d("Speed ", String.valueOf(velocityY) + " pixels/second");
        }
        if (e1.getY() > e2.getY()) {
            Log.d("Gesture ", "Down to Up swipe: " + e1.getX() + " - " + e2.getX());
            Log.d("Speed ", String.valueOf(velocityY) + " pixels/second");
        }
        return true;
    }
}

My XML layout:
Code:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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="match_parent"
    tools:context="com.example.qwisatz.androidgestures.MainActivity">

    <TextView
        android:id="@+id/topText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</android.support.constraint.ConstraintLayout>
 
Try returning 'true' from your onTouch() methods.

Do you mean here at the listener like this?
Code:
topText.setOnTouchListener(new View.OnTouchListener()
{
    @Override
    public boolean onTouch(View view, MotionEvent e) {

        //IF SHORT PRESS
        if(android_gesture_detector.onSingleTapConfirmed(e)){
            topText.setText("TAP PRESS");
            return true;

        } else if (android_gesture_detector.onScroll(e,  e,  100 , 50)){
            //ON SCROLL TOUCH
            topText.setText("THIS IS A DRAG");
            return true;
        } else if (android_gesture_detector.onDoubleTap(e)){
            //ON DOUBLE TAP
            topText.setText("THIS IS A DOUBLE TAP");
            return true;
        }
        return false;
    }

});

I also tried :
Code:
topText.setOnTouchListener(new View.OnTouchListener()
{
    @Override
    public boolean onTouch(View view, MotionEvent e) {

        //IF SHORT PRESS
        if(android_gesture_detector.onSingleTapConfirmed(e)){
            topText.setText("TAP PRESS");
        } else if (android_gesture_detector.onScroll(e,  e,  100 , 50)){
            //ON SCROLL TOUCH
            topText.setText("THIS IS A DRAG");
        } else if (android_gesture_detector.onDoubleTap(e)){
            //ON DOUBLE TAP
            topText.setText("THIS IS A DOUBLE TAP");
        }
        return true;
    }
});

But both of them still doesn't work.
 
You're complicating things somewhat by having two levels of gesture detection. Your MainActivity implements the onSingleTap() onDoubleTap() etc. methods.
I'd be inclined to get rid of those, as you're simply using them for logging purposes anyway.

The way to properly investigate and diagnose this problem is to run your app in debug mode, and set breakpoints in the code, specifically in your OnTouchListener methods. In this way you can see exactly what events are propagated to your listener method, and see how your code reacts to them.
Debug by logging is usually an inefficient, and mostly ineffective method of debugging code.
 
I might be veering off topic too much here, but basically I'm trying to figure out a way to do a specific task for each different type of touch response (Different touch does different things).

Forgive me for straying off the path, but basically I wanted a button that runs something unique depending on the type of touch I'm giving it and I here trying to explore methods using gesture detector and I'm having no luck. I'm very much a noobie in multiple motionEvent Handling with Android.

Basically I just want a short touch (does something eg. run some method )), long touch (does something different, eg. run a different method), touching it and moving ( inside code does something like a drag and runs some other method). I'm having huge pains in working this out and its killing me.

Here's another previous code I am trying to work this out
Code:
package com.example.qwisatz.clickholddrag;

import android.content.ClipData;
import android.support.v4.view.GestureDetectorCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.DragEvent;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    Button bottomButton;
    TextView topText;
    TextView infoDisplay;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        bottomButton = (Button) findViewById(R.id.bottomButton);
        topText = (TextView) findViewById(R.id.topText);
        infoDisplay = (TextView) findViewById(R.id.infoDisplay);



        //SHORT TOUCH ON bottomButton   = SETTEXT OF infoDisplay "SHORT TOUCH"
        //LONG TOUCH/HOLD               = SETTEXT OF infoDisplay "LONG TOUCH"
        //DRAG bottomButton TO topText  = SETTEXT OF infoDisplay "DRAG"

        //SHORT CLICK FOR BUTTON
        bottomButton.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                infoDisplay.setText("THIS IS A SHORT CLICK");
                Log.i("myError","SHORT");
            }
        });

        //LONG CLICK FOR BUTTON
        bottomButton.setOnLongClickListener(new View.OnLongClickListener() {
            public boolean onLongClick(View v) {
                infoDisplay.setText("THIS IS A LONG CLICK");
                Log.i("myError","LONG");
                return true;
            }
        });

        //DRAG LISTENER
        topText.setOnDragListener(new View.OnDragListener() {
            @Override
            public boolean onDrag(View v, DragEvent event) {
                // TODO Auto-generated method stub
                final int action = event.getAction();
                switch (action) {
                    case DragEvent.ACTION_DRAG_STARTED:
                        // Executed after startDrag() is called.
                        break;
                    case DragEvent.ACTION_DRAG_EXITED:
                        break;
                    case DragEvent.ACTION_DRAG_ENTERED:
                        // Executed after the Drag Shadow enters the drop area
                        break;
                    case DragEvent.ACTION_DROP: {
                        infoDisplay.setText("DRAGGED WORKED");
                        Log.i("myError","DRAGGED");
                    }

                    //WHERE CODE GOES   //ACTION WHEN THING IS DROPPED/ENDED
                    case DragEvent.ACTION_DRAG_ENDED: {
                        return (true);
                    }
                    default:
                        break;
                }
                return true;
            }
        });


        bottomButton.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent arg1) {
                ClipData data = ClipData.newPlainText("", "");
                //CREATES AFTER SHADOWY AFTERIMAGE OF BUTTON
                View.DragShadowBuilder shadow = new View.DragShadowBuilder(bottomButton);
                v.startDrag(data, shadow, null, 0);
                Log.i("myError", "drag bottomButton Listener");
                return false;
            }
        });

    }

}

XML
Code:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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="match_parent"
    tools:context="com.example.qwisatz.clickholddrag.MainActivity">

    <TextView
        android:id="@+id/topText"
        android:layout_width="wrap_content"
        android:layout_height="0dp"
        android:layout_marginBottom="414dp"
        android:layout_marginEnd="163dp"
        android:layout_marginStart="163dp"
        android:layout_marginTop="78dp"
        android:text="topText"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <Button
        android:id="@+id/bottomButton"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="105dp"
        android:layout_marginEnd="123dp"
        android:layout_marginStart="124dp"
        android:layout_marginTop="261dp"
        android:text="bottomButton"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/topText" />

    <TextView
        android:id="@+id/infoDisplay"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="infoDisplay"
        tools:layout_editor_absoluteX="163dp"
        tools:layout_editor_absoluteY="16dp" />

</android.support.constraint.ConstraintLayout>

If I comment out bottomButton.setOnTouchListener(new View.OnTouchListener() the short click and long click works. But if I try to put in a dragging code, the only thing it can detect is the drag touch listener. Is there any way that I could solve this button. I'm a huge noob and this question of multiple different type of touches to run different things is slowly killing me from the inside.
 
Back
Top Bottom