2010-11-09 94 views
324

我希望我的应用能够识别用户在电话屏幕上从右向左滑动的时间。Android:如何处理从左到右的滑动手势

如何做到这一点?

+1

检查此链接http://stackoverflow.com/questions/937313/android-basic-gesture-: 只是在其内部OnGestureListener使用onFlingGestureDetector检测 – Falmarri 2010-11-09 22:23:39

+0

看到我的答案如何上/下/左/右轻扫手势 http://stackoverflow.com/questions/13095494/how-to-detect-swipe-direction-between-left-right-and -up向下/ 26387629#2638 7629 – fernandohur 2015-06-30 23:01:10

+0

检查我的库可能有所帮助https://github.com/UdiOshi85/libSwipes – 2017-04-02 07:39:35

回答

645

OnSwipeTouchListener.java

import android.content.Context; 
import android.view.GestureDetector; 
import android.view.GestureDetector.SimpleOnGestureListener; 
import android.view.MotionEvent; 
import android.view.View; 
import android.view.View.OnTouchListener; 

public class OnSwipeTouchListener implements OnTouchListener { 

    private final GestureDetector gestureDetector; 

    public OnSwipeTouchListener (Context ctx){ 
     gestureDetector = new GestureDetector(ctx, new GestureListener()); 
    } 

    @Override 
    public boolean onTouch(View v, MotionEvent event) { 
     return gestureDetector.onTouchEvent(event); 
    } 

    private final class GestureListener extends SimpleOnGestureListener { 

     private static final int SWIPE_THRESHOLD = 100; 
     private static final int SWIPE_VELOCITY_THRESHOLD = 100; 

     @Override 
     public boolean onDown(MotionEvent e) { 
      return true; 
     } 

     @Override 
     public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { 
      boolean result = false; 
      try { 
       float diffY = e2.getY() - e1.getY(); 
       float diffX = e2.getX() - e1.getX(); 
       if (Math.abs(diffX) > Math.abs(diffY)) { 
        if (Math.abs(diffX) > SWIPE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) { 
         if (diffX > 0) { 
          onSwipeRight(); 
         } else { 
          onSwipeLeft(); 
         } 
         result = true; 
        } 
       } 
       else if (Math.abs(diffY) > SWIPE_THRESHOLD && Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD) { 
        if (diffY > 0) { 
         onSwipeBottom(); 
        } else { 
         onSwipeTop(); 
        } 
        result = true; 
       } 
      } catch (Exception exception) { 
       exception.printStackTrace(); 
      } 
      return result; 
     } 
    } 

    public void onSwipeRight() { 
    } 

    public void onSwipeLeft() { 
    } 

    public void onSwipeTop() { 
    } 

    public void onSwipeBottom() { 
    } 
} 

用法:

imageView.setOnTouchListener(new OnSwipeTouchListener(MyActivity.this) { 
    public void onSwipeTop() { 
     Toast.makeText(MyActivity.this, "top", Toast.LENGTH_SHORT).show(); 
    } 
    public void onSwipeRight() { 
     Toast.makeText(MyActivity.this, "right", Toast.LENGTH_SHORT).show(); 
    } 
    public void onSwipeLeft() { 
     Toast.makeText(MyActivity.this, "left", Toast.LENGTH_SHORT).show(); 
    } 
    public void onSwipeBottom() { 
     Toast.makeText(MyActivity.this, "bottom", Toast.LENGTH_SHORT).show(); 
    } 

}); 
+6

很好用,但是super.onTouch(view,motionEvent);在eclipse中给我错误警告“未定义类型对象”。删除这个工程很好。 – Opiatefuchs 2013-06-22 17:47:47

+19

感谢的作品像一个魅力,但你应该添加一个构造函数到'OnSwipeTouchListener'接收一个上下文,因为'GestureDetector'的构造函数从API级别3被弃用,并在该构造函数中实例化'GestureDetector'。 – 2013-10-01 09:56:20

+0

这是主要活动吗?然后列表本身如何加载?我的主要扩展列表活动? – Manny265 2013-10-21 14:29:25

3

需要一些小的更新。变量在onTouch方法中不匹配,并且不导入异常类。从onFling()返回false会更有意义,而不是启动一个变量,给它赋值,不做任何事情,只是返回它。

