Why does DrawerLayout sometimes glitch upon opening?

后端 未结 2 996
慢半拍i
慢半拍i 2020-12-04 11:43

I have followed the tutorial Navigation Drawer and everything works like a charm except for a small glitch. I\'ll try to explain it as much as possible, and if it still isn\

相关标签:
2条回答
  • 2020-12-04 11:55

    There is no error in drawerlayout file. Just add a ScrollView as the parent or root view to the content.xml(setcontentview file) file and tools:context=".MainActivity"

    0 讨论(0)
  • 2020-12-04 12:13

    I researched the code of DrawerLayout and found the next issue: When we touch the edge of screen there appears small (20*density px) part of the drawer (it makes moving drawer easier). It doesn't appears immediatly, but after a certain interval (160 ms) of time. It is realized by postDelayed.

    The drawer can be in several states: IDLE, DRAGGING and SETTLING. If it was in the DRAGGING state, it cannot return to this state anymore with the same pointer and edge (because there is a condition: mEdgeDragsInProgress[pointerId] & edge) == edge which doesn't allow to drag the edge which have been dragging already).

    So in some cases the drawer have moved to the state DRAGGING already when delayed Runnable is executing. This delayed action opens drawer for 20*density px and change state of drawer. So drawer cannot be moved anymore (because it cannot return to the state DRAGGING).

    There is a code for cancelling delayed action (which opens drawer), but this code in the method onInterceptTouchEvent, which is called only once (because it returns false). I think this code should be in the method onTouchEvent.

    Unfortunatly I didn't find any way to cancel delayed event (because it has private modifier and I can't get it). So only one way I found: copy the source code of DrawerLayout to my project and make this small change: copy

    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;
            }
    

    from the method onInterceptTouchEvent to the method onTouchEvent.

    0 讨论(0)
提交回复
热议问题