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

Commit f103758b authored by Svetoslav Ganov's avatar Svetoslav Ganov Committed by Android (Google) Code Review
Browse files

Merge "Delegate list item focus and click actions to the parent list." into jb-dev

parents bad417df c1d7e770
Loading
Loading
Loading
Loading
+78 −0
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.TransitionDrawable;
import android.os.Bundle;
import android.os.Debug;
import android.os.Handler;
import android.os.Parcel;
@@ -57,6 +58,7 @@ import android.view.ViewGroup;
import android.view.ViewParent;
import android.view.ViewTreeObserver;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityManager;
import android.view.accessibility.AccessibilityNodeInfo;
import android.view.animation.Interpolator;
import android.view.animation.LinearInterpolator;
@@ -648,6 +650,11 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
    private int mGlowPaddingLeft;
    private int mGlowPaddingRight;

    /**
     * Used for interacting with list items from an accessibility service.
     */
    private ListItemAccessibilityDelegate mAccessibilityDelegate;

    private int mLastAccessibilityScrollEventFromIndex;
    private int mLastAccessibilityScrollEventToIndex;

@@ -2121,9 +2128,77 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
            child.setLayoutParams(lp);
        }

        if (AccessibilityManager.getInstance(mContext).isEnabled()) {
            if (mAccessibilityDelegate == null) {
                mAccessibilityDelegate = new ListItemAccessibilityDelegate();
            }
            child.setAccessibilityDelegate(mAccessibilityDelegate);
        }

        return child;
    }

    class ListItemAccessibilityDelegate extends AccessibilityDelegate {
        @Override
        public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfo info) {
            super.onInitializeAccessibilityNodeInfo(host, info);

            final int position = getPositionForView(host);

            if (position == INVALID_POSITION) {
                return;
            }

            if (isClickable()) {
                info.addAction(AccessibilityNodeInfo.ACTION_CLICK);
                info.setClickable(true);
            }

            if (isLongClickable()) {
                info.addAction(AccessibilityNodeInfo.ACTION_LONG_CLICK);
                info.setLongClickable(true);
            }

            info.addAction(AccessibilityNodeInfo.ACTION_SELECT);

            if (position == getSelectedItemPosition()) {
                info.setSelected(true);
            }
        }

        @Override
        public boolean performAccessibilityAction(View host, int action, Bundle arguments) {
            final int position = getPositionForView(host);

            if (position == INVALID_POSITION) {
                return false;
            }

            final long id = getItemIdAtPosition(position);

            switch (action) {
                case AccessibilityNodeInfo.ACTION_SELECT:
                    setSelection(position);
                    return true;
                case AccessibilityNodeInfo.ACTION_CLICK:
                    if (!super.performAccessibilityAction(host, action, arguments)) {
                        return performItemClick(host, position, id);
                    }
                    return true;
                case AccessibilityNodeInfo.ACTION_LONG_CLICK:
                    if (!super.performAccessibilityAction(host, action, arguments)) {
                        return performLongPress(host, position, id);
                    }
                    return true;
                case AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS:
                    smoothScrollToPosition(position);
                    break;
            }

            return super.performAccessibilityAction(host, action, arguments);
        }
    }

    void positionSelector(int position, View sel) {
        if (position != INVALID_POSITION) {
            mSelectorPosition = position;
@@ -5671,6 +5746,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
            // Don't reclaim header or footer views, or views that should be ignored
            if (lp != null && mRecycler.shouldRecycleViewType(lp.viewType)) {
                views.add(child);
                child.setAccessibilityDelegate(null);
                if (listener != null) {
                    // Pretend they went through the scrap heap
                    listener.onMovedToScrapHeap(child);
@@ -6226,6 +6302,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
                mScrapViews[viewType].add(scrap);
            }

            scrap.setAccessibilityDelegate(null);
            if (mRecyclerListener != null) {
                mRecyclerListener.onMovedToScrapHeap(scrap);
            }
@@ -6287,6 +6364,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
                    lp.scrappedFromPosition = mFirstActivePosition + i;
                    scrapViews.add(victim);

                    victim.setAccessibilityDelegate(null);
                    if (hasListener) {
                        mRecyclerListener.onMovedToScrapHeap(victim);
                    }