Android: как обрабатывать жесты справа налево
Я хочу, чтобы мое приложение распознавало, когда пользователь проводит справа налево на экране телефона.
Как это сделать?
19 ответов:
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(); } });
этот код обнаруживает левый и правый свайпы, избегает устаревших вызовов 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 } });
Если Вам также нужно обработать события щелчка здесь некоторые изменения:
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; } });
расширение ответа Мирека, для случая, когда вы хотите использовать жесты прокрутки внутри прокрутки. По умолчанию прослушиватель касания для представления прокрутки отключается, и поэтому действие прокрутки не происходит. Чтобы исправить это, вам нужно переопределить
dispatchTouchEvent
методActivity
и вернуть унаследованная версия этого метода после того, как вы закончите с вашим собственным слушателем.для того, чтобы сделать несколько изменений в коде Мирека: Я добавляю геттер для
gestureDetector
in элементOnSwipeTouchListener
.public GestureDetector getGestureDetector(){ return gestureDetector; }
объявить
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);
и переопределить
dispatchTouchEvent
внутриActivity
:@Override public boolean dispatchTouchEvent(MotionEvent ev){ swipeListener.getGestureDetector().onTouchEvent(ev); return super.dispatchTouchEvent(ev); }
теперь оба прокрутки и салфетки действия должны работать.
для того чтобы
Click Listener
,DoubleClick Listener
,OnLongPress Listener
,Swipe Left
,Swipe Right
,Swipe Up
,Swipe Down
on SingleView
вам нужно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() { } }
использовать SwipeListView и пусть он обрабатывает обнаружение жестов для вас.
чтобы добавить 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(); } });
@ метод Эдварда Брея работает отлично. Если кто-то также хотел бы скопировать и вставить импорт для
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;
нуждается в некоторых незначительных обновлениях. Переменные не совпадают в методе onTouch, и класс исключений не импортируется. Было бы разумнее просто вернуть false из onFling(), вместо того, чтобы инициировать переменную, присваивая ей значение, ничего не делая с ней и просто возвращая ее.
некоторые части метода onTouch неверны. Смотрите view / motionEvent не может быть разрешен с помощью переменной swipe
один полезный совет, который сэкономил бы мне некоторое время, и я надеюсь может помочь другим: когда вы используете этот метод, вы только хотите добавить тег "implements" в свой класс OnSwipeTouchListener. Ваша деятельность и представление не реализуют его. Они просто используют в своих интересах ваш класс, который уже делает!
+1 для Мирека, потому что его код все еще дал мне то, что мне нужно для моего :)
небольшая модификация ответа @Mirek Rusin, и теперь вы можете обнаруживать мультитач-пойло. Этот код находится на Kotlin:
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 } }}
Где Жест.SWIPE_RIGHT и другие являются уникальным целочисленным индентификатором жеста, который я использую для обнаружения вида жеста позже в моей деятельности:
rootView?.setOnTouchListener(OnSwipeTouchListener(this, { gesture -> log(Gesture.parseName(this, gesture)) }))
Итак, вы видите, что жест здесь является целочисленной переменной, которая содержит значение, которое я передал раньше.
вам не нужны сложные расчеты. просто используя
GestureDetector
в своемOnGestureListener
внутриonFling
:
MyGestureListener.java
:import android.util.Log; import android.view.GestureDetector; import android.view.MotionEvent; public class MyGestureListener implements GestureDetector.OnGestureListener{ private static final long VELOCITY_THRESHOLD = 3000; @Override public boolean onDown(final MotionEvent e){ return false; } @Override public void onShowPress(final MotionEvent e){ } @Override public boolean onSingleTapUp(final MotionEvent e){ return false; } @Override public boolean onScroll(final MotionEvent e1, final MotionEvent e2, final float distanceX, final float distanceY){ return false; } @Override public void onLongPress(final MotionEvent e){ } @Override public boolean onFling(final MotionEvent e1, final MotionEvent e2, final float velocityX, final float velocityY){ if(Math.abs(velocityX) < VELOCITY_THRESHOLD && Math.abs(velocityY) < VELOCITY_THRESHOLD){ return false;//if the fling is not fast enough then it's just like drag } //if velocity in X direction is higher than velocity in Y direction, //then the fling is horizontal, else->vertical if(Math.abs(velocityX) > Math.abs(velocityY)){ if(velocityX >= 0){ Log.i("TAG", "swipe right"); }else{//if velocityX is negative, then it's towards left Log.i("TAG", "swipe left"); } }else{ if(velocityY >= 0){ Log.i("TAG", "swipe down"); }else{ Log.i("TAG", "swipe up"); } } return true; } }
использование:
GestureDetector mDetector = new GestureDetector(MainActivity.this, new MyGestureListener()); view.setOnTouchListener(new View.OnTouchListener(){ @Override public boolean onTouch(final View v, final MotionEvent event){ return mDetector.onTouchEvent(event); } });
@Mirek Rusin answeir очень хорош. Но, есть небольшая ошибка, и исправление 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; }
какая разница? Мы устанавливаем result = true, только если мы проверили, что все requrinments (и SWIPE_THRESHOLD и SWIPE_VELOCITY_THRESHOLD в порядке ). Это важно, если мы отбрасываем салфетки, если некоторые из требований не достигнуты,и мы должны сделать smth в методе onswipetouchlistener onswipetouchlistener!
вот простой Android код для обнаружения направления жеста
на
MainActivity.java
иactivity_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>
мое решение аналогично приведенным выше, но я абстрагировал обработку жестов в абстрактный класс
OnGestureRegisterListener.java
, которая включает салфетки,клик и долго нажать жесты.OnGestureRegisterListener.java
public abstract class OnGestureRegisterListener implements View.OnTouchListener { private final GestureDetector gestureDetector; private View view; public OnGestureRegisterListener(Context context) { gestureDetector = new GestureDetector(context, new GestureListener()); } @Override public boolean onTouch(View view, MotionEvent event) { this.view = view; return gestureDetector.onTouchEvent(event); } public abstract void onSwipeRight(View view); public abstract void onSwipeLeft(View view); public abstract void onSwipeBottom(View view); public abstract void onSwipeTop(View view); public abstract void onClick(View view); public abstract boolean onLongClick(View view); 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 void onLongPress(MotionEvent e) { onLongClick(view); super.onLongPress(e); } @Override public boolean onSingleTapUp(MotionEvent e) { onClick(view); return super.onSingleTapUp(e); } @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(view); } else { onSwipeLeft(view); } result = true; } } else if (Math.abs(diffY) > SWIPE_THRESHOLD && Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD) { if (diffY > 0) { onSwipeBottom(view); } else { onSwipeTop(view); } result = true; } } catch (Exception exception) { exception.printStackTrace(); } return result; } } }
и использовать его так. Обратите внимание, что вы можете легко пройти в свой
последний impl работает только с этим:
@Override public boolean onDown(MotionEvent e) { return true; }
Если вы хотите отобразить несколько кнопок с действиями, когда элемент списка проведите много библиотек в интернете, которые имеют такое поведение. Я реализовал библиотеку, которую я нашел в интернете, и я очень доволен. Это очень простой в использовании и очень быстро. Я улучшил исходную библиотеку и добавил новый прослушиватель щелчка для щелчка элемента. Также я добавил шрифт awesome library (http://fortawesome.github.io/Font-Awesome/) и теперь вы можете просто добавить новый заголовок элемента и Укажите имя значок из шрифта.
здесь это ссылка github
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(); } } }
использование ответ Эдварда Брея в Котлин
view.setOnTouchListener(object: OnSwipeTouchListener(this) { override fun onSwipeLeft() { super.onSwipeLeft() } override fun onSwipeRight() { super.onSwipeRight() } } )
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 /** * Detects left and right swipes across a view. */ class OnSwipeTouchListener(context: Context, onSwipeCallBack: OnSwipeCallBack?) : OnTouchListener { private var gestureDetector : GestureDetector private var onSwipeCallBack: OnSwipeCallBack?=null init { gestureDetector = GestureDetector(context, GestureListener()) this.onSwipeCallBack = onSwipeCallBack!! } companion object { private val SWIPE_DISTANCE_THRESHOLD = 100 private val SWIPE_VELOCITY_THRESHOLD = 100 } /* fun onSwipeLeft() {} fun onSwipeRight() {}*/ override fun onTouch(v: View, event: MotionEvent): Boolean { return gestureDetector.onTouchEvent(event) } private inner class GestureListener : SimpleOnGestureListener() { override fun onDown(e: MotionEvent): Boolean { return true } override fun onFling(eve1: MotionEvent?, eve2: MotionEvent?, velocityX: Float, velocityY: Float): Boolean { try { if(eve1 != null&& eve2!= null) { val distanceX = eve2?.x - eve1?.x val distanceY = eve2?.y - eve1?.y if (Math.abs(distanceX) > Math.abs(distanceY) && Math.abs(distanceX) > SWIPE_DISTANCE_THRESHOLD && Math.abs(velocityX) > SWIPE_VELOCITY_THRESHOLD) { if (distanceX > 0) onSwipeCallBack!!.onSwipeLeftCallback() else onSwipeCallBack!!.onSwipeRightCallback() return true } } }catch (exception:Exception){ exception.printStackTrace() } return false } } }