我有一个自定义视图,我想获得用户点击的X和Y坐标。我发现只能从onTouchEvent获取坐标,如果我有onTouchEvent,onClickEvent将不会触发。不幸的是,当用户拖动屏幕并点击时,onTouchEventfires。
我试图区分这两者,但是当我拖动时我仍然会触发代码:
public boolean onTouchEvent(MotionEvent event) {
int action = event.getAction();
if (action == MotionEvent.ACTION_DOWN) {
//fires on drag and click
我已经看过this但是正如我上面提到的,我不认为那里的解决方案会有效,因为我无法同时处理onClick和onTouch事件。也许我在这方面做错了,是否有正常的方法来处理捕获自定义事件的用户输入?我应该能够同时使用onClick和onTouch事件吗?
谢谢,Martyn
答案 0 :(得分:3)
你在onTouchEvent结束时返回了什么?根据文档返回true表示“事件已经完全处理,不做任何事情”,而返回false意味着系统将继续处理。我没有根据您的具体情况对此进行测试,但这表明返回false可能有效。这将使系统继续处理触摸/点击并将其发送到下面的“下面的视图”。
如果这不起作用,那么我还不能想到比做类似于Rich建议的更好的解决方案。你可以做一些事情,比如在ACTION_DOWN获得时间,然后在ACTION_UP上,比较已经过去的时间。如果它小于100毫秒,则应将其解释为单击。然后,您可以触发想要放入点击侦听器的任何代码。
例如,以下是编码方式:
long touchDownTime; // This has to be a class field so that it persists
// between calls to onTouchEvent
public boolean onTouchEvent(MotioNEvent event){
boolean handled = false;
int action = event.getAction();
switch (action){
case MotionEvent.ACTION_DOWN:
touchDownTime = SystemClock.elapsedRealtime();
break;
case MotionEvent.ACTION_UP:
if (SystemClock.elapsedRealtime() - touchDownTime <= 100){
int x = event.getX(); //or event.getRawX();
int y = event.getY();
performYourClick(x, y);
handled = true;
}
break;
}
return handled;
}
注意:我实际上没有测试该代码,所以我可能会犯一些语法错误。总体思路应该还是可以的。
答案 1 :(得分:2)
现在,我不知道onTouchEvent短路onClick,我不知道你是否需要将android:clickable
设置为true(或setClickable(true)
)。但是,如果你不能干净利落地工作,你可以在onTouchEvent中使用布尔值来模仿点击检测,如果所有其他方法都失败的话。在ACTION_DOWN中,将其设置为true(isClicking或类似的东西),在ACTION_MOVE中将其设置为false(因为用户拖动因此不点击),然后在ACTION_UP中可以测试它。如果这是真的,这意味着用户已按下但未拖动。这很hacky,但如果你不能onClick工作它基本上是一样的。
答案 2 :(得分:0)
仅供参考,在我的测试中,无论onTouch是返回true还是false,onTouch都会覆盖视图的onClick。
-Frink
答案 3 :(得分:0)
我能解决这个问题
我创建了一个Custom View公共类QuestionBuilderView extends View
在布局文件
中 < com.example.android.view.QuestionBuilderView
android:id="@+id/questionbuilderview"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
在主Activity中尝试调用自定义视图并将Onclick / On Touch事件侦听器设置为视图
View questionBuilder = findViewById(R.id.questionbuilderview);
questionBuilder.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent event) {
// TODO Auto-generated method stub
float touched_x = event.getX();
float touched_y = event.getY();
Toast.makeText(getApplicationContext(), " "+touched_x +","+touched_y, Toast.LENGTH_LONG).show();
// int action = event.getAction();
return true;
}
答案 4 :(得分:0)
我认为你必须调用super.onTouchEvent(event),因为在那个方法中,检测到了点击。
答案 5 :(得分:0)
您应该使用GestureDetector
。子类GestureDetector.SimpleOnGestureListener
并覆盖onDown(MotionEvent event)
方法以返回true。然后覆盖onSingleTapConfirmed
。将侦听器传递给GestureDetector
构造函数。然后使用该侦听器作为参数调用setOnDoubleTapListener
:
// in your view class constructor
GestureDetector.SimpleOnGestureListener listener = new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onDown(MotionEvent e) {
return true;
}
@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
// do whatever you want
return true;
}
};
mDetector = new GestureDetector(getContext(), listener);
mDetector.setOnDoubleTapListener(listener);
然后,您可以将MotionEvent
传递给探测器:
@Override
public boolean onTouchEvent(MotionEvent event) {
return mDetector.onTouchEvent(event);
}