onTouch方法的某些部分不正确。请参阅view/motionEvent cannot be resolved to a variable swipe

一个有用的技巧可以节省一些时间,我希望可以帮助其他人:当您使用此方法时,您只需将“implements”标记添加到OnSwipeTouchListener类。你的活动和视图没有实现它。他们只是利用你已经做过的班级!

+1米雷克因为他的代码还是给了我什么,我需要为我:)

44

如果您还需要处理,请点击事件的一些修改:

public class OnSwipeTouchListener implements OnTouchListener { 

    private final GestureDetector gestureDetector = new GestureDetector(new GestureListener()); 

    public boolean onTouch(final View v, final MotionEvent event) { 
     return gestureDetector.onTouchEvent(event); 
    } 

    private final class GestureListener extends SimpleOnGestureListener { 

     private static final int SWIPE_THRESHOLD = 100; 
     private static final int SWIPE_VELOCITY_THRESHOLD = 100; 


     @Override 
     public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { 
      boolean result = false; 
      try { 
       float diffY = e2.getY() - e1.getY(); 
       float diffX = e2.getX() - e1.getX(); 
       if (Math.abs(diffX) > Math.abs(diffY)) { 
        if (Math.abs(diffX) > SWIPE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) { 
         if (diffX > 0) { 
          result = onSwipeRight(); 
         } else { 
          result = onSwipeLeft(); 
         } 
        } 
       } else { 
        if (Math.abs(diffY) > SWIPE_THRESHOLD && Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD) { 
         if (diffY > 0) { 
          result = onSwipeBottom(); 
         } else { 
          result = onSwipeTop(); 
         } 
        } 
       } 
      } catch (Exception exception) { 
       exception.printStackTrace(); 
      } 
      return result; 
     } 
    } 

    public boolean onSwipeRight() { 
     return false; 
    } 

    public boolean onSwipeLeft() { 
     return false; 
    } 

    public boolean onSwipeTop() { 
     return false; 
    } 

    public boolean onSwipeBottom() { 
     return false; 
    } 
} 

而且样品用量:

background.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View arg0) { 
      toggleSomething(); 
     } 
    }); 
    background.setOnTouchListener(new OnSwipeTouchListener() { 
     public boolean onSwipeTop() { 
      Toast.makeText(MainActivity.this, "top", Toast.LENGTH_SHORT).show(); 
      return true; 
     } 
     public boolean onSwipeRight() { 
      Toast.makeText(MainActivity.this, "right", Toast.LENGTH_SHORT).show(); 
      return true; 
     } 
     public boolean onSwipeLeft() { 
      Toast.makeText(MainActivity.this, "left", Toast.LENGTH_SHORT).show(); 
      return true; 
     } 
     public boolean onSwipeBottom() { 
      Toast.makeText(MainActivity.this, "bottom", Toast.LENGTH_SHORT).show(); 
      return true; 
     } 
    }); 
+3

我在修改后的OnSwipeTouchListener中看不到修改。它到底在哪里? – 2013-10-23 20:48:56

+3

这应该是被接受的答案......差异很微妙但非常重要。首先,没有onDown()。其次,处理程序返回一个布尔值来表示他们是否使用该事件。如果你需要比同一个视图更多的处理器(这应该是默认情况下),这是非常重要的。 – 2014-11-07 23:24:13

+0

什么是toggleSomething()方法? – tung 2015-02-01 08:57:07

0

最后实现了一套只适用于这样的:

 @Override 
     public boolean onDown(MotionEvent e) { 
      return true; 
     } 
+0

它确实如果你阅读由ruX上面的答案) – 2014-05-22 06:11:27

+3

然后,它应该是对该答案的评论 - 否则,随着其他答案被添加,我们不知道你指的是哪一个。答案应该是完整的。如果其他答案不完整,则可以通过评论对其进行改进。 – 2014-05-22 22:04:17

0
public class TranslatorSwipeTouch implements OnTouchListener 
{ 
    private String TAG="TranslatorSwipeTouch"; 

    @SuppressWarnings("deprecation") 
    private GestureDetector detector=new GestureDetector(new TranslatorGestureListener()); 

    @Override 
    public boolean onTouch(View view, MotionEvent event) 
    { 
    return detector.onTouchEvent(event); 
    } 

private class TranslatorGestureListener extends SimpleOnGestureListener 
{ 
    private final int GESTURE_THRESHOULD=100; 
    private final int GESTURE_VELOCITY_THRESHOULD=100; 

