2013-07-09 59 views
4

如果这些手势是在某些特定的ListView行中制作的,我需要停止ListView以对用户手势做出响应 - 如何做?目标ListView的行视图设置了onTouchListener,由于ListView向上/向下滚动,我无法识别滑动/翻转。所以如果我将手指向上或向下移动 - ListView会截取并在相应的方向上滚动。所以我需要以某种方式来对它进行规则化,就像Y坐标超过一定数量一样 - 让ListView滚动,如果不是 - 识别手势为一次/滑动。 OnTouchListener是如何防止ListView滚动时触摸/滑动/扔它的行?

private int SWIPE_MIN_DISTANCE = 1; 
private int SWIPE_MAX_OFF_PATH = 300; 

final OnTouchListener flingSwipeListener = new OnTouchListener() { 
    float touchX; 
    float touchY; 
    @Override 
    public boolean onTouch(final View view, final MotionEvent event) { 
     if (event.getAction() == MotionEvent.ACTION_DOWN) 
     { 
      touchX = event.getX(); 
      touchY = event.getY(); 
     } 
     else if (event.getAction() == MotionEvent.ACTION_UP) 
     {     
     if (Math.abs(touchY - event.getY()) > SWIPE_MAX_OFF_PATH) 
        return false; 
      // right to left swipe 
      else if (touchX - event.getX() > SWIPE_MIN_DISTANCE){ 
        Log.i("flingSwipe","right to left swipe"); 
      } 
      // left to right swipe 
      else if (event.getX() - touchX > SWIPE_MIN_DISTANCE){ 
        Log.i("flingSwipe","left to right swipe"); 
      } 
     } 
     return true; 

    } 
}; 

此onTouchListner被设置为一个特定的行。我需要冻结ListView,而onTouchListener识别手势,但如果失败,我需要将MotionEvent发送到ListView。

回答

0

如果您需要在特定行上禁用触摸侦听器。比这很简单。

在所需的列表行上设置标签。在getview list适配器类中。

e.g:

ABCList extends ArrayAdapter<String> { 
     public MyCustomAdapter(Context context, int textViewResourceId, 
       String[] objects) { 
      super(context, textViewResourceId, objects); 
     } 

     @Override 
     public View getView(int position, View convertView, ViewGroup parent) { 

      View row = inflater.inflate(R.layout.history_list_item, parent, 
        false); 

      if(position == YOUR_DESIRED_ROW) 
          row.setTag("disableThisRow") 

      return row; 
     } 


    } 

然后编辑触摸听者这样。

final OnTouchListener flingSwipeListener = new OnTouchListener() { 
    float touchX; 
    float touchY; 
    @Override 
    public boolean onTouch(final View view, final MotionEvent event) { 
     String isRow=view.getTag(); 
     if(isRow.equals("disableThisRow"))return false; 

     if (event.getAction() == MotionEvent.ACTION_DOWN) 
     { 
      touchX = event.getX(); 
      touchY = event.getY(); 
     } 
     else if (event.getAction() == MotionEvent.ACTION_UP) 
     {     
     if (Math.abs(touchY - event.getY()) > SWIPE_MAX_OFF_PATH) 
        return false; 
      // right to left swipe 
      else if (touchX - event.getX() > SWIPE_MIN_DISTANCE){ 
        Log.i("flingSwipe","right to left swipe"); 
      } 
      // left to right swipe 
      else if (event.getX() - touchX > SWIPE_MIN_DISTANCE){ 
        Log.i("flingSwipe","left to right swipe"); 
      } 
     } 

     return true; 

    } 
}; 

这将禁用触摸disired list item ..希望这有助于。 或者如果你比这更多的手势听众也会与此类似。 希望它有助于

+0

不,我需要禁用ListView的内置触摸检测器/识别器,如果我滑动它的特定行。因为我需要冻结ListView而滑动它的行。 – Stan

+0

好的,只要用户触摸到你想要的行,你必须做的事情就是。禁用列表滚动。不是吗?当用户触摸其他行时,启用默认滚动。 – shujatAli

+0

是的,就像我在我的问题中的代码下面添加的一样。我需要冻结ListView,而用户在特定的ListView行中进行手势操作。所有其他ListView的行必须照常运行。此外,当我检测到我的OnTouchListener中的Y轴过大时,我需要将手势传递给ListView,以使用户能够滚动ListView,即使通过我的特殊行。 – Stan

1

如果要禁用当检测到任何水平滚动(刷卡),然后采用如下方案的ListView垂直滚动 - 在自定义的ListView类覆盖的onTouchEvent和替换操作MotionEvent.ACTION_MOVE到MotionEvent.ACTION_CANCEL:

public class ListView2 extends ListView 
{ 
    private enum ScrollDirection 
    { 
     Horizontal, 
     Vertical 
    } 

    private final int touchSlop; 

    private float downX = 0; 
    private float downY = 0; 

    private ScrollDirection scrollDirection; 

    public ListView2(Context context, AttributeSet attrs) 
    { 
     super(context, attrs); 
     touchSlop = ViewConfiguration.get(context).getScaledTouchSlop(); 
    } 

    @Override 
    public boolean onTouchEvent(MotionEvent ev) 
    { 
     switch (ev.getActionMasked()) 
     { 
      case MotionEvent.ACTION_MOVE: 
       if (scrollDirection == null) 
       { 
        if (Math.abs(downX - ev.getX()) > touchSlop) scrollDirection = ScrollDirection.Horizontal; 
        else if (Math.abs(downY - ev.getY()) > touchSlop) scrollDirection = ScrollDirection.Vertical; 
       } 
       if (scrollDirection == ScrollDirection.Horizontal) ev.setAction(MotionEvent.ACTION_CANCEL); 
       break; 

      case MotionEvent.ACTION_DOWN: 
       scrollDirection = null; 
       downX = ev.getX(); 
       downY = ev.getY(); 
       break; 

     } 
     return super.onTouchEvent(ev); 
    } 
} 

当然,您可以使检查逻辑是否禁用垂直滚动更复杂。