Prevent foocus from escaping open navigation drawer
When contents of NewPipe navigation drawer change, NavigationMenuView (which is actually a RecyclerView) removes and re-adds all its adapter children, which leads to temporary loss of focus on currently focused drawer child. This situation was not anticipated by developers of original support library DrawerLayout: while NavigationMenuView itself is able to keep focus from escaping via onRequestFocusInDescendants(), the implementation of that method in DrawerLayout does not pass focus to previously focused View. In fact it does not pass focus correctly at all because the AOSP implementation of that method does not call addFocusables() and simply focuses the first available VISIBLE View, without regard to state of drawers.
This commit is contained in:
parent
6aca344bf7
commit
381b491845
1 changed files with 29 additions and 0 deletions
|
@ -19,6 +19,7 @@ package org.schabi.newpipe.views;
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.graphics.Rect;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.view.Gravity;
|
import android.view.Gravity;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
@ -44,6 +45,34 @@ public final class FocusAwareDrawerLayout extends DrawerLayout {
|
||||||
super(context, attrs, defStyle);
|
super(context, attrs, defStyle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean onRequestFocusInDescendants(int direction, Rect previouslyFocusedRect) {
|
||||||
|
// SDK implementation of this method picks whatever visible View takes the focus first without regard to addFocusables
|
||||||
|
// if the open drawer is temporarily empty, the focus escapes outside of it, which can be confusing
|
||||||
|
|
||||||
|
boolean hasOpenPanels = false;
|
||||||
|
|
||||||
|
for (int i = 0; i < getChildCount(); ++i) {
|
||||||
|
View child = getChildAt(i);
|
||||||
|
|
||||||
|
DrawerLayout.LayoutParams lp = (DrawerLayout.LayoutParams) child.getLayoutParams();
|
||||||
|
|
||||||
|
if (lp.gravity != 0 && isDrawerVisible(child)) {
|
||||||
|
hasOpenPanels = true;
|
||||||
|
|
||||||
|
if (child.requestFocus(direction, previouslyFocusedRect)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasOpenPanels) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.onRequestFocusInDescendants(direction, previouslyFocusedRect);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void addFocusables(ArrayList<View> views, int direction, int focusableMode) {
|
public void addFocusables(ArrayList<View> views, int direction, int focusableMode) {
|
||||||
boolean hasOpenPanels = false;
|
boolean hasOpenPanels = false;
|
||||||
|
|
Loading…
Reference in a new issue