    @Override 
    public boolean onDown(MotionEvent e) { 
     return true; 
    } 

    @Override 
    public boolean onFling(MotionEvent event1,MotionEvent event2,float velocityx,float velocityy) 
    { 
     try 
     { 
      float diffx=event2.getX()-event1.getX(); 
      float diffy=event2.getY()-event1.getY(); 

      if(Math.abs(diffx)>Math.abs(diffy)) 
      { 
       if(Math.abs(diffx)>GESTURE_THRESHOULD && Math.abs(velocityx)>GESTURE_VELOCITY_THRESHOULD) 
       { 
        if(diffx>0) 
        { 
         onSwipeRight(); 
        } 
        else 
        { 
         onSwipeLeft(); 
        } 
       } 
      } 
      else 
      { 
       if(Math.abs(diffy)>GESTURE_THRESHOULD && Math.abs(velocityy)>GESTURE_VELOCITY_THRESHOULD) 
       { 
        if(diffy>0) 
        { 
         onSwipeBottom(); 
        } 
        else 
        { 
         onSwipeTop(); 
        } 
       } 
      } 
     } 
     catch(Exception e) 
     { 
      Log.d(TAG, ""+e.getMessage()); 
     } 
     return false;   
    } 

    public void onSwipeRight() 
    { 
     //Toast.makeText(this.getClass().get, "swipe right", Toast.LENGTH_SHORT).show(); 
     Log.i(TAG, "Right"); 
    } 
    public void onSwipeLeft() 
    { 
     Log.i(TAG, "Left"); 
     //Toast.makeText(MyActivity.this, "swipe left", Toast.LENGTH_SHORT).show(); 
    } 

    public void onSwipeTop() 
    { 
     Log.i(TAG, "Top"); 
     //Toast.makeText(MyActivity.this, "swipe top", Toast.LENGTH_SHORT).show(); 
    } 

    public void onSwipeBottom() 
    { 
     Log.i(TAG, "Bottom"); 
     //Toast.makeText(MyActivity.this, "swipe bottom", Toast.LENGTH_SHORT).show(); 
    } 

    } 

} 
167

此代码检测左右滑动,避免不推荐使用的API调用,并对早期答案进行了其他改进。

/** 
* Detects left and right swipes across a view. 
*/ 
public class OnSwipeTouchListener implements OnTouchListener { 

    private final GestureDetector gestureDetector; 

    public OnSwipeTouchListener(Context context) { 
     gestureDetector = new GestureDetector(context, new GestureListener()); 
    } 

    public void onSwipeLeft() { 
    } 

    public void onSwipeRight() { 
    } 

    public boolean onTouch(View v, MotionEvent event) { 
     return gestureDetector.onTouchEvent(event); 
    } 

    private final class GestureListener extends SimpleOnGestureListener { 

     private static final int SWIPE_DISTANCE_THRESHOLD = 100; 
     private static final int SWIPE_VELOCITY_THRESHOLD = 100; 

     @Override 
     public boolean onDown(MotionEvent e) { 
      return true; 
     } 

     @Override 
     public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { 
      float distanceX = e2.getX() - e1.getX(); 
      float distanceY = e2.getY() - e1.getY(); 
      if (Math.abs(distanceX) > Math.abs(distanceY) && Math.abs(distanceX) > SWIPE_DISTANCE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) { 
       if (distanceX > 0) 
        onSwipeRight(); 
       else 
        onSwipeLeft(); 
       return true; 
      } 
      return false; 
     } 
    } 
} 

使用方法如下:

view.setOnTouchListener(new OnSwipeTouchListener(context) { 
    @Override 
    public void onSwipeLeft() { 
     // Whatever 
    } 
}); 
+1

如何获得listview项目的触摸事件? – RicNjesh 2014-05-22 12:00:07

+0

'onDown()'不会被调用,所以我不能拦截e1'的'空值,并将它保持为空,所以刷卡永远不会奏效 – mangusta 2014-05-30 07:06:18

+0

对不起,如果这听起来很厚,但(A)在何处代码的第二块去? (view.setOn ...),(B)正在传递的“上下文”是什么?我很新,感谢任何帮助!在此先感谢 – Jona 2014-06-19 23:14:41

