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

Commit 53785cf3 authored by Wesley.CW Wang's avatar Wesley.CW Wang Committed by Automerger Merge Worker
Browse files

Fix TB lose focus when navigating recyclerview am: 49bcc271

Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/apps/ThemePicker/+/11881681

Change-Id: I616cf1686774490133f4f9a3feab312de7ca6f04
parents b488db93 49bcc271
Loading
Loading
Loading
Loading
+41 −9
Original line number Diff line number Diff line
@@ -26,12 +26,14 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityEvent;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.RecyclerViewAccessibilityDelegate;

import com.android.customization.model.CustomizationManager;
import com.android.customization.model.CustomizationOption;
@@ -154,17 +156,15 @@ public class OptionSelectorController<T extends CustomizationOption<T>> {
     * Initializes the UI for the options passed in the constructor of this class.
     */
    public void initOptions(final CustomizationManager<T> manager) {
        mContainer.setAccessibilityDelegateCompat(
                new OptionSelectorAccessibilityDelegate(mContainer));

        mAdapter = new RecyclerView.Adapter<TileViewHolder>() {
            @Override
            public int getItemViewType(int position) {
                return mOptions.get(position).getLayoutResId();
            }

            @Override
            public long getItemId(int position) {
                return position;
            }

            @NonNull
            @Override
            public TileViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
@@ -232,10 +232,6 @@ public class OptionSelectorController<T extends CustomizationOption<T>> {
                LinearLayoutManager.HORIZONTAL, false));
        Resources res = mContainer.getContext().getResources();

        // A workaround from b/37088814, fix TalkBack will lose focus when receive notify*Changed()
        mAdapter.setHasStableIds(true);
        mContainer.setItemAnimator(null);

        mContainer.setAdapter(mAdapter);

        // Measure RecyclerView to get to the total amount of space used by all options.
@@ -340,4 +336,40 @@ public class OptionSelectorController<T extends CustomizationOption<T>> {
            }
        }
    }

    private class OptionSelectorAccessibilityDelegate extends RecyclerViewAccessibilityDelegate {

        OptionSelectorAccessibilityDelegate(RecyclerView recyclerView) {
            super(recyclerView);
        }

        @Override
        public boolean onRequestSendAccessibilityEvent(
                ViewGroup host, View child, AccessibilityEvent event) {

            // Apply this workaround to horizontal recyclerview only,
            // since the symptom is TalkBack will lose focus when navigating horizontal list items.
            if (mContainer.getLayoutManager() != null
                    && mContainer.getLayoutManager().canScrollHorizontally()
                    && event.getEventType() == AccessibilityEvent.TYPE_VIEW_ACCESSIBILITY_FOCUSED) {
                int itemPos = mContainer.getChildLayoutPosition(child);
                int itemWidth = mContainer.getContext().getResources()
                        .getDimensionPixelOffset(R.dimen.option_tile_width);
                int itemMarginHorizontal = mContainer.getContext().getResources()
                        .getDimensionPixelOffset(R.dimen.option_tile_margin_horizontal) * 2;
                int scrollOffset = itemWidth + itemMarginHorizontal;

                // Make focusing item's previous/next item totally visible when changing focus,
                // ensure TalkBack won't lose focus when recyclerview scrolling.
                if (itemPos >= ((LinearLayoutManager) mContainer.getLayoutManager())
                        .findLastCompletelyVisibleItemPosition()) {
                    mContainer.scrollBy(scrollOffset, 0);
                } else if (itemPos <= ((LinearLayoutManager) mContainer.getLayoutManager())
                        .findFirstCompletelyVisibleItemPosition() && itemPos != 0) {
                    mContainer.scrollBy(-scrollOffset, 0);
                }
            }
            return super.onRequestSendAccessibilityEvent(host, child, event);
        }
    }
}