diff --git a/lib/java/com/google/android/material/internal/NavigationMenuPresenter.java b/lib/java/com/google/android/material/internal/NavigationMenuPresenter.java
index a929f62b080..53c64e69173 100644
--- a/lib/java/com/google/android/material/internal/NavigationMenuPresenter.java
+++ b/lib/java/com/google/android/material/internal/NavigationMenuPresenter.java
@@ -48,10 +48,12 @@
import androidx.annotation.Px;
import androidx.annotation.RestrictTo;
import androidx.annotation.StyleRes;
+import androidx.core.view.AccessibilityDelegateCompat;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat;
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.CollectionInfoCompat;
+import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.CollectionItemInfoCompat;
import androidx.core.widget.TextViewCompat;
import java.util.ArrayList;
@@ -596,6 +598,7 @@ public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
}
itemView.setMaxLines(itemMaxLines);
itemView.initialize(item.getMenuItem(), 0);
+ setAccessibilityDelegate(itemView, position, false);
break;
}
case VIEW_TYPE_SUBHEADER:
@@ -615,6 +618,7 @@ public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
if (subheaderColor != null) {
subHeader.setTextColor(subheaderColor);
}
+ setAccessibilityDelegate(subHeader, position, true);
break;
}
case VIEW_TYPE_SEPARATOR:
@@ -629,11 +633,46 @@ public void onBindViewHolder(@NonNull ViewHolder holder, int position) {
}
case VIEW_TYPE_HEADER:
{
+ setAccessibilityDelegate(holder.itemView, position, true);
break;
}
}
}
+ private void setAccessibilityDelegate(View view, int position, boolean isHeader) {
+ ViewCompat.setAccessibilityDelegate(
+ view,
+ new AccessibilityDelegateCompat() {
+ @Override
+ public void onInitializeAccessibilityNodeInfo(
+ @NonNull View host, @NonNull AccessibilityNodeInfoCompat info) {
+ super.onInitializeAccessibilityNodeInfo(host, info);
+ info.setCollectionItemInfo(
+ CollectionItemInfoCompat.obtain(
+ /* rowIndex= */ adjustItemPositionForA11yDelegate(position),
+ /* rowSpan= */ 1,
+ /* columnIndex =*/ 1,
+ /* columnSpan= */ 1,
+ /* heading= */ isHeader,
+ /* selected= */ host.isSelected()));
+ }
+ });
+ }
+
+ /** Adjusts position based on the presence of separators and header. */
+ private int adjustItemPositionForA11yDelegate(int position) {
+ int adjustedPosition = position;
+ for (int i = 0; i < position; i++) {
+ if (adapter.getItemViewType(i) == VIEW_TYPE_SEPARATOR) {
+ adjustedPosition--;
+ }
+ }
+ if (headerLayout.getChildCount() == 0) { // no header
+ adjustedPosition--;
+ }
+ return adjustedPosition;
+ }
+
@Override
public void onViewRecycled(ViewHolder holder) {
if (holder instanceof NormalViewHolder) {
@@ -816,7 +855,8 @@ public void setUpdateSuspended(boolean updateSuspended) {
int getRowCount() {
int itemCount = headerLayout.getChildCount() == 0 ? 0 : 1;
for (int i = 0; i < adapter.getItemCount(); i++) {
- if (adapter.getItemViewType(i) == VIEW_TYPE_NORMAL) {
+ int type = adapter.getItemViewType(i);
+ if (type == VIEW_TYPE_NORMAL || type == VIEW_TYPE_SUBHEADER) {
itemCount++;
}
}
@@ -880,7 +920,9 @@ private class NavigationMenuViewAccessibilityDelegate extends RecyclerViewAccess
public void onInitializeAccessibilityNodeInfo(
View host, @NonNull AccessibilityNodeInfoCompat info) {
super.onInitializeAccessibilityNodeInfo(host, info);
- info.setCollectionInfo(CollectionInfoCompat.obtain(adapter.getRowCount(), 0, false));
+ info.setCollectionInfo(
+ CollectionInfoCompat.obtain(
+ adapter.getRowCount(), /* columnCount= */ 1, /* hierarchical= */ false));
}
}
}
diff --git a/testing/java/com/google/android/material/testapp/res/menu/navigation_view_content.xml b/testing/java/com/google/android/material/testapp/res/menu/navigation_view_content.xml
index 7c8ab8df1b6..c801daf3b42 100644
--- a/testing/java/com/google/android/material/testapp/res/menu/navigation_view_content.xml
+++ b/testing/java/com/google/android/material/testapp/res/menu/navigation_view_content.xml
@@ -1,5 +1,4 @@
-
-
-