9

使用SwipeListView,让它处理手势检测为您服务。

Screenshot

+0

链接不起作用 - 找不到年龄。 – Singagirl 2016-09-06 04:09:23

+0

@DmitriyR感谢您指出死链接。根据repro的通知,我更新了来自同一开发人员的新位置。我不知道为什么GitHub的位置发生了变化。 – 2016-09-06 12:35:04

24

扩展在米雷克的回答,为的情况下,当你想使用滚动视图内的滑动手势。默认情况下,滚动视图的触摸监听器被禁用,因此滚动操作不会发生。为了解决这个问题,你需要重写ActivitydispatchTouchEvent方法,并在完成自己的侦听器后返回此方法的继承版本。

为了对Mirek的代码做一些修改: 我在OnSwipeTouchListener中为gestureDetector添加了一个吸气剂。

public GestureDetector getGestureDetector(){ 
    return gestureDetector; 
} 

在Activity中声明OnSwipeTouchListener作为类级字段。

OnSwipeTouchListener onSwipeTouchListener; 

修改相应的用途代码:

onSwipeTouchListener = new OnSwipeTouchListener(MyActivity.this) { 
    public void onSwipeTop() { 
     Toast.makeText(MyActivity.this, "top", Toast.LENGTH_SHORT).show(); 
    } 
    public void onSwipeRight() { 
     Toast.makeText(MyActivity.this, "right", Toast.LENGTH_SHORT).show(); 
    } 
    public void onSwipeLeft() { 
     Toast.makeText(MyActivity.this, "left", Toast.LENGTH_SHORT).show(); 
    } 
    public void onSwipeBottom() { 
     Toast.makeText(MyActivity.this, "bottom", Toast.LENGTH_SHORT).show(); 
    } 
}); 

imageView.setOnTouchListener(onSwipeTouchListener); 

,并覆盖内ActivitydispatchTouchEvent方法:

@Override 
    public boolean dispatchTouchEvent(MotionEvent ev){ 
     swipeListener.getGestureDetector().onTouchEvent(ev); 
      return super.dispatchTouchEvent(ev); 
    } 

现在无论是滚动和滑动操作应该工作。

8

要添加一个onClick,以下是我所做的。

.... 
// in OnSwipeTouchListener class 

private final class GestureListener extends SimpleOnGestureListener { 

    .... // normal GestureListener code 

    @Override 
    public boolean onSingleTapConfirmed(MotionEvent e) { 
     onClick(); // my method 
     return super.onSingleTapConfirmed(e); 
    } 

} // end GestureListener class 

    public void onSwipeRight() { 
    } 

    public void onSwipeLeft() { 
    } 

    public void onSwipeTop() { 
    } 

    public void onSwipeBottom() { 
    } 

    public void onClick(){ 
    } 


    // as normal 
    @Override 
    public boolean onTouch(View v, MotionEvent event) { 
     return gestureDetector.onTouchEvent(event); 
} 

} // end OnSwipeTouchListener class 

我使用的片段,因此使用getActivity()为背景。这就是我实现它的方式 - 而且很有效。


myLayout.setOnTouchListener(new OnSwipeTouchListener(getActivity()) { 
      public void onSwipeTop() { 
       Toast.makeText(getActivity(), "top", Toast.LENGTH_SHORT).show(); 
      } 
      public void onSwipeRight() { 
       Toast.makeText(getActivity(), "right", Toast.LENGTH_SHORT).show(); 
      } 
      public void onSwipeLeft() { 
       Toast.makeText(getActivity(), "left", Toast.LENGTH_SHORT).show(); 
      } 
      public void onSwipeBottom() { 
       Toast.makeText(getActivity(), "bottom", Toast.LENGTH_SHORT).show(); 
      } 

      public void onClick(){ 
       Toast.makeText(getActivity(), "clicked", Toast.LENGTH_SHORT).show(); 
      } 
     }); 
1

@Mirek鲁辛answeir是非常好的。 但是,有小bug,并修复被requried -

