带有onClick和onLongClick的Android onTouch

时间:2011-09-12 12:07:36

标签: android click touch

我有一个自定义视图,就像一个按钮。我想在用户按下它时更改背景,当用户将手指移到外面或释放它时将背景恢复为原始状态,我还想处理onClick / onLongClick事件。问题是onTouch要求我为ACTION_DOWN返回true,否则它不会向我发送ACTION_UP事件。但如果我返回true,onClick监听器将无效。

我以为我通过在onTouch中返回false并注册onClick来解决它 - 它在某种程度上有效,但是有点反对文档。我刚收到用户的消息,告诉我他无法长按此按钮,所以我想知道这里有什么问题。

当前代码的一部分:

public boolean onTouch(View v, MotionEvent evt)
{
  switch (evt.getAction())
  {
    case MotionEvent.ACTION_DOWN:
    {
      setSelection(true); // it just change the background
      break;
    }

    case MotionEvent.ACTION_CANCEL:
    case MotionEvent.ACTION_UP:
    case MotionEvent.ACTION_OUTSIDE:
    {
      setSelection(false); // it just change the background
      break;
    }
  }

  return false;
}

public void onClick(View v)
{
  // some other code here
}

public boolean onLongClick(View view)
  {
    // just showing a Toast here
    return false;
  }


// somewhere else in code
setOnTouchListener(this);
setOnClickListener(this);
setOnLongClickListener(this);

如何让它们正确地协同工作?

提前致谢

1 个答案:

答案 0 :(得分:13)

onClick& onLongClick实际上是从View.onTouchEvent发送的。

如果您覆盖View.onTouchEvent或通过View.OnTouchListener设置某些特定setOnTouchListener, 你必须关心它。

所以你的代码应该是这样的:

public boolean onTouch(View v, MotionEvent evt)
{
  // to dispatch click / long click event,
  // you must pass the event to it's default callback View.onTouchEvent
  boolean defaultResult = v.onTouchEvent(evt);

  switch (evt.getAction())
  {
    case MotionEvent.ACTION_DOWN:
    {
      setSelection(true); // just changing the background
      break;
    }
    case MotionEvent.ACTION_CANCEL:
    case MotionEvent.ACTION_UP:
    case MotionEvent.ACTION_OUTSIDE:
    {
      setSelection(false); // just changing the background
      break;
    }
    default:
      return defaultResult;
  }

  // if you reach here, you have consumed the event
  return true;
}