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.Rect;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
|
import android.util.MathUtils;
|
||||||
import android.util.SparseBooleanArray;
|
import android.util.SparseBooleanArray;
|
||||||
import android.view.FocusFinder;
|
import android.view.FocusFinder;
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
@@ -1490,6 +1491,10 @@ public class ListView extends AbsListView {
|
|||||||
|
|
||||||
View focusLayoutRestoreView = null;
|
View focusLayoutRestoreView = null;
|
||||||
|
|
||||||
|
AccessibilityNodeInfo accessibilityFocusLayoutRestoreNode = null;
|
||||||
|
View accessibilityFocusLayoutRestoreView = null;
|
||||||
|
int accessibilityFocusPosition = INVALID_POSITION;
|
||||||
|
|
||||||
// Remember stuff we will need down below
|
// Remember stuff we will need down below
|
||||||
switch (mLayoutMode) {
|
switch (mLayoutMode) {
|
||||||
case LAYOUT_SET_SELECTION:
|
case LAYOUT_SET_SELECTION:
|
||||||
@@ -1584,6 +1589,25 @@ public class ListView extends AbsListView {
|
|||||||
requestFocus();
|
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
|
// Clear out old views
|
||||||
detachAllViewsFromParent();
|
detachAllViewsFromParent();
|
||||||
recycleBin.removeSkippedScrap();
|
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
|
// tell focus view we are done mucking with it, if it is still in
|
||||||
// our view hierarchy.
|
// our view hierarchy.
|
||||||
if (focusLayoutRestoreView != null
|
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.
|
* @param child a direct child of this list.
|
||||||
* @return Whether child is a header or footer view.
|
* @return Whether child is a header or footer view.
|
||||||
|
|||||||
Reference in New Issue
Block a user