public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { 
      boolean result = false; 
      try { 
       float diffY = e2.getY() - e1.getY(); 
       float diffX = e2.getX() - e1.getX(); 
       if (Math.abs(diffX) > Math.abs(diffY)) { 
        if (Math.abs(diffX) > SWIPE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) { 
         if (diffX > 0) { 
          if (getOnSwipeListener() != null) { 
           getOnSwipeListener().onSwipeRight(); 
          } 
         } else { 
          if (getOnSwipeListener() != null) { 
           getOnSwipeListener().onSwipeLeft(); 
          } 
         } 
         result = true; 
        } 
       } 
       else if (Math.abs(diffY) > SWIPE_THRESHOLD && Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD) { 
        if (diffY > 0) { 
         if (getOnSwipeListener() != null) { 
          getOnSwipeListener().onSwipeBottom(); 
         } 
        } else { 
         if (getOnSwipeListener() != null) { 
          getOnSwipeListener().onSwipeTop(); 
         } 
        } 
        result = true; 
       } 

什么区别?只有当我们检查了所有的需求(SWIPE_THRESHOLD和SWIPE_VELOCITY_THRESHOLD都OK),我们才设置result = true。这是非常重要的,如果我们丢弃刷卡,如果一些requrinments没有实现,我们必须做onShipeTouchListener的onTouchEvent方法!

0

如果你想要显示一些按钮的动作,当一个列表项是刷卡是很多在互联网上有这种行为的库。 我实施了我在互联网上找到的图书馆,我非常满意。它使用起来非常简单,速度非常快。我改进了原始库,并为项目点击添加了新的点击侦听器。此外,我添加了字体真棒图书馆(http://fortawesome.github.io/Font-Awesome/),现在你可以简单地添加一个新的项目标题,并从字体真棒指定图标名称。

Here是GitHub的链接

17

为了有Click ListenerDoubleClick ListenerOnLongPress ListenerSwipe LeftSwipe RightSwipe UpSwipe Down上单View你需要setOnTouchListener。即,

view.setOnTouchListener(new OnSwipeTouchListener(MainActivity.this) { 

      @Override 
      public void onClick() { 
       super.onClick(); 
       // your on click here 
      } 

      @Override 
      public void onDoubleClick() { 
       super.onDoubleClick(); 
       // your on onDoubleClick here 
      } 

      @Override 
      public void onLongClick() { 
       super.onLongClick(); 
       // your on onLongClick here 
      } 

      @Override 
      public void onSwipeUp() { 
       super.onSwipeUp(); 
       // your swipe up here 
      } 

      @Override 
      public void onSwipeDown() { 
       super.onSwipeDown(); 
       // your swipe down here. 
      } 

      @Override 
      public void onSwipeLeft() { 
       super.onSwipeLeft(); 
       // your swipe left here. 
      } 

      @Override 
      public void onSwipeRight() { 
       super.onSwipeRight(); 
       // your swipe right here. 
      } 
     }); 

} 

为此,您需要OnSwipeTouchListener类实现OnTouchListener

public class OnSwipeTouchListener implements View.OnTouchListener { 

private GestureDetector gestureDetector; 

public OnSwipeTouchListener(Context c) { 
    gestureDetector = new GestureDetector(c, new GestureListener()); 
} 

public boolean onTouch(final View view, final MotionEvent motionEvent) { 
    return gestureDetector.onTouchEvent(motionEvent); 
} 

private final class GestureListener extends GestureDetector.SimpleOnGestureListener { 

    private static final int SWIPE_THRESHOLD = 100; 
    private static final int SWIPE_VELOCITY_THRESHOLD = 100; 

    @Override 
    public boolean onDown(MotionEvent e) { 
     return true; 
    } 

    @Override 
    public boolean onSingleTapUp(MotionEvent e) { 
     onClick(); 
     return super.onSingleTapUp(e); 
    } 

    @Override 
    public boolean onDoubleTap(MotionEvent e) { 
     onDoubleClick(); 
     return super.onDoubleTap(e); 
    } 

    @Override 
    public void onLongPress(MotionEvent e) { 
     onLongClick(); 
     super.onLongPress(e); 
    } 

    // Determines the fling velocity and then fires the appropriate swipe event accordingly 
    @Override 
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { 
     boolean result = false; 
     try { 
      float diffY = e2.getY() - e1.getY(); 
      float diffX = e2.getX() - e1.getX(); 
      if (Math.abs(diffX) > Math.abs(diffY)) { 
       if (Math.abs(diffX) > SWIPE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) { 
        if (diffX > 0) { 
         onSwipeRight(); 
        } else { 
         onSwipeLeft(); 
        } 
       } 
      } else { 
       if (Math.abs(diffY) > SWIPE_THRESHOLD && Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD) { 
        if (diffY > 0) { 
         onSwipeDown(); 
        } else { 
         onSwipeUp(); 
        } 
       } 
      } 
     } catch (Exception exception) { 
      exception.printStackTrace(); 
     } 
     return result; 
    } 
} 

public void onSwipeRight() { 
} 

public void onSwipeLeft() { 
} 

public void onSwipeUp() { 
} 

public void onSwipeDown() { 
} 

public void onClick() { 

} 

public void onDoubleClick() { 

} 

public void onLongClick() { 

} 
} 
+1

Zala的解决方案非常简单明了,在Android中通过滑动操作对我有很大帮助。此解决方案将解决无法使用滑动手势的初学者。 – user3264924 2015-09-02 15:34:54

+1

@Jaydipsinh Zala,你节省了我的时间,太棒了。这将解决我滚动时滚动顶部和底部指示器的问题。 – TejaDroid 2016-05-10 10:12:36

+0

最好的答案。谢谢 – neustart47 2016-09-06 16:32:54

5

@Edward Brey's method很好用。如果有人还想复制&粘贴进口的OnSwipeTouchListener,在这里,他们是:

import android.content.Context; 
import android.view.GestureDetector; 
import android.view.GestureDetector.SimpleOnGestureListener; 
import android.view.MotionEvent; 
import android.view.View; 
import android.view.View.OnTouchListener; 
1

下面是简单的Android代码检测手势方向

MainActivity.javaactivity_main.xml,写以下代码:

MainActivity.java

import java.util.ArrayList; 

import android.app.Activity; 
import android.gesture.Gesture; 
import android.gesture.GestureLibraries; 
import android.gesture.GestureLibrary; 
import android.gesture.GestureOverlayView; 
import android.gesture.GestureOverlayView.OnGesturePerformedListener; 
import android.gesture.GestureStroke; 
import android.gesture.Prediction; 
import android.os.Bundle; 
import android.widget.Toast; 

public class MainActivity extends Activity implements 
     OnGesturePerformedListener { 

    GestureOverlayView gesture; 
    GestureLibrary lib; 
    ArrayList<Prediction> prediction; 

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

     lib = GestureLibraries.fromRawResource(MainActivity.this, 
       R.id.gestureOverlayView1); 
     gesture = (GestureOverlayView) findViewById(R.id.gestureOverlayView1); 
     gesture.addOnGesturePerformedListener(this); 
    } 

    @Override 
    public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture) { 
     ArrayList<GestureStroke> strokeList = gesture.getStrokes(); 
     // prediction = lib.recognize(gesture); 
     float f[] = strokeList.get(0).points; 
     String str = ""; 

     if (f[0] < f[f.length - 2]) { 
      str = "Right gesture"; 
     } else if (f[0] > f[f.length - 2]) { 
      str = "Left gesture"; 
     } else { 
      str = "no direction"; 
     } 
     Toast.makeText(getApplicationContext(), str, Toast.LENGTH_LONG).show(); 

    } 

} 

