Android 如何为 ImageButton 组合 OnClickListener 和 OnTouchListener
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11578718/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to combine OnClickListener and OnTouchListener for an ImageButton
提问by Tobias Moe Thorstensen
I need to do something when the user clicks the ImageButton
I've tried to create a static class that implements bothOnClickListener
and OnTouchListener
当用户单击ImageButton
我试图创建一个同时实现OnClickListener
和的静态类时,我需要做一些事情OnTouchListener
static class ClickListenerForScrolling implements OnClickListener, OnTouchListener
that has the following methods:
具有以下方法:
@Override
public void onClick(View v)
and
和
@Override
public boolean onTouch(View arg0, MotionEvent arg1)
The whole idea behind this is to change the image source of the ImageButton
when the user touches it, and perform a task when the user clicks this button. Can anybody give me a hint on how to do this?
这背后的整个想法是ImageButton
在用户触摸它时更改其图像源,并在用户单击此按钮时执行任务。任何人都可以给我一个关于如何做到这一点的提示吗?
回答by Sven Menschner
Since both actions consist of the gestures "put finger on screen - lift finger from screen" you can't determine if it was touch action or a click action. So if you implement both listeners on this image button, a touch/click will change the picture AND press the button. Not sure if there is a determined order of these events...
由于这两个动作都包含“将手指放在屏幕上 - 从屏幕上抬起手指”的手势,因此您无法确定它是触摸动作还是点击动作。因此,如果您在此图像按钮上实现两个侦听器,则触摸/单击将更改图片并按下按钮。不确定这些事件是否有确定的顺序......
However, if you want to separate these events, you will either need to define to a different gesture to one of the actions (like wiping to change picture), or create different areas who handle the events, for example the image doesn't fit the whole button and the free area serves as button click area.
但是,如果要分离这些事件,则需要为其中一个操作定义不同的手势(例如擦除以更改图片),或者创建处理事件的不同区域,例如图像不适合整个按钮和空闲区域用作按钮单击区域。
HTH
HTH
Update:
更新:
I figured out, that a TouchEvent
is more general than a ClickEvent
thus it is called first.
我发现, aTouchEvent
比 a 更通用,ClickEvent
因此首先调用它。
public abstract boolean onTouch (View v, MotionEvent event)
This returns true, if the listener has consumed the event, false otherwise.
So you can decide in your implementation if the Event should also be handled by OnClickListener, then just return false
.
如果侦听器消耗了事件,则返回 true,否则返回 false。所以你可以在你的实现中决定事件是否也应该由 OnClickListener 处理,然后只返回false
.
回答by SUARPI - Oscar G.
The onTouchListener
is able to handle both movements.
的onTouchListener
是能够同时处理的动作。
Switch
between event.action()
values to obtain MotionEvent
.
Switch
event.action()
值之间获得MotionEvent
。
case MotionEvent.ACTION_DOWN
: is the first finger impact.case MotionEvent.ACTION_UP
: is when the finger goes away.
case MotionEvent.ACTION_DOWN
: 是第一指冲击。case MotionEvent.ACTION_UP
: 是手指消失的时候。
You'll have to set the impact point on ACTION_DOWN
.
您必须将撞击点设置为ACTION_DOWN
。
TheImpactPoint=event.getX();
TheImpactPoint=event.getX();
And then obtain the distance with ACTION_UP
然后获得距离 ACTION_UP
float distance =TheImpactPoint-event.getX();
float distance =TheImpactPoint-event.getX();
If distance = 0
then there is a click, otherwise it would be more or less than zero depending on gesture.
If distance = 0
然后有一个点击,否则它会大于或小于零取决于手势。
So this is the way to use the click event without a real click event and using only the onTouchListener
.
所以这是在没有真正的点击事件的情况下使用点击事件并且只使用onTouchListener
.
Hope will be useful.
希望会有用。
回答by siarhei sin
Use this code:
使用此代码:
public class GestureHelper implements OnTouchListener {
private final GestureDetector mGestureDetector;
public GestureHelper(Context context) {
mGestureDetector = new GestureDetector(context, new GestureListener(this));
}
public void onSwipeRight() {
};
public void onSwipeLeft() {
};
public void onSwipeTop() {
};
public void onSwipeBottom() {
};
public void onDoubleTap() {
};
public void onClick() {
};
@Override
public boolean onTouch(View v, MotionEvent event) {
return mGestureDetector.onTouchEvent(event);
}
private static final class GestureListener extends SimpleOnGestureListener {
private static final int SWIPE_THRESHOLD = 100;
private static final int SWIPE_VELOCITY_THRESHOLD = 100;
private GestureHelper mHelper;
public GestureListener(GestureHelper helper) {
mHelper = helper;
}
@Override
public boolean onDown(MotionEvent e) {
return true;
}
@Override
public boolean onSingleTapUp(MotionEvent e) {
mHelper.onClick();
return true;
}
@Override
public boolean onDoubleTap(MotionEvent e) {
mHelper.onDoubleTap();
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) {
mHelper.onSwipeRight();
} else {
mHelper.onSwipeLeft();
}
}
} else {
if (Math.abs(diffY) > SWIPE_THRESHOLD && Math.abs(velocityY) > SWIPE_VELOCITY_THRESHOLD) {
if (diffY > 0) {
mHelper.onSwipeBottom();
} else {
mHelper.onSwipeTop();
}
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
return result;
}
}
}
Extend this class and use like this...
扩展这个类并像这样使用......
view.setOnTouchListener(new SomeYourGestureHelper(context, someParameters));
回答by stannums
Use return false
instead of return true
使用return false
代替return true
回答by Mohammad Elsayed
There are many solutions for this problem, the best one for me is to eliminate totally the setOnClickListener and inside the onTouchListener do check if the action is ACTION_UP and then inside that check if the last before that is ACTION_DOWN:
这个问题有很多解决方案,对我来说最好的一个是完全消除 setOnClickListener 并在 onTouchListener 内部检查动作是否为 ACTION_UP 然后在该内部检查之前的最后一个是否为 ACTION_DOWN:
case MotionEvent.ACTION_UP:
if (lastAction == MotionEvent.ACTION_DOWN) {
//code for click
.
.
lastAction = event.getAction();
}
lastAction is int and I update it at the end of each ACTION
lastAction 是 int 并且我在每个 ACTION 结束时更新它