如何在Android中检测左侧或右侧的滑动?

我在android中有一个edittext视图。 在这个我想要检测一个左右滑动。 我可以用下面的代码把它放在空白处。 但是,当我在edittext上滑动时,这不起作用。 我该怎么做? 请让我知道如果我做错了什么。 谢谢。

使用的代码

switch (touchevent.getAction()) { case MotionEvent.ACTION_DOWN: { oldTouchValue = touchevent.getX(); break; } case MotionEvent.ACTION_UP: { float currentX = touchevent.getX(); if (oldTouchValue < currentX) { // swiped left } if (oldTouchValue > currentX ) { swiped right } break; } } 

最简单的从左到右滑动检测器:

在你的活动课添加下列属性:

 private float x1,x2; static final int MIN_DISTANCE = 150; 

并重写onTouchEvent()方法:

 @Override public boolean onTouchEvent(MotionEvent event) { switch(event.getAction()) { case MotionEvent.ACTION_DOWN: x1 = event.getX(); break; case MotionEvent.ACTION_UP: x2 = event.getX(); float deltaX = x2 - x1; if (Math.abs(deltaX) > MIN_DISTANCE) { Toast.makeText(this, "left2right swipe", Toast.LENGTH_SHORT).show (); } else { // consider as something else - a screen tap for example } break; } return super.onTouchEvent(event); } 

我喜欢@ user2999943的代码。 但是为了我自己的目的只是一些小的改变。

 @Override public boolean onTouchEvent(MotionEvent event) { switch(event.getAction()) { case MotionEvent.ACTION_DOWN: x1 = event.getX(); break; case MotionEvent.ACTION_UP: x2 = event.getX(); float deltaX = x2 - x1; if (Math.abs(deltaX) > MIN_DISTANCE) { // Left to Right swipe action if (x2 > x1) { Toast.makeText(this, "Left to Right swipe [Next]", Toast.LENGTH_SHORT).show (); } // Right to left swipe action else { Toast.makeText(this, "Right to Left swipe [Previous]", Toast.LENGTH_SHORT).show (); } } else { // consider as something else - a screen tap for example } break; } return super.onTouchEvent(event); } 

这是我使用的一个可爱的类(在我想要捕获事件的情况下,如果它是一个ViewGroup,我使用第二个实现):

 import android.util.Log; import android.view.MotionEvent; import android.view.View; public class SwipeDetector implements View.OnTouchListener{ private int min_distance = 100; private float downX, downY, upX, upY; private View v; private onSwipeEvent swipeEventListener; public SwipeDetector(View v){ this.v=v; v.setOnTouchListener(this); } public void setOnSwipeListener(onSwipeEvent listener) { try{ swipeEventListener=listener; } catch(ClassCastException e) { Log.e("ClassCastException","please pass SwipeDetector.onSwipeEvent Interface instance",e); } } public void onRightToLeftSwipe(){ if(swipeEventListener!=null) swipeEventListener.SwipeEventDetected(v,SwipeTypeEnum.RIGHT_TO_LEFT); else Log.e("SwipeDetector error","please pass SwipeDetector.onSwipeEvent Interface instance"); } public void onLeftToRightSwipe(){ if(swipeEventListener!=null) swipeEventListener.SwipeEventDetected(v,SwipeTypeEnum.LEFT_TO_RIGHT); else Log.e("SwipeDetector error","please pass SwipeDetector.onSwipeEvent Interface instance"); } public void onTopToBottomSwipe(){ if(swipeEventListener!=null) swipeEventListener.SwipeEventDetected(v,SwipeTypeEnum.TOP_TO_BOTTOM); else Log.e("SwipeDetector error","please pass SwipeDetector.onSwipeEvent Interface instance"); } public void onBottomToTopSwipe(){ if(swipeEventListener!=null) swipeEventListener.SwipeEventDetected(v,SwipeTypeEnum.BOTTOM_TO_TOP); else Log.e("SwipeDetector error","please pass SwipeDetector.onSwipeEvent Interface instance"); } public boolean onTouch(View v, MotionEvent event) { switch(event.getAction()){ case MotionEvent.ACTION_DOWN: { downX = event.getX(); downY = event.getY(); return true; } case MotionEvent.ACTION_UP: { upX = event.getX(); upY = event.getY(); float deltaX = downX - upX; float deltaY = downY - upY; //HORIZONTAL SCROLL if(Math.abs(deltaX) > Math.abs(deltaY)) { if(Math.abs(deltaX) > min_distance){ // left or right if(deltaX < 0) { this.onLeftToRightSwipe(); return true; } if(deltaX > 0) { this.onRightToLeftSwipe(); return true; } } else { //not long enough swipe... return false; } } //VERTICAL SCROLL else { if(Math.abs(deltaY) > min_distance){ // top or down if(deltaY < 0) { this.onTopToBottomSwipe(); return true; } if(deltaY > 0) { this.onBottomToTopSwipe(); return true; } } else { //not long enough swipe... return false; } } return true; } } return false; } public interface onSwipeEvent { public void SwipeEventDetected(View v, SwipeTypeEnum SwipeType); } public SwipeDetector setMinDistanceInPixels(int min_distance) { this.min_distance=min_distance; return this; } public enum SwipeTypeEnum { RIGHT_TO_LEFT,LEFT_TO_RIGHT,TOP_TO_BOTTOM,BOTTOM_TO_TOP } } 

这是一个使用的例子:

 filters_container=(RelativeLayout)root.findViewById(R.id.filters_container); new SwipeDetector(filters_container).setOnSwipeListener(new SwipeDetector.onSwipeEvent() { @Override public void SwipeEventDetected(View v, SwipeDetector.SwipeTypeEnum swipeType) { if(swipeType==SwipeDetector.SwipeTypeEnum.LEFT_TO_RIGHT) getActivity().onBackPressed(); } }); 

在某些情况下,您希望检测容器上的轻扫手势,并将触摸事件传递给子项,以便在这种情况下,您可以创build一个自定义视图组,让其说出RelativeLayout并覆盖onInterceptTouchEvent,然后您就可以检测到轻扫事件而不会阻止Touch Event传递给您的子视图,例如:

  import android.content.Context; import android.util.AttributeSet; import android.view.MotionEvent; import android.widget.RelativeLayout; public class SwipeDetectRelativeLayout extends RelativeLayout { private float x1,x2; static final int MIN_DISTANCE=150; private onSwipeEventDetected mSwipeDetectedListener; public SwipeDetectRelativeLayout(Context context) { super(context); } public SwipeDetectRelativeLayout(Context context, AttributeSet attrs) { super(context, attrs); } public SwipeDetectRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { switch(ev.getAction()) { case MotionEvent.ACTION_DOWN: x1 = ev.getX(); break; case MotionEvent.ACTION_UP: x2 = ev.getX(); float deltaX = x2 - x1; if (Math.abs(deltaX) > MIN_DISTANCE) { //swiping right to left if(deltaX<0) { if(mSwipeDetectedListener!=null) mSwipeDetectedListener.swipeEventDetected(); } } break; } return super.onInterceptTouchEvent(ev); } public interface onSwipeEventDetected { public void swipeEventDetected(); } public void registerToSwipeEvents(onSwipeEventDetected listener) { this.mSwipeDetectedListener=listener; } } 

滑动事件是一种onTouch事件。 简单地简化@Gal Rom的答案,只需跟踪垂直的水平三angular形,用一个小math就可以确定touchEvent是什么types的滑动。 (再次,让我强调,这是基于以前的答案,但简单可能吸引新手)。 这个想法是扩展一个OnTouchListener,检测刚刚发生了什么样的刷卡(touch),并为每种types调用特定的方法。

 public class SwipeListener implements View.OnTouchListener { private int min_distance = 100; private float downX, downY, upX, upY; View v; @Override public boolean onTouch(View v, MotionEvent event) { this.v = v; switch(event.getAction()) { // Check vertical and horizontal touches case MotionEvent.ACTION_DOWN: { downX = event.getX(); downY = event.getY(); return true; } case MotionEvent.ACTION_UP: { upX = event.getX(); upY = event.getY(); float deltaX = downX - upX; float deltaY = downY - upY; //HORIZONTAL SCROLL if (Math.abs(deltaX) > Math.abs(deltaY)) { if (Math.abs(deltaX) > min_distance) { // left or right if (deltaX < 0) { this.onLeftToRightSwipe(); return true; } if (deltaX > 0) { this.onRightToLeftSwipe(); return true; } } else { //not long enough swipe... return false; } } //VERTICAL SCROLL else { if (Math.abs(deltaY) > min_distance) { // top or down if (deltaY < 0) { this.onTopToBottomSwipe(); return true; } if (deltaY > 0) { this.onBottomToTopSwipe(); return true; } } else { //not long enough swipe... return false; } } return false; } } return false; } public void onLeftToRightSwipe(){ Toast.makeText(v.getContext(),"left to right", Toast.LENGTH_SHORT).show(); } public void onRightToLeftSwipe() { Toast.makeText(v.getContext(),"right to left", Toast.LENGTH_SHORT).show(); } public void onTopToBottomSwipe() { Toast.makeText(v.getContext(),"top to bottom", Toast.LENGTH_SHORT).show(); } public void onBottomToTopSwipe() { Toast.makeText(v.getContext(),"bottom to top", Toast.LENGTH_SHORT).show(); } } 

我写了一个简单的类,可以很容易地检测到滑动事件 – TOP,RIGHT,BOTTOM,LEFT。

1:检测单个滑动事件

 // Detect and consume specific events // {Available methods} - detectTop, detectRight, detectBottom, detectLeft SwipeEvents.detectTop(swipeElement, new SwipeEvents.SwipeSingleCallback() { @Override public void onSwipe() { showToast("Swiped - detectTop"); } }); 

2:用一个callback检测任何滑动事件。

 SwipeEvents.detect( swipeElement, new SwipeEvents.SwipeCallback() { @Override public void onSwipeTop() { //Swiped top } @Override public void onSwipeRight() { //Swiped right } @Override public void onSwipeBottom() { //Swiped bottom } @Override public void onSwipeLeft() { //Swiped left } }); 

这里是一个博客文章,解释如何使用: http : //bmutinda.com/android-detect-swipe-events/

我也为这里的代码片断创build了一个Gist: https : //gist.github.com/bmutinda/9578f70f1df9bd0687b8

谢谢。

从左到右和从右到左滑动检测器

首先声明float数据types的两个variables。

 private float x1, x2; 

其次,在java中连接你的xml视图。 就像我有ImageView

 ImageView img = (ImageView) findViewById(R.id.imageView); 

第三,你的ImageView上的setOnTouchListener

 img.setOnTouchListener( new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { // TODO Auto-generated method stub switch (event.getAction()) { case MotionEvent.ACTION_DOWN: x1 = event.getX(); break; case MotionEvent.ACTION_UP: x2 = event.getX(); float deltaX = x2 - x1; if (deltaX < 0) { Toast.makeText(MainActivity.this, "Right to Left swipe", Toast.LENGTH_SHORT).show(); }else if(deltaX >0){ Toast.makeText(MainActivity.this, "Left to Right swipe", Toast.LENGTH_SHORT).show(); } break; } return false; } }); 

我想添加到部分工作的接受答案,但缺less时间variables,这使得它完美。

最简单的从左到右滑动检测器,具有时间variables:

在你的活动课添加下列属性:

 private float x1,x2; private long startClickTime; static final int MIN_DISTANCE = 150; static final int MAX_SWIPE_TIME = 200; 

并重写onTouchEvent()方法:

  @Override public boolean onTouchEvent(MotionEvent event) { switch(event.getAction()) { case MotionEvent.ACTION_DOWN: startClickTime = Calendar.getInstance().getTimeInMillis(); x1 = event.getX(); break; case MotionEvent.ACTION_UP: long clickDuration = Calendar.getInstance().getTimeInMillis() - startClickTime; x2 = event.getX(); float deltaX = x2 - x1; if (Math.abs(deltaX) > MIN_DISTANCE && clickDuration < MAX_SWIPE_TIME) { Toast.makeText(this, "left2right swipe", Toast.LENGTH_SHORT).show (); } else { // consider as something else - a screen tap for example } break; } return super.onTouchEvent(event); } 

检测四个方向的滑动

 private float x1,x2,y1,y2; static final int MIN_DISTANCE = 70; 

 switch(pSceneTouchEvent.getAction()) { case MotionEvent.ACTION_DOWN: x1 = pSceneTouchEvent.getX(); y1 = pSceneTouchEvent.getY(); break; case MotionEvent.ACTION_UP: x2 = pSceneTouchEvent.getX(); y2 = pSceneTouchEvent.getY(); float deltaX = x2 - x1; float deltaY = y2 - y1; if (deltaX > MIN_DISTANCE) { swipeLeftToRight(); } else if( Math.abs(deltaX) > MIN_DISTANCE) { swipeRightToLeft(); } else if(deltaY > MIN_DISTANCE){ swipeTopToBottom(); } else if( Math.abs(deltaY) > MIN_DISTANCE){ swipeBottopmToTop(); } break; } 

我想你想要的就是所谓的一举一动。 MotionEvents可以用来确定投掷的方向。

 public class MainActivity extends Activity implements GestureDetector.OnGestureListener { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.stellar_layout); mDetector = new GestureDetectorCompat(this, this); } @Override public boolean onFling(MotionEvent event1, MotionEvent event2, float velocityX, float velocityY) { Log.d(tag, "onFling:\n " + event1.toString()+ "\n " + event2.toString()); /* prints the following MotionEvent { action=ACTION_DOWN, id[0]=0, x[0]=297.0, y[0]=672.0, toolType[0]=TOOL_TYPE_FINGER, buttonState=0, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=0, eventTime=488341979, downTime=488341979, deviceId=6, source=0x1002 } MotionEvent { action=ACTION_UP, id[0]=0, x[0]=560.0, y[0]=583.0, toolType[0]=TOOL_TYPE_FINGER, buttonState=0, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=0, eventTime=488342047, downTime=488341979, deviceId=6, source=0x1002 } */ return true; } } 

http://developer.android.com/training/gestures/detector.html

 public class TransferMarket extends Activity { float x1,x2; float y1, y2; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_transfer_market); } // onTouchEvent () method gets called when User performs any touch event on screen // Method to handle touch event like left to right swap and right to left swap public boolean onTouchEvent(MotionEvent touchevent) { switch (touchevent.getAction()) { // when user first touches the screen we get x and y coordinate case MotionEvent.ACTION_DOWN: { x1 = touchevent.getX(); y1 = touchevent.getY(); break; } case MotionEvent.ACTION_UP: { x2 = touchevent.getX(); y2 = touchevent.getY(); //if left to right sweep event on screen if (x1 < x2) { Toast.makeText(this, "Left to Right Swap Performed", Toast.LENGTH_LONG).show(); } // if right to left sweep event on screen if (x1 > x2) { Toast.makeText(this, "Right to Left Swap Performed", Toast.LENGTH_LONG).show(); } // if UP to Down sweep event on screen if (y1 < y2) { Toast.makeText(this, "UP to Down Swap Performed", Toast.LENGTH_LONG).show(); } //if Down to UP sweep event on screen if (y1 > y2) { Toast.makeText(this, "Down to UP Swap Performed", Toast.LENGTH_LONG).show(); } break; } } return false; } 

最好的答案是@加尔罗姆的。 有更多关于它的信息:先触摸事件返回到子视图。 如果为它们定义onClick或onTouch侦听器,parnt视图(例如fragment)将不会收到任何触摸侦听器。 所以如果你想在这种情况下为片段定义滑动监听器,你必须在一个新的类中实现它:

  package com.neganet.QRelations.fragments; import android.content.Context; import android.util.AttributeSet; import android.view.MotionEvent; import android.widget.FrameLayout; public class SwipeListenerFragment extends FrameLayout { private float x1,x2; static final int MIN_DISTANCE=150; private onSwipeEventDetected mSwipeDetectedListener; public SwipeListenerFragment(Context context) { super(context); } public SwipeListenerFragment(Context context, AttributeSet attrs) { super(context, attrs); } public SwipeListenerFragment(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } @Override public boolean onInterceptTouchEvent(MotionEvent ev) { boolean result=false; switch(ev.getAction()) { case MotionEvent.ACTION_DOWN: x1 = ev.getX(); break; case MotionEvent.ACTION_UP: x2 = ev.getX(); float deltaX = x2 - x1; if (Math.abs(deltaX) > MIN_DISTANCE) { if(deltaX<0) { result=true; if(mSwipeDetectedListener!=null) mSwipeDetectedListener.swipeLeftDetected(); }else if(deltaX>0){ result=true; if(mSwipeDetectedListener!=null) mSwipeDetectedListener.swipeRightDetected(); } } break; } return result; } public interface onSwipeEventDetected { public void swipeLeftDetected(); public void swipeRightDetected(); } public void registerToSwipeEvents(onSwipeEventDetected listener) { this.mSwipeDetectedListener=listener; } } 

我改了@Gal Rom的class。 所以它可以检测到左右滑动,特别是检测后返回onInterceptTouchEvent true。 它的重要,因为如果我们不这样做有时候子视图可能会收到事件和滑动片段和onClick子视图(例如)运行,并导致一些问题。 做这个类后,你必须改变你的片段xml文件:

  <com.neganet.QRelations.fragments.SwipeListenerFragment xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:id="@+id/main_list_layout" android:clickable="true" android:focusable="true" android:focusableInTouchMode="true" android:layout_height="match_parent" tools:context="com.neganet.QRelations.fragments.mainList" android:background="@color/main_frag_back"> <!-- TODO: Update blank fragment layout --> <android.support.v7.widget.RecyclerView android:id="@+id/farazList" android:scrollbars="horizontal" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="left|center_vertical" /> </com.neganet.QRelations.fragments.SwipeListenerFragment> 

你看到开始标记是我们所做的类。 现在在片段类中:

  View view=inflater.inflate(R.layout.fragment_main_list, container, false); SwipeListenerFragment tdView=(SwipeListenerFragment) view; tdView.registerToSwipeEvents(this); and then Implement SwipeListenerFragment.onSwipeEventDetected in it: @Override public void swipeLeftDetected() { Toast.makeText(getActivity(), "left", Toast.LENGTH_SHORT).show(); } @Override public void swipeRightDetected() { Toast.makeText(getActivity(), "right", Toast.LENGTH_SHORT).show(); } 

这有点复杂,但完美:)

如果要从滑动开始捕捉事件,可以使用MotionEvent.ACTION_MOVE并存储要比较的第一个值

 private float upX1; private float upX2; private float upY1; private float upY2; private boolean isTouchCaptured = false; static final int min_distance = 100; viewObject.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_MOVE: { downX = event.getX(); downY = event.getY(); if (!isTouchCaptured) { upX1 = event.getX(); upY1 = event.getY(); isTouchCaptured = true; } else { upX2 = event.getX(); upY2 = event.getY(); float deltaX = upX1 - upX2; float deltaY = upY1 - upY2; //HORIZONTAL SCROLL if (Math.abs(deltaX) > Math.abs(deltaY)) { if (Math.abs(deltaX) > min_distance) { // left or right if (deltaX < 0) { return true; } if (deltaX > 0) { return true; } } else { //not long enough swipe... return false; } } //VERTICAL SCROLL else { if (Math.abs(deltaY) > min_distance) { // top or down if (deltaY < 0) { return false; } if (deltaY > 0) { return false; } } else { //not long enough swipe... return false; } } } return false; } case MotionEvent.ACTION_UP: { isTouchCaptured = false; } } return false; } }); 

这应该可以帮助你也许…

 private final GestureDetector.SimpleOnGestureListener onGestureListener = new GestureDetector.SimpleOnGestureListener() { @Override public boolean onDoubleTap(MotionEvent e) { Log.i("gestureDebug333", "doubleTapped:" + e); return super.onDoubleTap(e); } @Override public boolean onDoubleTapEvent(MotionEvent e) { Log.i("gestureDebug333", "doubleTappedEvent:" + e); return super.onDoubleTapEvent(e); } @Override public boolean onDown(MotionEvent e) { Log.i("gestureDebug333", "onDown:" + e); return super.onDown(e); } @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { Log.i("gestureDebug333", "flinged:" + e1 + "---" + e2); Log.i("gestureDebug333", "fling velocity:" + velocityX + "---" + velocityY); if (e1.getAction() == MotionEvent.ACTION_DOWN && e1.getX() > (e2.getX() + 300)){ // Toast.makeText(context, "flinged right to left", Toast.LENGTH_SHORT).show(); goForward(); } if (e1.getAction() == MotionEvent.ACTION_DOWN && e2.getX() > (e1.getX() + 300)){ //Toast.makeText(context, "flinged left to right", Toast.LENGTH_SHORT).show(); goBack(); } return super.onFling(e1, e2, velocityX, velocityY); } @Override public void onLongPress(MotionEvent e) { super.onLongPress(e); } @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { return super.onScroll(e1, e2, distanceX, distanceY); } @Override public void onShowPress(MotionEvent e) { super.onShowPress(e); } @Override public boolean onSingleTapConfirmed(MotionEvent e) { return super.onSingleTapConfirmed(e); } @Override public boolean onSingleTapUp(MotionEvent e) { return super.onSingleTapUp(e); } }; 

经过整整一天的工作,这个function终于能够得到正确的答案。

首先,创build以下类:

 import android.util.Log; import android.view.MotionEvent; import android.view.View; /** * Created by hoshyar on 1/19/17. */ public class SwipeDetector implements View.OnTouchListener { public static enum Action { LR, // Left to Right RL, // Right to Left TB, // Top to bottom BT, // Bottom to Top None // when no action was detected } private static final String logTag = "Swipe"; private static final int MIN_DISTANCE = 100; private float downX, downY, upX, upY; private Action mSwipeDetected = Action.None; public boolean swipeDetected() { return mSwipeDetected != Action.None; } public Action getAction() { return mSwipeDetected; } @Override public boolean onTouch(View v, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: downX = event.getX(); downY = event.getY(); mSwipeDetected = Action.None; return false; case MotionEvent.ACTION_MOVE: upX = event.getX(); upY = event.getY(); float deltaX = downX - upX; float deltaY = downY - upY; Log.i(logTag,String.valueOf(deltaX)); Log.i(logTag,String.valueOf(deltaX)); if (deltaY>0 && deltaY<10 && deltaX<0 || deltaY==0 && deltaX>-15 && deltaX<0){ Log.i(logTag,"to right"); }if (deltaY>=0 && deltaY<10 && deltaX>0 || deltaY<0 && deltaX>15 && deltaX<40){ Log.i(logTag,"to left"); } if (Math.abs(deltaX) > MIN_DISTANCE) { // left or right if (deltaX < 0) { mSwipeDetected = Action.LR; return false; } if (deltaX > 0) { mSwipeDetected = Action.RL; return false; } } else if (Math.abs(deltaY) > MIN_DISTANCE) { if (deltaY < 0) { Log.i(logTag,"to bottom"); mSwipeDetected = Action.TB; return false; } if (deltaY > 0) { Log.i(logTag,"to up"); mSwipeDetected = Action.BT; return false; } } return true; } return false; } } 

最后在你想要应用的对象上。 我的例子:

 SwipeDetector swipeDetector = new SwipeDetector(); listView.setOnTouchListener(swipeDetector); 

祝你好运 。