activity_main.xml中

<android.gesture.GestureOverlayView xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:tools="http://schemas.android.com/tools" 
    xmlns:android1="http://schemas.android.com/apk/res/android" 
    xmlns:android2="http://schemas.android.com/apk/res/android" 
    android:id="@+id/gestureOverlayView1" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android1:orientation="vertical" > 

    <TextView 
     android:id="@+id/textView1" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:text="Draw gesture" 
     android:textAppearance="?android:attr/textAppearanceMedium" /> 

</android.gesture.GestureOverlayView> 
2

@Mirek鲁辛答案的小修改,现在你可以检测到多点触摸刷卡。此代码是科特林:

class OnSwipeTouchListener(ctx: Context, val onGesture: (gestureCode: Int) -> Unit) : OnTouchListener { 

private val SWIPE_THRESHOLD = 200 
private val SWIPE_VELOCITY_THRESHOLD = 200 

private val gestureDetector: GestureDetector 

var fingersCount = 0 

fun resetFingers() { 
    fingersCount = 0 
} 

init { 
    gestureDetector = GestureDetector(ctx, GestureListener()) 
} 

override fun onTouch(v: View, event: MotionEvent): Boolean { 
    if (event.pointerCount > fingersCount) { 
     fingersCount = event.pointerCount 
    } 
    return gestureDetector.onTouchEvent(event) 
} 

private inner class GestureListener : SimpleOnGestureListener() { 

    override fun onDown(e: MotionEvent): Boolean { 
     return true 
    } 

    override fun onFling(e1: MotionEvent, e2: MotionEvent, velocityX: Float, velocityY: Float): Boolean { 
     var result = false 
     try { 
      val diffY = e2.y - e1.y 
      val diffX = e2.x - e1.x 
      if (Math.abs(diffX) > Math.abs(diffY)) { 
       if (Math.abs(diffX) > SWIPE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) { 
        if (diffX > 0) { 
         val gesture = when (fingersCount) { 
          1 -> Gesture.SWIPE_RIGHT 
          2 -> Gesture.TWO_FINGER_SWIPE_RIGHT 
          3 -> Gesture.THREE_FINGER_SWIPE_RIGHT 
          else -> -1 
         } 
         if (gesture > 0) { 
          onGesture.invoke(gesture) 
         } 
        } else { 
         val gesture = when (fingersCount) { 
          1 -> Gesture.SWIPE_LEFT 
          2 -> Gesture.TWO_FINGER_SWIPE_LEFT 
          3 -> Gesture.THREE_FINGER_SWIPE_LEFT 
          else -> -1 
         } 
         if (gesture > 0) { 
          onGesture.invoke(gesture) 
         } 
        } 
        resetFingers() 
       } 
      } else if (Math.abs(diffY) > SWIPE_THRESHOLD && Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD) { 
       if (diffY > 0) { 
        val gesture = when (fingersCount) { 
         1 -> Gesture.SWIPE_DOWN 
         2 -> Gesture.TWO_FINGER_SWIPE_DOWN 
         3 -> Gesture.THREE_FINGER_SWIPE_DOWN 
         else -> -1 
        } 
        if (gesture > 0) { 
         onGesture.invoke(gesture) 
        } 
       } else { 
        val gesture = when (fingersCount) { 
         1 -> Gesture.SWIPE_UP 
         2 -> Gesture.TWO_FINGER_SWIPE_UP 
         3 -> Gesture.THREE_FINGER_SWIPE_UP 
         else -> -1 
        } 
        if (gesture > 0) { 
         onGesture.invoke(gesture) 
        } 
       } 
       resetFingers() 
      } 
      result = true 

     } catch (exception: Exception) { 
      exception.printStackTrace() 
     } 

     return result 
    } 
}} 

