2010-11-09 47 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() 
     } 
    } 
) 
相關問題