Android 如何获得连续的触摸事件?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2539524/
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 get a continuous Touch Event?
提问by daliz
My class extends View and I need to get continuous touch events on it.
我的课程扩展了 View,我需要在它上面获得连续的触摸事件。
If I use:
如果我使用:
public boolean onTouchEvent(MotionEvent me) {
if(me.getAction()==MotionEvent.ACTION_DOWN) {
myAction();
}
return true;
}
... the touch event is captured once.
...触摸事件被捕获一次。
What if I need to get continuous touches without moving the finger? Please, tell me I don't need to use threads or timers. My app is already too much heavy.
如果我需要在不移动手指的情况下连续触摸怎么办?请告诉我我不需要使用线程或计时器。我的应用程序已经太重了。
Thanks.
谢谢。
回答by Steve Haley
Use if(me.getAction() == MotionEvent.ACTION_MOVE)
. It's impossible to keep a finger 100% completely still on the screen so Action_Move will get called every time the finger moves, even if it's only a pixel or two.
使用if(me.getAction() == MotionEvent.ACTION_MOVE)
. 不可能让手指 100% 完全静止在屏幕上,因此每次手指移动时都会调用 Action_Move,即使它只有一两个像素。
You could also listen for me.getAction() == MotionEvent.ACTION_UP
- until that happens, the user must still have their finger on the screen.
您还可以聆听me.getAction() == MotionEvent.ACTION_UP
- 在发生这种情况之前,用户必须仍将手指放在屏幕上。
回答by Nicolás Loaiza
You need to set this properties for the element android:focusable="true" android:clickable="true" if not, just produce the down action.
您需要为元素 android:focusable="true" android:clickable="true" 设置此属性,否则,只需生成向下操作。
回答by Rahul Patel
Her is the simple code snippet which shows that how you can handle the continues touch event. When you touch the device and hold the touch and move your finder, the Touch Move action performed.
她是一个简单的代码片段,它显示了如何处理继续触摸事件。当您触摸设备并按住触摸并移动您的查找器时,将执行触摸移动操作。
@Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
if(isTsunami){
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
// Write your code to perform an action on down
break;
case MotionEvent.ACTION_MOVE:
// Write your code to perform an action on contineus touch move
break;
case MotionEvent.ACTION_UP:
// Write your code to perform an action on touch up
break;
}
}
return true;
}
回答by Garry
Try this. It works to me:
尝试这个。它对我有用:
public static OnTouchListener loadContainerOnTouchListener() {
OnTouchListener listener = new OnTouchListener(){
@Override
public boolean onTouch(View v, MotionEvent event) {
LinearLayout layout = (LinearLayout)v;
for(int i =0; i< layout.getChildCount(); i++)
{
View view = layout.getChildAt(i);
Rect outRect = new Rect(view.getLeft(), view.getTop(), view.getRight(), view.getBottom());
if(outRect.contains((int)event.getX(), (int)event.getY()))
{
Log.d(this.getClass().getName(), String.format("Over view.id[%d]", view.getId()));
}
}
}
Remember: the listener you′ll set must be a container layout (Grid, Relative, Linear).
请记住:您将设置的侦听器必须是容器布局(Grid、Relative、Linear)。
LinearLayout layout = findViewById(R.id.yourlayoutid);
layout.setOnTouchListener(HelperClass.loadContainerOnTouchListener());
回答by Pb Studies
This might help,
这可能会有所帮助,
requestDisallowInterceptTouchEvent(true);
on the parent view, like this -
在父视图上,像这样 -
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
view.getParent().requestDisallowInterceptTouchEvent(true);
switch(motionEvent.getAction()){
}
return false;
}
回答by Chris Sullivan
I was making a game with a custom view used as a thumb control. . . here is what I did
我正在制作一个带有用作拇指控件的自定义视图的游戏。. . 这是我所做的
float x = 0, y = 0;
@Override
public boolean onTouchEvent(MotionEvent event) {
x = event.getX();
y = event.getY();
// handle touch events with
switch( event.getActionMasked() ) {
case MotionEvent.ACTION_DOWN :
if(cont)
{
// remove any previous callbacks
removeCallbacks(contin);
// post new runnable
postDelayed(contin, 10);
}
invalidate();
return true;
case MotionEvent.ACTION_MOVE :
if(!cont && thumbing != null)
{
// do non-continuous operations here
}
invalidate();
return true;
case MotionEvent.ACTION_UP :
// set runnable condition to false
x = 0;
// remove the callbacks to the thread
removeCallbacks(contin);
invalidate();
return true;
default :
return super.onTouchEvent(event);
}
}
public boolean cont = false;
// sets input to continuous
public void set_continuous(boolean b) { cont = b; }
public Runnable contin = new Runnable()
{
@Override
public void run() {
if(x != 0)
{
// do continuous operations here
postDelayed(this, 10);
}
}
};
A quick note however, make sure in your main activity that is calling this view removes the callbacks manually via the onPause method as follows
但是,请注意,请确保在调用此视图的主要活动中通过 onPause 方法手动删除回调,如下所示
@Override
protected void onPause() {
if(left.cont) left.removeCallbacks(left.contin);
if(right.cont) right.removeCallbacks(left.contin);
super.onPause();
}
That way if you pause and come back touch events aren't being handled twice and the view is free from it's thread's overhead.
这样,如果您暂停并返回触摸事件不会被处理两次,并且视图不受线程开销的影响。
** tested on Samsung Galaxy S3 with hardware acceleration on **
** 在三星 Galaxy S3 上测试,硬件加速**
回答by Paolo Moschini
All these answer are partially correct but they do not resolve in the right way the problem.
所有这些答案都是部分正确的,但它们并没有以正确的方式解决问题。
First of all, for everyone out there that decide to track when the event is ACTION_MOVE. Well that works only guess when? When user move his finger, so could if you decide to implement a custom thumb control is okay but for a normal custom button that's not the case.
首先,对于决定跟踪事件何时为 ACTION_MOVE 的每个人。嗯,这只能猜测什么时候?当用户移动他的手指时,如果您决定实现自定义拇指控件也可以,但对于普通的自定义按钮则不然。
Second, using a flag inside ACTION_DOWN and check it in ACTION_UP seems the logic way to do it, but as Clusterfux find out if you implement a while(!up_flag)
logic you get stuck into troubles ;)
其次,在 ACTION_DOWN 中使用一个标志并在 ACTION_UP 中检查它似乎是这样做的逻辑方法,但是当 Clusterfux 发现你是否实现了一个while(!up_flag)
逻辑时,你会陷入困境;)
So the proper way to do it is mentioned here:
所以这里提到了正确的方法:
Continuous "Action_DOWN" in Android
Just keep in mind that if the logic you're going to write during the continuous press has to modify the UI in some way, you have to do it from the main thread in all the other cases it's better use another thread.
请记住,如果您要在连续按下期间编写的逻辑必须以某种方式修改 UI,则您必须在所有其他情况下从主线程执行此操作,最好使用另一个线程。