Имею EditText
вид в android. На этом я хочу обнаружить свайп влево или вправо. Я могу получить его на пустом месте, используя приведенный ниже код. Но это не работает, когда я смахиваю по файлу 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); }
источник
getAction()
возвращает смешанные данные как типа действия, так и индекса указателя, не лучше ли использоватьgetActionMasked()
, который возвращает только тип действия?Мне нравится код от @ 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); }
источник
Это симпатичный класс, который я использую (в случаях, когда я хочу поймать событие в View, если это 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(); } });
В некоторых случаях вы хотели бы обнаружить жесты смахивания на контейнере и передать события касания дочерним элементам, чтобы в этом случае вы могли создать группу Custom View, скажем, 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, просто отслеживайте вертикальные и горизонтальные дельты, и с небольшой математикой вы можете определить, какой был жест touchEvent. (Опять же, позвольте мне подчеркнуть, что это ОБЯЗАТЕЛЬНО основано на предыдущем ответе, но простота может понравиться новичкам). Идея состоит в том, чтобы расширить OnTouchListener, определить, какой тип касания (касания) только что произошел, и вызвать определенные методы для каждого типа.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: обнаружение любого события смахивания одним обратным вызовом.
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/
Я также создал Gist для фрагментов кода, доступных здесь: https://gist.github.com/bmutinda/9578f70f1df9bd0687b8
Спасибо.
источник
Слева направо и справа налево Детектор смахивания
Сначала объявите две переменные типа float.
private float x1, x2;
Во-вторых, подключите ваше xml-представление в java. Как у меня
ImageView
ImageView img = (ImageView) findViewById(R.id.imageView);
В-третьих,
setOnTouchListener
по вашемуImageView
.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; } });
источник
Я хочу добавить к принятому ответу, который работает частично, но в нем отсутствует переменная времени, что делает его идеальным.
Простейший детектор смахивания слева направо с переменной времени:
В вашем классе активности добавьте следующие атрибуты:
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); }
источник
Я думаю, то, что вы хотите, называется интрижкой. 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
источник
Обнаружение движения в четырех направлениях
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; }
источник
После целого дня работы над этой функцией наконец-то смог получить правильный ответ.
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);
Удачи .
источник
Если вы хотите поймать событие с начала смахивания, вы можете использовать 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; } });
источник
Toast.makeText(MainAcivity.this, "top to down" + increaseValue, Toast.LENGTH_SHORT).show();
нее, как сделать одно движение, чтобы добавить значения min = 0 и max = 10.это должно вам помочь ...
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); } };
источник
Краткая и легкая версия:
1. Сначала создайте этот абстрактный класс
public abstract class HorizontalSwipeListener implements View.OnTouchListener { private float firstX; private int minDistance; HorizontalSwipeListener(int minDistance) { this.minDistance = minDistance; } abstract void onSwipeRight(); abstract void onSwipeLeft(); @Override public boolean onTouch(View view, MotionEvent event) { switch (event.getAction()) { case MotionEvent.ACTION_DOWN: firstX = event.getX(); return true; case MotionEvent.ACTION_UP: float secondX = event.getX(); if (Math.abs(secondX - firstX) > minDistance) { if (secondX > firstX) { onSwipeLeft(); } else { onSwipeRight(); } } return true; } return view.performClick(); } }
2.Затем создайте конкретный класс, реализующий то, что вам нужно:
public class SwipeListener extends HorizontalSwipeListener { public SwipeListener() { super(200); } @Override void onSwipeRight() { System.out.println("right"); } @Override void onSwipeLeft() { System.out.println("left"); } }
источник
вот общий детектор смахивания влево для любого вида в Котлине с использованием привязки данных
@BindingAdapter("onSwipeLeft") fun View.setOnSwipeLeft(runnable: Runnable) { setOnTouchListener(object : View.OnTouchListener { var x0 = 0F; var y0 = 0F; var t0 = 0L val defaultClickDuration = 200 override fun onTouch(v: View?, motionEvent: MotionEvent?): Boolean { motionEvent?.let { event -> when(event.action) { MotionEvent.ACTION_DOWN -> { x0 = event.x; y0 = event.y; t0 = System.currentTimeMillis() } MotionEvent.ACTION_UP -> { val x1 = event.x; val y1 = event.y; val t1 = System.currentTimeMillis() if (x0 == x1 && y0 == y1 && (t1 - t0) < defaultClickDuration) { performClick() return false } if (x0 > x1) { runnable.run() } } else -> {} } } return true } }) }
а затем использовать его в своем макете:
app:onSwipeLeft="@{() -> viewModel.swipeLeftHandler()}"
источник
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; }
источник
лучший ответ - @Gal Rom. об этом подробнее: событие касания сначала возвращается в дочерние представления. и если вы определяете для них onClick или onTouch listener, parnt view (например, фрагмент) не получит никакого сенсорного слушателя. Поэтому, если вы хотите определить прослушиватель смахивания для фрагмента в этой ситуации, вы должны реализовать его в новом классе:
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. Таким образом, он может обнаруживать как правое, так и левое смахивание и, в частности, возвращает onInterceptTouchEvent true после обнаружения. это важно, потому что, если мы этого не сделаем, дочерние представления могут получать событие, и оба метода Swipe for fragment и onClick for child view (например) запускаются и вызывают некоторые проблемы. после создания этого класса вы должны изменить свой 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>
вы видите, что тег begin - это созданный нами класс. теперь в классе фрагментов:
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(); }
Это немного сложно, но отлично работает :)
источник
Вы должны расширить класс
View.OnTouchListener
и обработатьonTouch
метод, переопределив его.interface SwipeListener { fun onSwipeLeft() fun onSwipeRight() } class SwipeGestureListener internal constructor( private val listener: SwipeListener, private val minDistance: Int = DEFAULT_SWIPE_MIN_DISTANCE ) : View.OnTouchListener { companion object { const val DEFAULT_SWIPE_MIN_DISTANCE = 200 } private var anchorX = 0F override fun onTouch(view: View, event: MotionEvent): Boolean { when (event.action) { MotionEvent.ACTION_DOWN -> { anchorX = event.x return true } MotionEvent.ACTION_UP -> { if (abs(event.x - anchorX) > minDistance) { if (event.x > anchorX) { listener.onSwipeRight() } else { listener.onSwipeLeft() } } return true } } return view.performClick() } }
Вы можете легко реализовать это в своем
Activity
илиFragment
.class MainActivity : AppCompatActivity(), SwipeListener { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) viewGroup.setOnTouchListener(SwipeGestureListener(this)) } override fun onSwipeLeft() { Toast.makeText(this, "Swipe Left", Toast.LENGTH_SHORT).show() } override fun onSwipeRight() { Toast.makeText(this, "Swipe Right", Toast.LENGTH_SHORT).show() } }
источник