Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit aaa026a9 authored by Alan Viverette's avatar Alan Viverette Committed by Android (Google) Code Review
Browse files

Merge "Restore A11y and keyboard focus positions after GridView layout"

parents 7586ca89 5d565faa
Loading
Loading
Loading
Loading
+29 −0
Original line number Diff line number Diff line
@@ -55,6 +55,7 @@ import android.view.ViewConfiguration;
import android.view.ViewDebug;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.view.ViewRootImpl;
import android.view.ViewTreeObserver;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
@@ -2124,6 +2125,34 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
    protected void layoutChildren() {
    }

    /**
     * @return the direct child that contains accessibility focus, or null if no
     *         child contains accessibility focus
     */
    View getAccessibilityFocusedChild() {
        final ViewRootImpl viewRootImpl = getViewRootImpl();
        if (viewRootImpl == null) {
            return null;
        }

        View focusedView = viewRootImpl.getAccessibilityFocusedHost();
        if (focusedView == null) {
            return null;
        }

        ViewParent viewParent = focusedView.getParent();
        while ((viewParent instanceof View) && (viewParent != this)) {
            focusedView = (View) viewParent;
            viewParent = viewParent.getParent();
        }

        if (!(viewParent instanceof View)) {
            return null;
        }

        return focusedView;
    }

    void updateScrollIndicators() {
        if (mScrollUp != null) {
            boolean canScrollUp;
+40 −1
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import android.content.res.TypedArray;
import android.graphics.Rect;
import android.os.Trace;
import android.util.AttributeSet;
import android.util.MathUtils;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.SoundEffectConstants;
@@ -1215,6 +1216,24 @@ 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;
            }

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

            // Pull all children into the RecycleBin.
            // These views will be reused if possible
            final int firstPosition = mFirstPosition;
@@ -1229,7 +1248,6 @@ public class GridView extends AbsListView {
            }

            // Clear out old views
            //removeAllViewsInLayout();
            detachAllViewsFromParent();
            recycleBin.removeSkippedScrap();

@@ -1300,6 +1318,27 @@ 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) {
                    // 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();
                    }
                }
            }

            if (focusedChild != null) {
                focusedChild.setHasTransientState(false);
            }

            mLayoutMode = LAYOUT_NORMAL;
            mDataChanged = false;
            if (mPositionScrollAfterLayout != null) {
+0 −28
Original line number Diff line number Diff line
@@ -1732,34 +1732,6 @@ public class ListView extends AbsListView {
        }
    }

    /**
     * @return the direct child that contains accessibility focus, or null if no
     *         child contains accessibility focus
     */
    private View getAccessibilityFocusedChild() {
        final ViewRootImpl viewRootImpl = getViewRootImpl();
        if (viewRootImpl == null) {
            return null;
        }

        View focusedView = viewRootImpl.getAccessibilityFocusedHost();
        if (focusedView == null) {
            return null;
        }

        ViewParent viewParent = focusedView.getParent();
        while ((viewParent instanceof View) && (viewParent != this)) {
            focusedView = (View) viewParent;
            viewParent = viewParent.getParent();
        }

        if (!(viewParent instanceof View)) {
            return null;
        }

        return focusedView;
    }

    /**
     * Obtain the view and add it to our list of children. The view can be made
     * fresh, converted from an unused view, or used as is if it was in the