summaryrefslogtreecommitdiff
path: root/src/com/android/customization/widget/OptionSelectorController.java
diff options
context:
space:
mode:
authorWesley.CW Wang <wesleycwwang@google.com>2020-06-16 19:11:35 +0800
committerWesley.CW Wang <wesleycwwang@google.com>2020-06-17 15:00:51 +0800
commit49bcc2711091dfee873a5dfe005d91b989f9a28a (patch)
tree90d501ba6bab18820a8f42cb71a669d85b771ba1 /src/com/android/customization/widget/OptionSelectorController.java
parent0e91a8927647d95114ccf83e58d3183bc8e29a2f (diff)
Fix TB lose focus when navigating recyclerview
- Issue history: b/37088814 and previous workaround: ag/11747784 - Since the previous workaround no longer works, apply new scroll behavior to the recyclerview when TB navigating, make sure the focusing item's previous/next item totally visible, then TB won't lose focus. video: https://drive.google.com/file/d/1KJQT9cAmm9G5yZGDZZTNnpezDbT_Rh31/view?usp=sharing Bug: 157007291 Test: manually, enable TB and test the result Change-Id: I1c4c8416d7b1849cf705db931bcd9c6e5c354719
Diffstat (limited to 'src/com/android/customization/widget/OptionSelectorController.java')
-rw-r--r--src/com/android/customization/widget/OptionSelectorController.java50
1 files changed, 41 insertions, 9 deletions
diff --git a/src/com/android/customization/widget/OptionSelectorController.java b/src/com/android/customization/widget/OptionSelectorController.java
index a532e401..69a45a94 100644
--- a/src/com/android/customization/widget/OptionSelectorController.java
+++ b/src/com/android/customization/widget/OptionSelectorController.java
@@ -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);
+ }
+ }
}