Adding Fling Gesture to an image view - Android
好的,我在这里引用了代码:在网格布局上进行手势检测
但是无法让它发挥作用。 在我的主要活动中,我定义了一个简单的图像。 我想检测一下图像上的闪光。 这是我的代码如下。 底部的onclick方法为空。 是因为这个吗? 我把它留空了,因为在其他代码示例中它不是我想要的。 我只想要一个简单的吐司,弹出正确的方向或向前扔。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | public class GestureRightLeft extends Activity implements OnClickListener { ImageView peek; private static final int SWIPE_MIN_DISTANCE = 120; private static final int SWIPE_MAX_OFF_PATH = 250; private static final int SWIPE_THRESHOLD_VELOCITY = 200; private GestureDetector gestureDetector; View.OnTouchListener gestureListener; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); peek =(ImageView) findViewById(R.id.peek); peek.setImageResource(R.drawable.bluestrip); gestureDetector = new GestureDetector(new MyGestureDetector()); gestureListener = new View.OnTouchListener() { public boolean onTouch(View v, MotionEvent event) { if (gestureDetector.onTouchEvent(event)) { return true; } return false; } }; } class MyGestureDetector extends SimpleOnGestureListener { @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { try { if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH) return false; // right to left swipe if(e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) { Toast.makeText(GestureRightLeft.this,"Left Swipe", Toast.LENGTH_SHORT).show(); } else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) { Toast.makeText(GestureRightLeft.this,"Right Swipe", Toast.LENGTH_SHORT).show(); } } catch (Exception e) { // nothing } return false; } } @Override public void onClick(View v) {} } |
这是我能想到的最简单的弗林格工作版本。
实际上,您可以将其绑定到任何组件,而不仅仅是ImageView。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | public class MyActivity extends Activity { private void onCreate() { final GestureDetector gdt = new GestureDetector(new GestureListener()); final ImageView imageView = (ImageView) findViewById(R.id.image_view); imageView.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(final View view, final MotionEvent event) { gdt.onTouchEvent(event); return true; } }); } private static final int SWIPE_MIN_DISTANCE = 120; private static final int SWIPE_THRESHOLD_VELOCITY = 200; private class GestureListener extends SimpleOnGestureListener { @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { if(e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) { return false; // Right to left } else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) { return false; // Left to right } if(e1.getY() - e2.getY() > SWIPE_MIN_DISTANCE && Math.abs(velocityY) > SWIPE_THRESHOLD_VELOCITY) { return false; // Bottom to top } else if (e2.getY() - e1.getY() > SWIPE_MIN_DISTANCE && Math.abs(velocityY) > SWIPE_THRESHOLD_VELOCITY) { return false; // Top to bottom } return false; } } } |
但是没有活动onClickListener(如果你不需要捕获任何onclick动作)
它不仅捕获水平,还捕获垂直(如果不需要,只删除垂直部分),水平滑动具有优先级,如您所见。
在方法返回的地方(我的评论在哪里)只是调用你的方法或其他:)
试试这个
1 2 3 4 5 6 7 8 9 10 | imageView.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { if (gestureDetector.onTouchEvent(event)) { return false; } return true; } }); |
1 2 3 4 5 6 7 | imageView.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { return !gestureDetector.onTouchEvent(event); } }); |
一些先决条件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | 1)setonClick method image.setOnClickListener(this); 2)set your gesture detection in onTouch() image.setOnTouchListener(new OnTouchListener() { GestureDetector gestureDetector = new GestureDetector(new SwingGestureDetection((mContext),image,a)); @Override public boolean onTouch(View v, MotionEvent event) { return gestureDetector.onTouchEvent(event); } }); 3)create SwingGestureDetection class and implement all method @Override public boolean onFling(MotionEvent start, MotionEvent finish, float arg2,float arg3) { if(start.getRawX()<finish.getRawX()){ System.out.println("next...swing"); }else{ System.out.println("previois...swing"); } 4)pass your imageview in constructor public SwingGestureDetection(Context con,ImageView image,int pos) { mContext=con; this.image=image; this.position=pos; } |
这对我来说是完美的工作。如果任何查询然后发表评论。
试着读:
http://illusionsandroid.blogspot.com/2011/05/adding-fling-gesture-listener-to-view.html
它允许您将活动实现与自定义侦听器分开。这只是Alex Orlov报道的解决方案的重构
如果您不想创建单独的类或使代码复杂,
您可以在OnTouchListener中创建一个GestureDetector变量,使代码更容易
namVyuVar可以是您需要设置列表器的View的任何名称
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | namVyuVar.setOnTouchListener(new View.OnTouchListener() { @Override public boolean onTouch(View view, MotionEvent MsnEvtPsgVal) { flingActionVar.onTouchEvent(MsnEvtPsgVal); return true; } GestureDetector flingActionVar = new GestureDetector(getApplicationContext(), new GestureDetector.SimpleOnGestureListener() { private static final int flingActionMinDstVac = 120; private static final int flingActionMinSpdVac = 200; @Override public boolean onFling(MotionEvent fstMsnEvtPsgVal, MotionEvent lstMsnEvtPsgVal, float flingActionXcoSpdPsgVal, float flingActionYcoSpdPsgVal) { if(fstMsnEvtPsgVal.getX() - lstMsnEvtPsgVal.getX() > flingActionMinDstVac && Math.abs(flingActionXcoSpdPsgVal) > flingActionMinSpdVac) { // TskTdo :=> On Right to Left fling return false; } else if (lstMsnEvtPsgVal.getX() - fstMsnEvtPsgVal.getX() > flingActionMinDstVac && Math.abs(flingActionXcoSpdPsgVal) > flingActionMinSpdVac) { // TskTdo :=> On Left to Right fling return false; } if(fstMsnEvtPsgVal.getY() - lstMsnEvtPsgVal.getY() > flingActionMinDstVac && Math.abs(flingActionYcoSpdPsgVal) > flingActionMinSpdVac) { // TskTdo :=> On Bottom to Top fling return false; } else if (lstMsnEvtPsgVal.getY() - fstMsnEvtPsgVal.getY() > flingActionMinDstVac && Math.abs(flingActionYcoSpdPsgVal) > flingActionMinSpdVac) { // TskTdo :=> On Top to Bottom fling return false; } return false; } }); }); |
使用ImageView设计您的布局。
将
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | float x1,x2; float y1, y2; @Override public boolean onTouch(View view, MotionEvent event) { switch ( event.getAction() ){ case MotionEvent.ACTION_DOWN:{ x1 = event.getX(); y1 = event.getY(); break; } case MotionEvent.ACTION_UP:{ x2 = event.getX(); y2 = event.getY(); if ( x1<x2 ) { //implement what you need to do here } if ( x1>x2 ) { //implement what you need to do here } break; } } return false; } |
如果您正在寻找像ImageView.setOnGestureListener这样的方法,那么就没有了。你可以去看看Android源代码。您最好的选择是在View对象的onTouch()中处理它。
这是我能做的最简单的GestureDetector。
我有一个名为GenesMotionDetector.java的类。这是它的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | package gene.com.motioneventssample; import android.app.Activity; import android.os.Bundle; import android.view.GestureDetector; import android.view.MotionEvent; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.TextView; public class GenesMotionDetector extends Activity implements GestureDetector.OnGestureListener { private GestureDetector gestureScanner; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.nothing); gestureScanner= new GestureDetector(getBaseContext(),this); } @Override public boolean onTouchEvent(MotionEvent me) { System.out.println("Inside onTouchEvent() of GenesMotionDetector.java"); return gestureScanner.onTouchEvent(me); } @Override public boolean onDown(MotionEvent e) { System.out.println("Inside onDown() of GenesMotionDetector.java"); return true; } @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { System.out.println("Inside onFling() of GenesMotionDetector.java"); return true; } @Override public void onLongPress(MotionEvent e) { System.out.println("Inside onLongPress() of GenesMotionDetector.java"); } @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { System.out.println("Inside onScroll() of GenesMotionDetector.java"); return true; } @Override public void onShowPress(MotionEvent e) { System.out.println("Inside onShowPress() of GenesMotionDetector.java"); } @Override public boolean onSingleTapUp(MotionEvent e) { System.out.println("Inside onSingleTapUp() of GenesMotionDetector.java"); return true; } } |
该类的相应XML布局文件是nothing.xml。这是它的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/screen" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:id="@+id/text" android:background="#17528c" android:text="testing" android:layout_width="100dp" android:layout_height="200dp" /> <ImageView android:id="@+id/image" android:background="#f8af20" android:layout_width="100dp" android:layout_height="200dp" /> </LinearLayout> |
现在,采取我可以制作的最简单的GestureDetector(从上面)并根据你的需要修改它,我得到这个:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 | package gene.com.motioneventssample; import android.app.Activity; import android.os.Bundle; import android.view.GestureDetector; import android.view.MotionEvent; import android.view.VelocityTracker; import android.view.View; import android.widget.ImageView; public class GenesMotionDetector3 extends Activity implements GestureDetector.OnGestureListener { private GestureDetector gestureScanner; ImageView mView3; View.OnTouchListener gestureListener; MotionEvent initialME, finalME; private VelocityTracker mVelocityTracker = null; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.nothing); mView3 = (ImageView) findViewById(R.id.image); // Gesture detection gestureScanner = new GestureDetector(getBaseContext(), this); gestureListener = new View.OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { switch(event.getAction()){ case MotionEvent.ACTION_DOWN: initialME= event; if(mVelocityTracker == null) { // Retrieve a new VelocityTracker object to watch the velocity of a motion. mVelocityTracker = VelocityTracker.obtain(); } else { // Reset the velocity tracker back to its initial state. mVelocityTracker.clear(); } // Add a user's movement to the tracker. mVelocityTracker.addMovement(event); break; case MotionEvent.ACTION_MOVE: mVelocityTracker.addMovement(event); // When you want to determine the velocity, call // computeCurrentVelocity(). Then call getXVelocity() // and getYVelocity() to retrieve the velocity for each pointer ID. mVelocityTracker.computeCurrentVelocity(1000); break; case MotionEvent.ACTION_UP: finalME=event; break; case MotionEvent.ACTION_CANCEL: // Return a VelocityTracker object back to be re-used by others. mVelocityTracker.recycle(); break; } return onFling(initialME, finalME, mVelocityTracker.getXVelocity(), mVelocityTracker.getYVelocity()); //return false; } }; mView3.setOnTouchListener(gestureListener); } @Override public boolean onTouchEvent(MotionEvent me) { System.out.println("Inside onTouchEvent() of GenesMotionDetector.java"); return gestureScanner.onTouchEvent(me); } @Override public boolean onDown(MotionEvent e) { System.out.println("Inside onDown() of GenesMotionDetector.java"); return true; } @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { System.out.println("Inside onFling() of GenesMotionDetector.java"); System.out.println("e1="+ e1); System.out.println("e2="+ e2); System.out.println("velocityX="+ velocityX); System.out.println("velocityY="+ velocityY); return true; } @Override public void onLongPress(MotionEvent e) { System.out.println("Inside onLongPress() of GenesMotionDetector.java"); } @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { System.out.println("Inside onScroll() of GenesMotionDetector.java"); return true; } @Override public void onShowPress(MotionEvent e) { System.out.println("Inside onShowPress() of GenesMotionDetector.java"); } @Override public boolean onSingleTapUp(MotionEvent e) { System.out.println("Inside onSingleTapUp() of GenesMotionDetector.java"); return true; } } |
您也可以只处理onTouch()中的所有内容。我基本上是在onTouch中获取手势并将其传递给onFling()。