在ScrollView

时间:2015-05-20 04:07:39

标签: android

我在Android应用中传播触摸事件有困难。我有一个ScrollView,其中包含一个充当项目的视图。当您点击该项目时,我想处理一个onclick事件。这可以通过将setOnClickListener与项一起使用来完成。但我还需要拦截scrollview的ACTION_UP和ACTION_DOWN事件。我使用scrollview的setOnTouchListener。

未收到scrollview的ACTION_UP和ACTION_DOWN。然后我决定使用setOnTouchListener作为setOnClickListener的项目intead。这改善了事情。当您按下该项目时,项目的onTouchListener会被调用ACTION_DOWN。退出项目的onTouchListener时,我返回false。然后调用scrollview的onTouchListener并接收ACTION_DOWN。事情似乎很顺利。虽然为什么首先调用项目的onTouchListener而不是滚动视图,但这确实让我很困惑。退出scrollview的onTouchListener时,我返回false。现在,当我松开手指时,会调用scrollview的ACTION_UP并返回false。

此时我遇到的问题是永远不会调用项目的ACTION_UP。我必须尝试在onTouchListener中返回true / false的每个组合,但是我无法使ACTION_UP工作,或者如果我确实让它工作,那么scrollview的onTouchListener中的某些内容就不再有用了。

我也尝试在scrollview的onTouchHandler中添加dispatchTouchEvent,但发现我得到了无休止的递归调用。

有没有办法让滚动视图及其子项目接收ACTION_UP / ACTION_DOWN?

1 个答案:

答案 0 :(得分:0)

要让滚动视图中的项目响应onClick,但也知道用户何时向下或向上轻击手指,需要一些棘手的编码。这里的解决方案适用于API 15+。需要注意的关键是没有onTouchListener实际用于scrollview。而是使用OnSimpleGestureListener在项目上检测事件。但是,值得注意的是,OnSimpleGestureListener不存在onUp方法,即使onDown也是如此(如图所示)。要解决onUp,你必须测试onTouchEvent的返回值:

GestureDetector gestureDetector = new GestureDetector(context, new GestureDetectorListItem());

listItem.setOnTouchListener(this.onTouchArticleItem);

private View.OnTouchListener onTouchArticleItem = new View.OnTouchListener()
{
  @Override
  public boolean onTouch(View v, MotionEvent event)
  {
    try
    {

      boolean state = gestureDetector.onTouchEvent(event);

      if ((event.getAction() == android.view.MotionEvent.ACTION_UP) && !state)
      {
        // Handle up event here.
        return true;
      }
      else if ((event.getAction() == android.view.MotionEvent.ACTION_DOWN) && state)
      {
        // Handle down event here.
        return true;
      }
      else
        return state;


    }
    catch (Exception ex)
    {
      Logger.Log(context, ex.getMessage(), Log.ERROR);
      return false;
    }
  }
};


private class GestureDetectorListItem extends GestureDetector.SimpleOnGestureListener
{
  public boolean onSingleTapUp(MotionEvent e)
  {
    return true;
  }

  public void onLongPress(MotionEvent e)
  {
  }

  public boolean onDoubleTap(MotionEvent e)
  {
    return false;
  }

  public boolean onDoubleTapEvent(MotionEvent e)
  {
    return false;
  }

  public boolean onSingleTapConfirmed(MotionEvent e)
  {
    return false;

  }

  public void onShowPress(MotionEvent e)
  {
  }

  public boolean onDown(MotionEvent e)
  {
    return true;
  }


  public boolean onScroll(MotionEvent e1, MotionEvent e2, final float distanceX, float distanceY)
  {
    return super.onScroll(e1, e2, distanceX, distanceY);
  }

  @Override
  public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY)
  {
    return super.onFling(e1, e2, velocityX, velocityY);
  }
}

我在这个解决方案中看到的唯一问题是滚动视图中滚动的项目太少。如果项目太少而用户按下除项目之外的滚动视图上的某个位置,则不会检测到上/下事件。这对您的应用程序是否重要是您必须决定的事情。如果需要,则可能还需要包含用于scrollview的onTouchListener。