• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package androidx.recyclerview.widget;
18 
19 import android.os.Bundle;
20 import android.view.View;
21 import android.view.accessibility.AccessibilityEvent;
22 
23 import androidx.annotation.NonNull;
24 import androidx.core.view.AccessibilityDelegateCompat;
25 import androidx.core.view.accessibility.AccessibilityNodeInfoCompat;
26 
27 /**
28  * The AccessibilityDelegate used by RecyclerView.
29  * <p>
30  * This class handles basic accessibility actions and delegates them to LayoutManager.
31  */
32 public class RecyclerViewAccessibilityDelegate extends AccessibilityDelegateCompat {
33     final RecyclerView mRecyclerView;
34     final AccessibilityDelegateCompat mItemDelegate;
35 
36 
RecyclerViewAccessibilityDelegate(@onNull RecyclerView recyclerView)37     public RecyclerViewAccessibilityDelegate(@NonNull RecyclerView recyclerView) {
38         mRecyclerView = recyclerView;
39         mItemDelegate = new ItemDelegate(this);
40     }
41 
shouldIgnore()42     boolean shouldIgnore() {
43         return mRecyclerView.hasPendingAdapterUpdates();
44     }
45 
46     @Override
performAccessibilityAction(View host, int action, Bundle args)47     public boolean performAccessibilityAction(View host, int action, Bundle args) {
48         if (super.performAccessibilityAction(host, action, args)) {
49             return true;
50         }
51         if (!shouldIgnore() && mRecyclerView.getLayoutManager() != null) {
52             return mRecyclerView.getLayoutManager().performAccessibilityAction(action, args);
53         }
54 
55         return false;
56     }
57 
58     @Override
onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfoCompat info)59     public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfoCompat info) {
60         super.onInitializeAccessibilityNodeInfo(host, info);
61         info.setClassName(RecyclerView.class.getName());
62         if (!shouldIgnore() && mRecyclerView.getLayoutManager() != null) {
63             mRecyclerView.getLayoutManager().onInitializeAccessibilityNodeInfo(info);
64         }
65     }
66 
67     @Override
onInitializeAccessibilityEvent(View host, AccessibilityEvent event)68     public void onInitializeAccessibilityEvent(View host, AccessibilityEvent event) {
69         super.onInitializeAccessibilityEvent(host, event);
70         event.setClassName(RecyclerView.class.getName());
71         if (host instanceof RecyclerView && !shouldIgnore()) {
72             RecyclerView rv = (RecyclerView) host;
73             if (rv.getLayoutManager() != null) {
74                 rv.getLayoutManager().onInitializeAccessibilityEvent(event);
75             }
76         }
77     }
78 
79     /**
80      * Gets the AccessibilityDelegate for an individual item in the RecyclerView.
81      * A basic item delegate is provided by default, but you can override this
82      * method to provide a custom per-item delegate.
83      */
84     @NonNull
getItemDelegate()85     public AccessibilityDelegateCompat getItemDelegate() {
86         return mItemDelegate;
87     }
88 
89     /**
90      * The default implementation of accessibility delegate for the individual items of the
91      * RecyclerView.
92      * <p>
93      * If you are overriding {@code RecyclerViewAccessibilityDelegate#getItemDelegate()} but still
94      * want to keep some default behavior, you can create an instance of this class and delegate to
95      * the parent as necessary.
96      */
97     public static class ItemDelegate extends AccessibilityDelegateCompat {
98         final RecyclerViewAccessibilityDelegate mRecyclerViewDelegate;
99 
100         /**
101          * Creates an item delegate for the given {@code RecyclerViewAccessibilityDelegate}.
102          *
103          * @param recyclerViewDelegate The parent RecyclerView's accessibility delegate.
104          */
ItemDelegate(@onNull RecyclerViewAccessibilityDelegate recyclerViewDelegate)105         public ItemDelegate(@NonNull RecyclerViewAccessibilityDelegate recyclerViewDelegate) {
106             mRecyclerViewDelegate = recyclerViewDelegate;
107         }
108 
109         @Override
onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfoCompat info)110         public void onInitializeAccessibilityNodeInfo(View host, AccessibilityNodeInfoCompat info) {
111             super.onInitializeAccessibilityNodeInfo(host, info);
112             if (!mRecyclerViewDelegate.shouldIgnore()
113                     && mRecyclerViewDelegate.mRecyclerView.getLayoutManager() != null) {
114                 mRecyclerViewDelegate.mRecyclerView.getLayoutManager()
115                         .onInitializeAccessibilityNodeInfoForItem(host, info);
116             }
117         }
118 
119         @Override
performAccessibilityAction(View host, int action, Bundle args)120         public boolean performAccessibilityAction(View host, int action, Bundle args) {
121             if (super.performAccessibilityAction(host, action, args)) {
122                 return true;
123             }
124             if (!mRecyclerViewDelegate.shouldIgnore()
125                     && mRecyclerViewDelegate.mRecyclerView.getLayoutManager() != null) {
126                 return mRecyclerViewDelegate.mRecyclerView.getLayoutManager()
127                         .performAccessibilityActionForItem(host, action, args);
128             }
129             return false;
130         }
131     }
132 }
133 
134