安卓系统:如何制作一个位于SlidingDrawer中的片段中的CustomListView滚动并可点击



我想用工作滚动和点击事件设置以下布局:

我的自定义SlidingDrawer.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>

元素的宽度是在运行时设置的。在这里我必须提到,我真正的内容是在抽屉的把手上,而内容只是一个假人。我这样做是因为我无法隐藏把手。或者让它隐形。所以,如果我想刷进去,我会触摸把手(我的内容)并拉动。在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方向上滑动,那么我的抽屉应该处理这个手势,bc我返回true。相反,每个事件都被转发到ListView。我尝试在"onInterceptTouchEvent"之前运行"dispatchTouchEvent",但没有成功。也许有更好的解决方案,而不是使用SlidingDrawer通过手指移动视图?

好吧,在流了很多眼泪、汗水和鲜血之后,我终于找到了一个适合我的解决方案:我不再使用SlidingDrawer,而是通过更改LayoutParams来移动我的布局。通过"dispatchTouchEvent",我可以访问我的列表。

@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
if (mGestureDetector.onTouchEvent(ev)) {
return true;
}
if (ev.getAction() == MotionEvent.ACTION_UP) {
Log.i(TAG, "ACTION_UP");
Log.i(TAG, "getLeft: " + getLeft());
if (getLeft() < 280) {
// run ani to left
} else {
// run ani to right
}
}
return super.dispatchTouchEvent(ev);
}

在我的手势检测器中,我在重写的onScroll函数中处理布局转换。如果有人需要探测器,请不要犹豫,我会分享的。

最新更新