Swipeevent for Android app

Asked

Viewed 134 times

6

I’m making an application to control the SwipeView but is working only the validations from left to right and right to left. Validations up and down up are not working.

Could someone please help me?

I will share a code that makes all the validations and met all the expectations I wanted to do on app, including it also validates a double touch on the screen.

My new code (filtroGestos.java):

import android.app.Activity;
import android.view.GestureDetector;  
import android.view.GestureDetector.SimpleOnGestureListener;
import android.view.MotionEvent;

public class filtroGestos extends SimpleOnGestureListener {

public final static int SWIPE_CIMA    = 1;
public final static int SWIPE_BAIXO  = 2;
public final static int SWIPE_ESQUERDA  = 3;
public final static int SWIPE_DIREITA = 4;

public final static int MODE_TRANSPARENT = 0;
public final static int MODE_SOLID       = 1;
public final static int MODE_DYNAMIC     = 2;

private final static int ACTION_FAKE = -13; //um número improvável
private int swipe_Min_Distance = 100;
private int swipe_Max_Distance = 350;
private int swipe_Min_Velocity = 100;

private int mode             = MODE_DYNAMIC;
private boolean running      = true;
private boolean tapIndicator = false;

private Activity context;
private GestureDetector detector;
private SimpleGestureListener listener;

public filtroGestos(Activity context,SimpleGestureListener sgl) {

    this.context = context;
    this.detector = new GestureDetector(context, this);
    this.listener = sgl;
}

public void onTouchEvent(MotionEvent event){

    if(!this.running)
        return;

    boolean result = this.detector.onTouchEvent(event);

    if(this.mode == MODE_SOLID)
        event.setAction(MotionEvent.ACTION_CANCEL);
    else if (this.mode == MODE_DYNAMIC) {

        if(event.getAction() == ACTION_FAKE)
            event.setAction(MotionEvent.ACTION_UP);
        else if (result)
            event.setAction(MotionEvent.ACTION_CANCEL);
        else if(this.tapIndicator){
            event.setAction(MotionEvent.ACTION_DOWN);
            this.tapIndicator = false;
        }

    }
    //Senão não faça nada
}

public void setMode(int m){
    this.mode = m;
}

public int getMode(){
    return this.mode;
}

public void setEnabled(boolean status){
    this.running = status;
}

public void setSwipeMaxDistance(int distance){
    this.swipe_Max_Distance = distance;
}

public void setSwipeMinDistance(int distance){
    this.swipe_Min_Distance = distance;
}

public void setSwipeMinVelocity(int distance){
    this.swipe_Min_Velocity = distance;
}

public int getSwipeMaxDistance(){
    return this.swipe_Max_Distance;
}

public int getSwipeMinDistance(){
    return this.swipe_Min_Distance;
}

public int getSwipeMinVelocity(){
    return this.swipe_Min_Velocity;
}

@Override
public boolean onFling(MotionEvent event1, MotionEvent event2, float velocityX,
                       float velocityY) {

    final float xDistance = Math.abs(event1.getX() - event2.getX());
    final float yDistance = Math.abs(event1.getY() - event2.getY());

    if(xDistance > this.swipe_Max_Distance || yDistance > this.swipe_Max_Distance)
        return false;

    velocityX = Math.abs(velocityX);
    velocityY = Math.abs(velocityY);
    boolean result = false;

    if(velocityX > this.swipe_Min_Velocity && xDistance > this.swipe_Min_Distance){
        if(event1.getX() > event2.getX()) // esquerda para direita
            this.listener.onSwipe(SWIPE_ESQUERDA);
        else
            this.listener.onSwipe(SWIPE_DIREITA);

        result = true;
    }
    else if(velocityY > this.swipe_Min_Velocity && yDistance > this.swipe_Min_Distance){
        if(event1.getY() > event2.getY()) // baixo para cima
            this.listener.onSwipe(SWIPE_CIMA);
        else
            this.listener.onSwipe(SWIPE_BAIXO);

        result = true;
    }

    return result;
}

@Override
public boolean onSingleTapUp(MotionEvent e) {
    this.tapIndicator = true;
    return false;
}

@Override
public boolean onDoubleTap(MotionEvent arg) {
    this.listener.onDoubleTap();
    return true;
}

@Override
public boolean onDoubleTapEvent(MotionEvent arg) {
    return true;
}

@Override
public boolean onSingleTapConfirmed(MotionEvent arg) {

    if(this.mode == MODE_DYNAMIC){
        arg.setAction(ACTION_FAKE);
        this.context.dispatchTouchEvent(arg);
    }

    return false;
}

static interface SimpleGestureListener{
    void onSwipe(int direction);
    void onDoubleTap();
}
}

