J'ai une EditText
vue sous Android. Sur ce, je veux détecter un balayage vers la gauche ou la droite. Je peux l'obtenir sur un espace vide en utilisant le code ci-dessous. Mais cela ne fonctionne pas lorsque je glisse sur un fichier EditText
. Comment je fais ça? S'il vous plaît laissez-moi savoir si je fais quelque chose de mal. Merci.
Code utilisé:
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;
}
}
Réponses:
Détecteur de balayage de gauche à droite le plus simple:
Dans votre classe d'activités, ajoutez les attributs suivants:
private float x1,x2; static final int MIN_DISTANCE = 150;
et
onTouchEvent()
méthode de remplacement :@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); }
la source
getAction()
renvoie des données mixtes du type d'action et de l'index de pointeur, il ne serait pas préférable d'utilisergetActionMasked()
, cela ne renvoie que le type d'action?J'aime le code de @ user2999943. Mais juste quelques changements mineurs pour mes propres besoins.
@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); }
la source
C'est une classe mignonne que j'utilise (dans les cas où je veux attraper un événement sur une vue, s'il s'agit d'un ViewGroup, j'utilise la deuxième implémentation):
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 } }
et ceci est un exemple d'utilisation:
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(); } });
Dans certains cas, vous souhaitez détecter les gestes de balayage sur un conteneur et transmettre les événements tactiles aux enfants afin que dans ce cas, vous puissiez créer un groupe d'affichage personnalisé, disons RelativeLayout et remplacer onInterceptTouchEvent, et là vous pouvez détecter l'événement de balayage sans bloquer le passage de Touch Event à vos vues enfants, par exemple:
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; } }
la source
Les événements de balayage sont une sorte d'
onTouch
événements. Simplement simplifier la réponse de @Gal Rom, il suffit de garder une trace des deltas verticaux et horizontaux, et avec un peu de maths, vous pouvez déterminer le type de balayage d'un touchEvent. (Encore une fois, permettez-moi de souligner que c'était OBSENEMENT basé sur une réponse précédente, mais la simplicité peut plaire aux novices). L'idée est d'étendre un OnTouchListener, de détecter le type de balayage (tactile) qui vient de se produire et d'appeler des méthodes spécifiques pour chaque type.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(); } }
la source
J'ai écrit une classe simple qui permet de détecter facilement les événements de balayage - TOP, RIGHT, BOTTOM, LEFT.
1: détecter un événement de balayage unique
// 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: Détectez l'un des événements de balayage avec un seul rappel.
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 } });
Voici un article de blog expliquant comment utiliser: http://bmutinda.com/android-detect-swipe-events/
J'ai également créé un Gist pour les extraits de code disponibles ici: https://gist.github.com/bmutinda/9578f70f1df9bd0687b8
Merci.
la source
Détecteur de balayage de gauche à droite et de droite à gauche
Tout d'abord, déclarez deux variables de type de données flottantes.
private float x1, x2;
Deuxièmement, câblez votre vue xml en java. Comme j'ai
ImageView
ImageView img = (ImageView) findViewById(R.id.imageView);
Troisièmement,
setOnTouchListener
sur votreImageView
.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; } });
la source
Je veux ajouter à la réponse acceptée qui fonctionne partiellement, mais il manque la variable de temps, ce qui la rend parfaite.
Détecteur de balayage de gauche à droite le plus simple avec une variable de temps:
Dans votre classe d'activités, ajoutez les attributs suivants:
private float x1,x2; private long startClickTime; static final int MIN_DISTANCE = 150; static final int MAX_SWIPE_TIME = 200;
et remplacez la méthode 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); }
la source
Je pense que ce que tu veux s'appelle une aventure. Les MotionEvents peuvent être utilisés pour déterminer la direction du lancer.
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
la source
Détecter le balayage dans quatre directions
private float x1,x2,y1,y2; static final int MIN_DISTANCE = 70;
et
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; }
la source
Après une journée complète de travail sur cette fonctionnalité, nous avons enfin pu obtenir la bonne réponse.
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);
Bonne chance .
la source
Si vous souhaitez capturer l'événement dès le début du balayage, vous pouvez utiliser MotionEvent.ACTION_MOVE et stocker la première valeur à comparer
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; } });
la source
Toast.makeText(MainAcivity.this, "top to down" + increaseValue, Toast.LENGTH_SHORT).show();
elle, comment faire un seul coup pour ajouter des valeurs min = 0 et max = 10.cela devrait peut-être vous aider ...
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); } };
la source
Version courte et facile:
1. Créez d'abord cette classe abstraite
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(); } }
Ensuite, créez une classe concrète mettant en œuvre ce dont vous avez besoin:
public class SwipeListener extends HorizontalSwipeListener { public SwipeListener() { super(200); } @Override void onSwipeRight() { System.out.println("right"); } @Override void onSwipeLeft() { System.out.println("left"); } }
la source
voici un détecteur générique de balayage à gauche pour toute vue dans kotlin utilisant la liaison de données
@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 } }) }
puis pour l'utiliser dans votre mise en page:
app:onSwipeLeft="@{() -> viewModel.swipeLeftHandler()}"
la source
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; }
la source
la meilleure réponse est celle de @Gal Rom. il y a plus d'informations à ce sujet: touchez d'abord les retours d'événement aux vues enfants. et si vous définissez un écouteur onClick ou onTouch pour eux, la vue parnt (par exemple fragment) ne recevra aucun écouteur tactile. Donc, si vous voulez définir l'écouteur de balayage pour le fragment dans cette situation, vous devez l'implémenter dans une nouvelle classe:
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; } }
J'ai changé la classe de @Gal Rom. Ainsi, il peut détecter à la fois le balayage à droite et à gauche et, spécialement, il renvoie onInterceptTouchEvent true après la détection. c'est important parce que si nous ne le faisons pas parfois, les vues enfants peuvent recevoir un événement et que Swipe pour fragment et onClick pour vue enfant (par exemple) s'exécutent et causent des problèmes. après avoir créé cette classe, vous devez modifier votre fichier XML de fragment:
<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>
vous voyez que la balise de début est la classe que nous avons créée. maintenant dans la classe fragment:
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(); }
C'est un peu compliqué mais fonctionne parfaitement :)
la source
Vous devez étendre une classe à partir de
View.OnTouchListener
et gérer laonTouch
méthode en la remplaçant.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() } }
Vous pouvez simplement l'implémenter comme ceci dans votre fichier
Activity
ouFragment
.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() } }
la source