手势操作者不执行一致性

时间:2013-06-06 20:42:14

标签: android listview gestures

更新:请参阅赏金以了解扩展问题。

我在GestureDetector上设置了ListView。 ListView是一个完整的片段,它来自窗口的一侧并部分覆盖另一个片段。我想让用户能够靠近它(即Wunderlist是右侧这个功能的一个很好的例子)。

这是我的设置:

    gestureListener = new View.OnTouchListener() {
        public boolean onTouch(View v, MotionEvent event) {

            if (gestureDetector.onTouchEvent(event)) {
                return true;
            }

            return false;
        }
    };
    listView.setOnTouchListener(gestureListener); 

听众本身:

public class GestureListener extends SimpleOnGestureListener {

        private static final int SWIPE_MIN_DISTANCE = 180;
        private static final int SWIPE_THRESHOLD_VELOCITY = 50;

        @Override
        public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
                float velocityY) {

            try {
                if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE
                        && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {

                    FragmentManager fma = getActivity()
                            .getSupportFragmentManager();



                    FragmentManager fm = getFragmentManager();
                    FragmentTransaction t = fm.beginTransaction();

                    SherlockListFragment mFrag = new RateReviewFragment();

                    t.add(R.id.main_frag, mFrag);
                    t.setCustomAnimations(R.anim.animation_enter,
                            R.anim.animation_leave);
                    t.remove(mFrag);
                    t.commit();

                }
                return false;
            } catch (Exception e) {

            }
            return false;
        }





        @Override
        public void onLongPress(MotionEvent e) {

            // edited out; this opens up a context menu
        }

    }

有时候,当ListView滚动到底部(或列表滚动因列表行点击而中断)时,GestureListener只会停止...收听。刷卡不起作用。您必须滚动到顶部才能再次使用它。

如果有人能帮我隔离这些问题,我将不胜感激!

更新:只剩下一个问题,“听众停止聆听”

更新二:我可能已经弄明白这是什么原因;只是不知道修复:

我在记录行动后发现了一些事情;我在列表中得到的越低(我与它的互动越多),测量结果就不一致了。例如,如果我将手指向左和向右移动一厘米 - 在列表的最顶部,它会说我移动了,例如,200像素。但是当我遇到上述问题时,对于 SAME 1厘米的距离,它要低得多,可能是50。因此窗口不会关闭,因为它不符合if条件。

Sidenote :我已经多次说过,问题出在“与列表交互”时。这意味着:如果我快速从上到下滚动;没有任何问题;但是,如果我慢慢地向下工作,也许点击屏幕,滚动打开和关闭,点击listView上的按钮,其中一些打开一个新的活动(然后回到相同的位置),这是“互动“与”。

5 个答案:

答案 0 :(得分:3)

试试这个,

    gestureDetector = new GestureDetector(getActivity(),
            new GestureListener());
    View.OnTouchListener gestureListener = new View.OnTouchListener() {
        public boolean onTouch(View v, MotionEvent event) {
           listView.onTouchEvent(event);
           gestureDetector.onTouchEvent(event);

            return true;
        }
    };
    listView.setOnTouchListener(gestureListener);

并进行以下更改

@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2,
                float distanceX, float distanceY) {
  return true;
}

修改 我看到了app wunderlist,如果你想模拟那个功能试试这个方法,

使用onInterceptTouch进行根布局(其中listView是其子代),在此方法中,您必须检查用户是否刷过以下内容,

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
  if (ev.getAction() == MotionEvent.ACTION_MOVE) {
    if(/* Check your condition here */) { 
      // User has swiped 
      return true;
    }
  }

  return false; // return false so that the event will be passed to child views.
}

了解更多信息Android onInterceptTouchEvent

答案 1 :(得分:2)

以这种方式更改onTouch:

@Override
public boolean onTouch(View arg0, MotionEvent arg1) {
     boolean consumed = gestureDetector.onTouchEvent(event);
     if (event.getAction() == MotionEvent.ACTION_MOVE) {
                return false;
     }

    return consumed;
}

答案 2 :(得分:1)

不确定这是否会有所帮助,因为上帝知道幕后发生了所有这些碎片问题但是试试这个:

在调用 onTouch 之后,在返回false之前检查 gestureDetector 是否仍处于活动状态(非空),(通过向listview类发送回调或其他内容)如果不是创建它的新实例并再次调用

listView.setOnTouchListener(gestureListener); 

答案 3 :(得分:1)

<强>第一

我注意到,在您的手势监听器中,您会在true中返回onDown。如果我已正确理解您的问题,您将离开ListView的点击和垂直滑动事件,因此您只对代码中的水平滑动事件感兴趣。

为什么不删除您不感兴趣的所有功能,从而将您不感兴趣的所有内容留给ListView?如果您必须拥有它们,请至少返回false,这是默认设置(请参阅here)。

另外,AbsListView ListView(change in X) >> (change in Y) 的父级)的code显示了一个非常复杂的状态系统,用于处理水龙头和滑动,所以它最好尽可能不受影响在我看来

<强>其次

鉴于您最近的观察结果,关键是要考虑X和Y位移之间的比率而不是滑动的绝对大小。虽然我无法解释所报告的滑动尺寸的变化,但我们真正感兴趣的是一种主要是水平的运动,即:

if ((velocityY == 0.0f) || (Math.abs(velocityX/velocityY) > 3.0f) {
    // The movement is predominantly horizontal
    // Put other checks here (like direction and so on)
    // Then do the stuff
}

这可以通过以下方式实现:

e1

这样做的好处是不会使用e2Event,这会带给我们......

<强>第三

如您所知,问题在于您与列表视图进行了互动。此时,int numPointers = e1.getPointerCount(); for (int pointerIndex1 = 0; pointerIndex1 < numPointers; pointerIndex1++) { int pointerId = e1.getPointerId(pointerIndex1); // find index for pointerId in e2. float deltaX = e2.getX(pointerIndex2) - e1.getX(pointerIndex1); // and so on } 中可能会报告多个指针。不保证它们返回的默认X和Y信息与任何特定指针事件有关。如果你想进行涉及X和Y的计算,可能需要检查你是否正在比较来自同一指针事件的信息,使用类似的东西:

{{1}}

答案 4 :(得分:0)

尽量让OnTouchListener像这样:

View.OnTouchListener gestureListener = new View.OnTouchListener() {
    public boolean onTouch(View v, MotionEvent event) {
    gestureDetector.onTouchEvent(event);
        return true;
    }
};

然后 - 您总是在false中返回onFling()。在true子句中返回try/catch。并尝试将相同的数据传递给onScroll内的else子句中的onFling方法。