summaryrefslogtreecommitdiff
path: root/core/java/android/widget/GridView.java
diff options
context:
space:
mode:
Diffstat (limited to 'core/java/android/widget/GridView.java')
-rw-r--r--core/java/android/widget/GridView.java71
1 files changed, 43 insertions, 28 deletions
diff --git a/core/java/android/widget/GridView.java b/core/java/android/widget/GridView.java
index 67430028cbbb..4ed48ff08f90 100644
--- a/core/java/android/widget/GridView.java
+++ b/core/java/android/widget/GridView.java
@@ -30,13 +30,13 @@ import android.view.SoundEffectConstants;
import android.view.View;
import android.view.ViewDebug;
import android.view.ViewGroup;
+import android.view.ViewRootImpl;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.accessibility.AccessibilityNodeProvider;
import android.view.accessibility.AccessibilityNodeInfo.CollectionInfo;
import android.view.accessibility.AccessibilityNodeInfo.CollectionItemInfo;
import android.view.animation.GridLayoutAnimationController;
-import android.widget.AbsListView.AbsPositionScroller;
-import android.widget.ListView.ListViewPositionScroller;
import android.widget.RemoteViews.RemoteView;
import java.lang.annotation.Retention;
@@ -1222,22 +1222,32 @@ public class GridView extends AbsListView {
setSelectedPositionInt(mNextSelectedPosition);
- // Remember which child, if any, had accessibility focus.
- final int accessibilityFocusPosition;
- final View accessFocusedChild = getAccessibilityFocusedChild();
- if (accessFocusedChild != null) {
- accessibilityFocusPosition = getPositionForView(accessFocusedChild);
- accessFocusedChild.setHasTransientState(true);
- } else {
- accessibilityFocusPosition = INVALID_POSITION;
- }
+ AccessibilityNodeInfo accessibilityFocusLayoutRestoreNode = null;
+ View accessibilityFocusLayoutRestoreView = null;
+ int accessibilityFocusPosition = INVALID_POSITION;
+
+ // Remember which child, if any, had accessibility focus. This must
+ // occur before recycling any views, since that will clear
+ // accessibility focus.
+ final ViewRootImpl viewRootImpl = getViewRootImpl();
+ if (viewRootImpl != null) {
+ final View focusHost = viewRootImpl.getAccessibilityFocusedHost();
+ if (focusHost != null) {
+ final View focusChild = getAccessibilityFocusedChild(focusHost);
+ if (focusChild != null) {
+ if (!dataChanged || focusChild.hasTransientState()
+ || mAdapterHasStableIds) {
+ // The views won't be changing, so try to maintain
+ // focus on the current host and virtual view.
+ accessibilityFocusLayoutRestoreView = focusHost;
+ accessibilityFocusLayoutRestoreNode = viewRootImpl
+ .getAccessibilityFocusedVirtualView();
+ }
- // Ensure the child containing focus, if any, has transient state.
- // If the list data hasn't changed, or if the adapter has stable
- // IDs, this will maintain focus.
- final View focusedChild = getFocusedChild();
- if (focusedChild != null) {
- focusedChild.setHasTransientState(true);
+ // Try to maintain focus at the same position.
+ accessibilityFocusPosition = getPositionForView(focusChild);
+ }
+ }
}
// Pull all children into the RecycleBin.
@@ -1324,13 +1334,22 @@ public class GridView extends AbsListView {
mSelectorRect.setEmpty();
}
- if (accessFocusedChild != null) {
- accessFocusedChild.setHasTransientState(false);
-
- // If we failed to maintain accessibility focus on the previous
- // view, attempt to restore it to the previous position.
- if (!accessFocusedChild.isAccessibilityFocused()
- && accessibilityFocusPosition != INVALID_POSITION) {
+ // Attempt to restore accessibility focus, if necessary.
+ final View newAccessibilityFocusedView = viewRootImpl.getAccessibilityFocusedHost();
+ if (newAccessibilityFocusedView == null) {
+ if (accessibilityFocusLayoutRestoreView != null
+ && accessibilityFocusLayoutRestoreView.isAttachedToWindow()) {
+ final AccessibilityNodeProvider provider =
+ accessibilityFocusLayoutRestoreView.getAccessibilityNodeProvider();
+ if (accessibilityFocusLayoutRestoreNode != null && provider != null) {
+ final int virtualViewId = AccessibilityNodeInfo.getVirtualDescendantId(
+ accessibilityFocusLayoutRestoreNode.getSourceNodeId());
+ provider.performAction(virtualViewId,
+ AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS, null);
+ } else {
+ accessibilityFocusLayoutRestoreView.requestAccessibilityFocus();
+ }
+ } else if (accessibilityFocusPosition != INVALID_POSITION) {
// Bound the position within the visible children.
final int position = MathUtils.constrain(
accessibilityFocusPosition - mFirstPosition, 0, getChildCount() - 1);
@@ -1341,10 +1360,6 @@ public class GridView extends AbsListView {
}
}
- if (focusedChild != null) {
- focusedChild.setHasTransientState(false);
- }
-
mLayoutMode = LAYOUT_NORMAL;
mDataChanged = false;
if (mPositionScrollAfterLayout != null) {