Swipescreen.java

import android.app.Activity;
import android.os.Bundle;
import android.view.MotionEvent;
import android.widget.Toast;

public class SwipeScreen extends Activity implements filtroGestos.SimpleGestureListener {
        private filtroGestos detect;
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // Detecta area tocada
    detect = new filtroGestos(this,this);
}

@Override
public boolean dispatchTouchEvent(MotionEvent motionEvent){
    // Chama o método onTouchEvent da classe filtroGestos
    this.detect.onTouchEvent(motionEvent);
    return super.dispatchTouchEvent(motionEvent);
}
@Override
public void onSwipe(int swipeDirection) {
    String str = "";

    switch (swipeDirection) {

        case filtroGestos.SWIPE_DIREITA : str = "Swipe Esquerda para Direita";
            break;
        case filtroGestos.SWIPE_ESQUERDA :  str = "Swipe Direita para Esquerda";
            break;
        case filtroGestos.SWIPE_BAIXO :  str = "Swipe Cima para Baixo";
            break;
        case filtroGestos.SWIPE_CIMA :    str = "Swipe Baixo para Cima";
            break;

    }
    Toast.makeText(this, str, Toast.LENGTH_SHORT).show();
}

@Override
public void onDoubleTap() {
    Toast.makeText(this, "Toque Duplo", Toast.LENGTH_SHORT).show();
}
}

Manifest.XML

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.lmontanhine.aulas_android_swipescreen" >

<application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >
    <activity
        android:name="com.example.lmontanhine.aulas_android_swipescreen.SwipeScreen"
        android:label="@string/app_name" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
  </application>
 </manifest>
  • I think it would be nice to consider the "delta" of the vertical and horizontal movement, that is, if there was a greater vertical movement than the horizontal one which should be considered? And if I move diagonally, what will be the result? Otherwise I see no problem in your code.

  • Instead of editing the question with the correct code put an answer with it and accept it.

  • @Thank you for warning. I will do it as soon as possible.

1 answer

0

Try to use GestureDetector for top and bottom movements, instead of SwipeEvent, example:

package com.exemplo.gesture;
import android.app.Activity;
import android.os.Bundle;
import android.view.GestureDetector;
import android.view.GestureDetector.OnGestureListener;
import android.view.MotionEvent;
import android.widget.ImageView;
public class Main extends Activity implements OnGestureListener {
        private GestureDetector movimento;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        movimento = new GestureDetector(this);
    }
}

And use Swipedemo in the layout:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >
    <TextView
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:text="Swipe Demo Exemplo"
        android:gravity="center"
        android:layout_margin="10dip" />
        <LinearLayout
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:orientation="vertical"
            android:gravity="center">
                 <ImageView
                     android:layout_width="wrap_content"
                     android:layout_height="wrap_content"
                     android:layout_gravity="center"
                     android:gravity="center"
                     android:layout_margin="10dip"
                     android:id="@+id/image_place_holder"/>
           </LinearLayout>
</LinearLayout>
  • Thanks for the help @Kauan Kubaski, but I didn’t understand the answer. I even tried to make these changes but the code returns error at several points. I have already created an XML with the literal "Swipe Detector" and below displays the actions through Toast, but as I said, the way I implemented the code, when I do the movement from left to right, for example, it shows: "Swipe left to right (OK) along with the message Swipe Up to Down (Not OK)"...here’s the problem...the validations are not being made correctly. Hugs.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.