凡Gesture.SWIPE_RIGHT和其他人是我真的使用,以检测一种姿态后来在我的活动姿态的唯一的整数indentificator:

rootView?.setOnTouchListener(OnSwipeTouchListener(this, { 
    gesture -> log(Gesture.parseName(this, gesture)) 
})) 

所以你看这里的手势是一个整型变量,它保存了我之前通过的值。

+0

有人可以给我看一个如何使用Kotlin来检测左滑动和正常点击相同视图的例子。 – user3561494 2018-03-05 21:34:28

+0

你如何在列表视图中使用它?它不会返回被触摸的视图的位置,因此如何知道哪一行被触摸? – user3561494 2018-03-05 22:59:47

1

你不需要那些复杂的计算。

 @Override 
     public boolean onFling(final MotionEvent e1, final MotionEvent e2, final float velocityX, 
       final float velocityY) { 
      if ((velocityX * velocityX) > (velocityY * velocityY)) { 
       if (velocityX < 0) { 
        Log.i("TAG", "swipe left"); 
       } else { 
        Log.i("TAG", "swipe right"); 
       } 
      } else { 
       if (velocityY < 0) { 
        Log.i("TAG", "swipe up"); 
       } else { 
        Log.i("TAG", "swipe down"); 
       } 
      } 
      return false; 
     } 
+0

感谢它完全为我工作。永远不会产生任何空指针异常+1 – 2017-10-10 08:01:50

0

Edward Brey's answer在科特林

使用
view.setOnTouchListener(object: OnSwipeTouchListener(this) { 
     override fun onSwipeLeft() { 
     super.onSwipeLeft() 
     } 
     override fun onSwipeRight() { 
     super.onSwipeRight() 
     } 
    } 
)