我已按照教程 Navigation Drawer除了一个小故障之外,一切都像魅力一样。我会尽量解释清楚,如果还不清楚,我会尝试上传问题视频。
在尝试打开抽屉时会出现问题,并且仅在打开时才会出现,而且只是有时会发生,并非总是如此。那是当我开始打开它时,它会在打开约 4 毫米时出现故障并卡住,并且始终保持相同的距离。如果我向后移动手指,它就不会继续打开或关闭,当我松开时,它会关闭。
请注意:
- 我已在多台设备(Nexus 7、Nexus)和虚拟设备上尝试过,问题依然存在。
- Issue replicated using the example provided by Google. (Youtube Link)
- Issue presented with my app. (Youtube Link)
- 我设法在 Gmail 应用中复制了一次问题,但只复制了一次(我相信它使用相同的实现),但在我的应用和示例应用中出现的频率要高得多。
- 我注意到,如果您只需单击屏幕边缘,就会在抽屉打开的相同距离处发生故障,因为它在初始打开后卡住并且从不拖动。
任何指针将不胜感激。
最佳答案
我研究了DrawerLayout
的代码,发现下一个问题:
当我们触摸屏幕边缘时,会出现 drawer
的小部分(20*density px)(它使移动抽屉更容易)。它不会立即出现,而是在一定的时间间隔(160 毫秒)之后出现。通过postDelayed
实现。
drawer
可以处于以下几种状态:IDLE
、DRAGGING
和 SETTLING
。如果处于DRAGGING
状态,就不能再回到这个状态,指针和边一样(因为有一个条件:mEdgeDragsInProgress[pointerId] & edge)== edge
不允许拖动已经拖动的边缘)。
所以在某些情况下,当延迟 Runnable
正在执行时,抽屉已经移动到状态 DRAGGING
。此延迟操作打开 drawer
20*density px 并更改 drawer
的状态。所以 drawer
不能再移动了(因为它不能返回到 DRAGGING
状态)。
有一个取消延迟 Action 的代码(打开抽屉),但是这个代码在方法onInterceptTouchEvent
中,只调用了一次(因为它返回false
) .我认为这段代码应该在 onTouchEvent
方法中。
不幸的是,我没有找到任何方法来取消延迟事件(因为它有 private
修饰符,我无法得到它)。所以我只找到了一种方法:将 DrawerLayout
的源代码复制到我的项目中并进行这个小改动:复制
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;
}
从方法 onInterceptTouchEvent
到方法 onTouchEvent
。
关于java - 为什么 DrawerLayout 在打开时有时会出现故障?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17896052/