更新:请参阅赏金以了解扩展问题。
我在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
上的按钮,其中一些打开一个新的活动(然后回到相同的位置),这是“互动“与”。
答案 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.
}
答案 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
这样做的好处是不会使用e2
或Event
,这会带给我们......
<强>第三强>
如您所知,问题在于您与列表视图进行了互动。此时,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
方法。