我想使用工作滚动和单击事件设置以下布局:
我的 CustomSlidingDrawer.xml:
<com.project.util.CustomSliderDrawer
android:id="@+id/slidingDrawerHotelList"
android:layout_width="0dp"
android:layout_height="match_parent"
android:allowSingleTap="false"
android:content="@+id/content"
android:handle="@+id/handle"
android:orientation="horizontal" >
<RelativeLayout
android:id="@+id/handle"
android:layout_width="0dp"
android:layout_height="match_parent" >
<RelativeLayout
android:id="@+id/content"
android:layout_width="0dp"
android:layout_height="0dp" >
</RelativeLayout>
</RelativeLayout>
</com.project.util.CustomSliderDrawer>
元素的宽度在运行时设置。这里不得不提一下,我真正的内容是在Drawer的handle中,内容只是一个dummy。我这样做是因为我无法隐藏手柄。或者让它不可见。所以,如果我想刷入,我触摸手柄(我的内容)并拉动。在 SlidingDrawer 中,句柄是包含 CustomListView 的片段的占位符。现在起作用了:我可以滚动 SlidingDrawer。
我想获得什么行为:在 SlidingDrawer 上,在 X 轴方向(垂直滑动)检测到 MotionEvents。如果检测到 Y 轴方向的 MotionEvent,则事件应该转到我的 CustomListView。甚至 onClicks 也应该传递到 ListView。
我试过的:我读了很多:这里,这个页面和这个 然后我尝试将所有导航控件放在主要活动中,这在我眼中真正有意义:
主要活动:
slidingDrawer.setOnTouchListener(new OnTouchListener() {
int downX, downY;
@Override
public boolean onTouch(View v, MotionEvent event) {
int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
downX = (int) event.getX();
downY = (int) event.getY();
break;
case MotionEvent.ACTION_MOVE:
int deltaX = downX - (int) event.getX();
int deltaY = downY - (int) event.getY();
if (Math.abs(deltaX) > Math.abs(deltaY)) {
Log.i(TAG, "scrollX direction");
isVerticalSwipe = true;
} else {
Log.i(TAG, "scrollY direction");
isVerticalSwipe = false;
}
break;
case MotionEvent.ACTION_UP:
break;
}
return false;
}
});
但是当我在这里尝试将“isVerticalSwipe”作为本地返回时,SlidingDrawer 不再正常工作。:-( 第二次尝试是拦截自定义滑动抽屉中的触摸事件:
自定义滑动抽屉:
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
switch (ev.getAction()) {
case MotionEvent.ACTION_DOWN:
Log.i(TAG, "onInterceptTouchEvent ACTION_DOWN");
xDistance = yDistance = 0f;
downX = (int) ev.getX();
downY = (int) ev.getY();
break;
case MotionEvent.ACTION_MOVE:
Log.i(TAG, "onInterceptTouchEvent ACTION_MOVE");
final int curX = (int) ev.getX();
final int curY = (int) ev.getY();
xDistance += Math.abs(curX - downX);
yDistance += Math.abs(curY - downY);
downX = curX;
downY = curY;
if (xDistance > yDistance)
return false;
}
return super.onInterceptTouchEvent(ev);
}
这里只发生 DOWN 事件,永远不会到达 MOVE 事件。我也用“dispatchTouchEvent”做了一些尝试,但没有成功。
我知道,这些事件将通过我的观点的“层”——从上到下。所以很高兴知道,我如何在我的 CustomSlidingDrawer (= 顶视图)中实现上面第一个链接的构造,当检测到垂直滑动时保持并处理它,如果它是水平滑动,那么请将它发送到CustomListView 并在那里执行事件。
感谢任何帮助、想法、想法或代码片段。:) 谢谢!
[编辑]
我已经取得了一些进展。我现在将我的事件从 SlidingDrawer 到我的 ListView。我可以滚动并单击列表 - 效果很好。但不幸的是,我的 SlidingDrawer 不再显示任何反应。这些行在我的自定义 SlidingDrawer 中:
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
gestureDetector = new GestureDetector(new MyGestureDetector());
if (gestureDetector.onTouchEvent(event)) {
return true;
} else if (event.getAction() == MotionEvent.ACTION_UP
|| event.getAction() == MotionEvent.ACTION_CANCEL) {
return false;
} else {
Log.i(TAG, "gestureDetector returned false");
return false;
}
}
class MyGestureDetector extends SimpleOnGestureListener {
@Override
public boolean onDown(MotionEvent e) {
Log.i(TAG, "onDown");
downX = (int) e.getX();
downY = (int) e.getY();
return false;
}
@Override
public boolean onScroll(MotionEvent e1, MotionEvent e2,
float distanceX, float distanceY) {
float deltaX = downX - e2.getX();
float deltaY = downY - e2.getY();
if (Math.abs(deltaX) > Math.abs(deltaY)) {
Log.i(TAG, "scrollX direction");
return true;
} else {
Log.i(TAG, "scrollY direction");
return false;
}
}
}
我真的不明白为什么它不起作用,如果在 x 方向上滑动,那么我的抽屉应该处理手势,因为我返回 true。相反,每个事件都被转发到 ListView。我试图在“onInterceptTouchEvent”之前运行“dispatchTouchEvent”,但没有成功。也许有更好的解决方案,而不是使用 SlidingDrawer 通过手指移动视图?