am 390a06b8: Merge "Restore accessibility focus after ListView layout." into jb-mr1-dev
* commit '390a06b882f555b73f466985067d71d856f55f2f': Restore accessibility focus after ListView layout.
This commit is contained in:
@@ -29,6 +29,7 @@ import android.graphics.PixelFormat;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.MathUtils;
|
||||
import android.util.SparseBooleanArray;
|
||||
import android.view.FocusFinder;
|
||||
import android.view.KeyEvent;
|
||||
@@ -1490,6 +1491,10 @@ public class ListView extends AbsListView {
|
||||
|
||||
View focusLayoutRestoreView = null;
|
||||
|
||||
AccessibilityNodeInfo accessibilityFocusLayoutRestoreNode = null;
|
||||
View accessibilityFocusLayoutRestoreView = null;
|
||||
int accessibilityFocusPosition = INVALID_POSITION;
|
||||
|
||||
// Remember stuff we will need down below
|
||||
switch (mLayoutMode) {
|
||||
case LAYOUT_SET_SELECTION:
|
||||
@@ -1584,6 +1589,25 @@ public class ListView extends AbsListView {
|
||||
requestFocus();
|
||||
}
|
||||
|
||||
// Remember which child, if any, had accessibility focus.
|
||||
final View accessFocusedView = getViewRootImpl().getAccessibilityFocusedHost();
|
||||
if (accessFocusedView != null) {
|
||||
final View accessFocusedChild = findAccessibilityFocusedChild(accessFocusedView);
|
||||
if (accessFocusedChild != null) {
|
||||
if (!dataChanged || isDirectChildHeaderOrFooter(accessFocusedChild)) {
|
||||
// If the views won't be changing, try to maintain focus
|
||||
// on the current view host and (if applicable) its
|
||||
// virtual view.
|
||||
accessibilityFocusLayoutRestoreView = accessFocusedView;
|
||||
accessibilityFocusLayoutRestoreNode = getViewRootImpl()
|
||||
.getAccessibilityFocusedVirtualView();
|
||||
} else {
|
||||
// Otherwise, try to maintain focus at the same position.
|
||||
accessibilityFocusPosition = getPositionForView(accessFocusedChild);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Clear out old views
|
||||
detachAllViewsFromParent();
|
||||
recycleBin.removeSkippedScrap();
|
||||
@@ -1682,6 +1706,22 @@ public class ListView extends AbsListView {
|
||||
}
|
||||
}
|
||||
|
||||
// Attempt to restore accessibility focus.
|
||||
if (accessibilityFocusLayoutRestoreNode != null) {
|
||||
accessibilityFocusLayoutRestoreNode.performAction(
|
||||
AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS);
|
||||
} else if (accessibilityFocusLayoutRestoreView != null) {
|
||||
accessibilityFocusLayoutRestoreView.requestAccessibilityFocus();
|
||||
} else if (accessibilityFocusPosition != INVALID_POSITION) {
|
||||
// Bound the position within the visible children.
|
||||
final int position = MathUtils.constrain(
|
||||
(accessibilityFocusPosition - mFirstPosition), 0, (getChildCount() - 1));
|
||||
final View restoreView = getChildAt(position);
|
||||
if (restoreView != null) {
|
||||
restoreView.requestAccessibilityFocus();
|
||||
}
|
||||
}
|
||||
|
||||
// tell focus view we are done mucking with it, if it is still in
|
||||
// our view hierarchy.
|
||||
if (focusLayoutRestoreView != null
|
||||
@@ -1712,6 +1752,22 @@ public class ListView extends AbsListView {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param focusedView the view that has accessibility focus.
|
||||
* @return the direct child that contains accessibility focus.
|
||||
*/
|
||||
private View findAccessibilityFocusedChild(View focusedView) {
|
||||
ViewParent viewParent = focusedView.getParent();
|
||||
while ((viewParent instanceof View) && (viewParent != this)) {
|
||||
focusedView = (View) viewParent;
|
||||
viewParent = viewParent.getParent();
|
||||
}
|
||||
if (!(viewParent instanceof View)) {
|
||||
return null;
|
||||
}
|
||||
return focusedView;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param child a direct child of this list.
|
||||
* @return Whether child is a header or footer view.
|
||||
|
||||
Reference in New Issue
Block a user