1

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

我的 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 通过手指移动视图?

4

1 回答 1

0

好的,经过大量的泪水、汗水和鲜血,我终于找到了一个适合我的解决方案:我不再使用 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);
}

在我的 GestureDetector 中,我在覆盖的 onScroll 函数中处理布局转换。如果有人需要探测器,请不要犹豫,我会分享。

于 2012-10-17T15:00:11.930 回答