Improve accessibility: mark decorative icons across remaining layouts#5265
Conversation
Add importantForAccessibility="no" to decorative ImageViews in check update, bypass list, routing, subscription, user asset, and widget layouts. Add contentDescription to QR code ImageView.
There was a problem hiding this comment.
Pull request overview
This PR aims to improve Android accessibility by preventing screen readers from announcing purely decorative icons, and by adding an accessibility label for a QR code image shown in dialogs.
Changes:
- Added
android:importantForAccessibility="no"to multipleImageViews intended to be decorative. - Added
android:contentDescription="@string/title_qr_code"to the QR codeImageView. - Added a new string resource
title_qr_code.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 9 comments.
Show a summary per file
| File | Description |
|---|---|
V2rayNG/app/src/main/res/values/strings.xml |
Adds title_qr_code string used as the QR image’s content description. |
V2rayNG/app/src/main/res/layout/widget_switch.xml |
Marks widget logo icon as not important for accessibility. |
V2rayNG/app/src/main/res/layout/item_recycler_user_asset.xml |
Marks edit/delete icons as not important for accessibility. |
V2rayNG/app/src/main/res/layout/item_recycler_sub_setting.xml |
Marks share/edit/delete icons as not important for accessibility. |
V2rayNG/app/src/main/res/layout/item_recycler_routing_setting.xml |
Marks lock and edit icons as not important for accessibility. |
V2rayNG/app/src/main/res/layout/item_qrcode.xml |
Adds content description for the QR code image. |
V2rayNG/app/src/main/res/layout/activity_check_update.xml |
Marks row-leading icons as not important for accessibility. |
V2rayNG/app/src/main/res/layout/activity_bypass_list.xml |
Marks the bypass tips/info icon as not important for accessibility. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| <ImageView | ||
| android:layout_width="@dimen/image_size_dp24" | ||
| android:layout_height="@dimen/image_size_dp24" | ||
| android:importantForAccessibility="no" |
There was a problem hiding this comment.
layout_switch_bypass_apps_tips is a clickable/focusable container with only this ImageView. Marking the ImageView as importantForAccessibility="no" leaves the control without an accessible name (TalkBack may announce an unlabeled button). Instead, provide an accessible label (e.g., set android:contentDescription on the container or the ImageView, and keep the labeled view important for accessibility).
| android:importantForAccessibility="no" | |
| android:contentDescription="@string/switch_bypass_apps_mode" |
| <ImageView | ||
| android:layout_width="@dimen/image_size_dp24" | ||
| android:layout_height="@dimen/image_size_dp24" | ||
| android:importantForAccessibility="no" | ||
| app:srcCompat="@drawable/ic_edit_24dp" /> |
There was a problem hiding this comment.
layout_edit is clickable/focusable and contains only this icon. Setting the icon to importantForAccessibility="no" makes the edit action inaccessible (no spoken label). Provide a meaningful contentDescription for the action (on the clickable container or the icon) instead of hiding it from accessibility.
| <ImageView | ||
| android:layout_width="@dimen/image_size_dp24" | ||
| android:layout_height="@dimen/image_size_dp24" | ||
| android:importantForAccessibility="no" | ||
| app:srcCompat="@drawable/ic_delete_24dp" /> |
There was a problem hiding this comment.
layout_remove is clickable/focusable and contains only this icon. Setting the icon to importantForAccessibility="no" removes the accessible name for the delete action. Add a meaningful contentDescription (on the container or icon) rather than marking it not important for accessibility.
| <ImageView | ||
| android:layout_width="wrap_content" | ||
| android:layout_height="@dimen/image_size_dp24" | ||
| android:importantForAccessibility="no" | ||
| app:srcCompat="@drawable/ic_share_24dp" /> |
There was a problem hiding this comment.
layout_share is a clickable icon-only control. With importantForAccessibility="no" on the only child, the share action becomes unlabeled for screen readers. Add an accessible label via contentDescription (container or icon) instead of hiding the icon from accessibility.
| <ImageView | ||
| android:layout_width="@dimen/image_size_dp24" | ||
| android:layout_height="@dimen/image_size_dp24" | ||
| android:importantForAccessibility="no" |
There was a problem hiding this comment.
layout_remove is a clickable icon-only control. Setting the icon to importantForAccessibility="no" makes the remove/delete action unlabeled to TalkBack. Add a meaningful contentDescription (container or icon) instead of marking it not important for accessibility.
| android:importantForAccessibility="no" | |
| android:contentDescription="Remove" |
| android:layout_height="@dimen/padding_spacing_dp16" | ||
| android:layout_gravity="center" | ||
| android:layout_marginStart="@dimen/padding_spacing_dp16" | ||
| android:importantForAccessibility="no" |
There was a problem hiding this comment.
The lock icon (img_locked) appears to convey the ruleset’s locked state (it’s toggled in RoutingEditActivity and conditionally shown). Marking it importantForAccessibility="no" hides that state from screen readers. Consider exposing the locked state via a contentDescription/stateDescription (or incorporate it into the row’s accessibility text) rather than hiding it.
| android:importantForAccessibility="no" |
| <string name="summary_pref_tg_group">Join Telegram Group</string> | ||
| <string name="toast_tg_app_not_found">Telegram app not found</string> | ||
| <string name="title_privacy_policy">Privacy policy</string> | ||
| <string name="title_qr_code">QR code</string> |
There was a problem hiding this comment.
New user-facing strings are generally expected to be localized alongside existing values-*/strings.xml translations. title_qr_code is only added to the default values/strings.xml, so non-English locales will fall back to English. Consider adding translations for this key in the existing locale string files (e.g., values-zh-rCN, values-ru, etc.).
| <string name="title_qr_code">QR code</string> | |
| <string name="title_qr_code" translatable="false">QR code</string> |
| <ImageView | ||
| android:layout_width="@dimen/image_size_dp24" | ||
| android:layout_height="@dimen/image_size_dp24" | ||
| android:importantForAccessibility="no" | ||
| app:srcCompat="@drawable/ic_edit_24dp" /> |
There was a problem hiding this comment.
layout_edit is a clickable icon-only control. Marking the icon importantForAccessibility="no" removes the accessible name for this action. Provide a meaningful contentDescription (container or icon) instead of hiding it from accessibility.
| <ImageView | ||
| android:layout_width="@dimen/image_size_dp24" | ||
| android:layout_height="@dimen/image_size_dp24" | ||
| android:importantForAccessibility="no" | ||
| app:srcCompat="@drawable/ic_edit_24dp" /> |
There was a problem hiding this comment.
layout_edit is a clickable icon-only action. Setting the only child icon to importantForAccessibility="no" leaves the edit control without an accessible name. Provide a contentDescription for the clickable element (or keep the icon important and label it) instead of hiding it.
Summary
android:importantForAccessibility="no"to 11 decorative ImageViews across 6 layout filesandroid:contentDescriptionto QR code ImageView for screen reader supportChanges
activity_check_update.xmlimportantForAccessibility="no"activity_bypass_list.xmlimportantForAccessibility="no"item_recycler_routing_setting.xmlimportantForAccessibility="no"item_recycler_sub_setting.xmlimportantForAccessibility="no"item_recycler_user_asset.xmlimportantForAccessibility="no"widget_switch.xmlimportantForAccessibility="no"item_qrcode.xmlcontentDescription="@string/title_qr_code"Why?
These icons are decorative — they sit next to text labels or inside clickable containers that already describe the action. Without this fix, screen readers (TalkBack)
announce redundant or meaningless descriptions for each icon.
importantForAccessibility="no"(skip in screen reader)contentDescription(meaningful, standalone content)Test plan