我正在尝试基于我的应用程序实现导航抽屉模式。我从 这里下载了示例代码并运行它,90%的情况下抽屉正常工作,但有时在尝试打开抽屉时抽屉会被卡住。我有一种复制情况的方法,但并不总是有效。我的操作步骤如下:
1- 按原样运行示例代码。
2- 将手指放在左侧边缘以获取抽屉提示
3- 放开手指并在主片段上按下手指
4- 尝试像往常一样打开抽屉
有时无论您将手指向右滑动多少次以打开抽屉,抽屉始终会卡在提示模式上。有没有人遇到/修复这个问题?
我正在尝试基于我的应用程序实现导航抽屉模式。我从 这里下载了示例代码并运行它,90%的情况下抽屉正常工作,但有时在尝试打开抽屉时抽屉会被卡住。我有一种复制情况的方法,但并不总是有效。我的操作步骤如下:
1- 按原样运行示例代码。
2- 将手指放在左侧边缘以获取抽屉提示
3- 放开手指并在主片段上按下手指
4- 尝试像往常一样打开抽屉
有时无论您将手指向右滑动多少次以打开抽屉,抽屉始终会卡在提示模式上。有没有人遇到/修复这个问题?
我遇到了一个和你提到的类似的问题。我在一个相对布局 (FILL_PARENT
) 中放置了一个列表视图。每当列表视图中的内容较少,当我拖动列表视图外部的区域时,导航抽屉就会卡住。为相对布局设置 android:clickable="true"
可以解决这个问题。希望这可以帮到你。
clickable="true"
设置到你用于承载主要内容的任何布局中。 - mato为了澄清Viji的回答,如果您正在使用类似提供的导航抽屉示例的东西:
<!-- A DrawerLayout is intended to be used as the top-level content view using match_parent for both width and height to consume the full space available. -->
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- As the main content view, the view below consumes the entire
space available using match_parent in both dimensions. -->
<FrameLayout
android:id="@+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<!-- android:layout_gravity="start" tells DrawerLayout to treat
this as a sliding drawer on the left side for left-to-right
languages and on the right side for right-to-left languages.
The drawer is given a fixed width in dp and extends the full height of
the container. A solid background is used for contrast
with the content view. -->
<ListView
android:id="@+id/left_drawer"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:choiceMode="singleChoice"
android:divider="@android:color/transparent"
android:dividerHeight="0dp"
android:background="#111"/>
</android.support.v4.widget.DrawerLayout>
在FrameLayout中添加android:clickable="true"
似乎可以解决这个问题。
两种解决方案。
android:clickable
让我解释一下这个 bug 的原因。
DrawerLayout 有三种状态:STATE_IDLE、STATE_DRAGGING 和 STATE_SETTLING。
ACTION_DOWN-> onEdgeTouched will be triggered if it is on the edge, DrawerLayout will trigger peekDrawer after 120ms
PeekDrawer实际上会改变DrawerLayout的状态为STATE_SETTLING,然后让抽屉滚动到指定位置。然后将状态设置为IDLE。
ACTION_MOVE->
If the current state is DRAGGING, drag captureView
If the current state is not DRAGGING, it will try to execute tryCaptureViewForDrag to reset the state to DRAGGING.
And at the same time, it will also determine whether a new edge gesture is triggered (emphasis !!)
If a new edge gesture was dete, it will invoke onEdgeDragStared
and DrawerLayout will go to captureView to captrue the drawer
如何解决这个问题?
peekDrawer
peekDrawer
之前,触发onEdgeDragStarted事件让抽屉布局捕获抽屉,此时dragState将被设置为STATE_DRAGGING因此,解决方案就是停止peekDrawer
,实际上,抽屉布局已经解决了这个问题。
public boolean onInterceptTouchEvent(MotionEvent ev) {
switch (action) {
case MotionEvent.ACTION_MOVE: {
// If we cross the touch slop, don't perform the delayed peek for an edge touch.
if (mLeftDragger.checkTouchSlop(ViewDragHelper.DIRECTION_ALL)) {
mLeftCallback.removeCallbacks();
mRightCallback.removeCallbacks();
}
break;
}
}
return interceptForDrag || interceptForTap || hasPeekingDrawer() || mChildrenCanceledTouch;
}