将 Fling 手势添加到图像视图 - Android
Posted
技术标签:
【中文标题】将 Fling 手势添加到图像视图 - Android【英文标题】:Adding Fling Gesture to an image view - Android 【发布时间】:2011-05-05 03:13:38 【问题描述】:好的,我一直在这里引用代码:Fling gesture detection on grid layout
但就是不能让它工作。在我的主要活动中,我定义了一个简单的图像。我想检测图像上的一扔。下面是我的代码。底部的 onclick 方法是空的。是不是因为这个?我将其留空,因为在其他代码示例中它不是我想要的。我只想弹出一个简单的吐司,说向右或向左。
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)
【问题讨论】:
另见How to add a gesture detector to a view in android 【参考方案1】:这是我能想到的最简单的 flinger 工作版本。 实际上,您可以将它绑定到任何组件,而不仅仅是 ImageView。
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 操作) 它不仅可以捕获水平,还可以捕获垂直(如果不需要,只需删除垂直部分),并且水平滑动具有优先级,如您所见。 在方法返回的地方(我的 cmets 所在的地方)只需调用您的方法或其他任何方法 :)
【讨论】:
改用final GestureDetector gdt = GestureDetector(this, new GestureListener());
,根据developer.android.com/reference/android/view/…
这更像是分页。可以在这里找到一个很好的示例:developer.android.com/training/custom-views/…
@Radu,阅读@Snicolas 提供的链接。您必须覆盖 onDown
并返回 true。
我不完全理解代码,但 IMO 这不可能是正确的,因为 onFling
在所有执行路径中都返回 false
。【参考方案2】:
试试这个
imageView.setOnTouchListener(new View.OnTouchListener()
@Override
public boolean onTouch(View v, MotionEvent event)
if (gestureDetector.onTouchEvent(event))
return false;
return true;
);
【讨论】:
+1 谢谢老兄它对我有用.. 我返回 true 而不是 false 。现在我的问题解决了 @contactmeandroid 里面如果条件我也返回 true;它对我有用。 @Ganapathy 它有效,但在滑动时我想拖动图像但我无法做到 android 中的拖放框架可能会对您有所帮助。developer.android.com/guide/topics/ui/drag-drop.html 简化返回 !mGestureDetector.onTouchEvent(motionEvent);【参考方案3】:imageView.setOnTouchListener(new View.OnTouchListener()
@Override
public boolean onTouch(View v, MotionEvent event)
return !gestureDetector.onTouchEvent(event);
);
【讨论】:
【参考方案4】:一些前置条件
1) setonClick 方法
image.setOnClickListener(this);
2) 在 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) 创建 SwingGestureDetection 类并实现所有方法
@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) 在构造函数中传递您的图像视图
public SwingGestureDetection(Context con,ImageView image,int pos)
mContext = con;
this.image = image;
this.position = pos;
这对我来说是完美的工作。如果有任何疑问,请发表评论。
【讨论】:
【参考方案5】:尝试阅读: http://illusionsandroid.blogspot.com/2011/05/adding-fling-gesture-listener-to-view.html
它允许您将活动实现与自定义侦听器分开。这只是对 Alex Orlov 报告的解决方案的重构
【讨论】:
【参考方案6】:如果您不喜欢创建单独的类或使代码复杂, 你可以在 OnTouchListener 中创建一个 GestureDetector 变量,让你的代码更简单
namVyuVar 可以是任何需要设置listner的View的名字
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;
);
);
【讨论】:
【参考方案7】:如果您正在寻找像 ImageView.setOnGestureListener 这样的方法,则没有。你可以去看看Android源代码。您最好的选择是在 View 对象的 onTouch() 中处理它。
这是我能做的最简单的 GestureDetector。
我有一个名为 GenesMotionDetector.java 的类。这是它的代码:
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。这是它的代码:
<?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_
android:layout_>
<TextView
android:id="@+id/text"
android:background="#17528c"
android:text="testing"
android:layout_
android:layout_ />
<ImageView
android:id="@+id/image"
android:background="#f8af20"
android:layout_
android:layout_ />
</LinearLayout>
现在,使用我可以(从上面)制作的最简单的 GestureDetector 并根据您的需要对其进行修改,我得到了:
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()。
【讨论】:
【参考方案8】:使用 ImageView 设计您的布局。
将setOnTouchListener
添加到imageView.imageview.setOnTouchListener(this)
.添加未实现的方法View.OnTouchListener
。然后onTouch
方法您可以实现您的客座逻辑。这个示例告诉您从左到右和从右到左客座,
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;
【讨论】:
答案不提供投掷逻辑,OP正在寻找。以上是关于将 Fling 手势添加到图像视图 - Android的主要内容,如果未能解决你的问题,请参考以下文章