Android:自定义视图onClickEvent with X& Y位置

时间:2010-05-13 12:07:52

标签: android view user-input

我有一个自定义视图,我想获得用户点击的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

6 个答案:

答案 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);
}