Fix missing TalkBack labels on Card Browser filter checkboxes · ankidroid/Anki-Android@ad8e787 · GitHub
Skip to content

Commit ad8e787

Browse files
committed
Fix missing TalkBack labels on Card Browser filter checkboxes
The Flags and Card State bottom sheet filters bind a per-row CheckBox without a contentDescription, so TalkBack only announces "checked" / "not checked" with no indication of which flag or state it toggles. Set contentDescription to the row's label, matching the pattern already used in BrowserColumnSelectionAdapter.
1 parent eb22e1e commit ad8e787

4 files changed

Lines changed: 82 additions & 0 deletions

File tree

AnkiDroid/src/main/java/com/ichi2/anki/browser/search/CardStateBottomSheetFragment.kt

Lines changed: 1 addition & 0 deletions

AnkiDroid/src/main/java/com/ichi2/anki/browser/search/FlagsBottomSheetFragment.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ class FlagsBottomSheetFragment : BottomSheetDialogFragment(R.layout.fragment_bot
127127
) {
128128
val model = this.states[position]
129129
holder.binding.text.text = model.label
130+
holder.binding.checkbox.contentDescription = model.label
130131
holder.binding.icon.setImageResource(model.flag.drawableRes)
131132
// TODO: Long press to rename
132133
holder.binding.root.setOnClickListener { onItemClickedListener(model.flag) }
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
// SPDX-License-Identifier: GPL-3.0-or-later
2+
// SPDX-FileCopyrightText: 2026 Alok Srivastava <alok020505@gmail.com>
3+
4+
package com.ichi2.anki.browser.search
5+
6+
import android.os.Looper
7+
import android.widget.CheckBox
8+
import androidx.recyclerview.widget.RecyclerView
9+
import androidx.test.espresso.Espresso.onView
10+
import androidx.test.espresso.matcher.RootMatchers.isDialog
11+
import androidx.test.espresso.matcher.ViewMatchers.withId
12+
import androidx.test.ext.junit.runners.AndroidJUnit4
13+
import com.ichi2.anki.R
14+
import com.ichi2.anki.RobolectricTest
15+
import com.ichi2.anki.browser.withCardBrowserFragment
16+
import org.hamcrest.MatcherAssert.assertThat
17+
import org.hamcrest.Matchers.equalTo
18+
import org.junit.Test
19+
import org.junit.runner.RunWith
20+
import org.robolectric.Shadows.shadowOf
21+
22+
/** Test of [CardStateBottomSheetFragment] */
23+
@RunWith(AndroidJUnit4::class)
24+
class CardStateBottomSheetFragmentTest : RobolectricTest() {
25+
// TalkBack users must hear which card state a checkbox toggles, not just "checked"/"not checked"
26+
@Test
27+
fun `card state checkbox exposes its label to TalkBack`() =
28+
withCardBrowserFragment {
29+
CardStateBottomSheetFragment().show(childFragmentManager, CardStateBottomSheetFragment.TAG)
30+
shadowOf(Looper.getMainLooper()).idle()
31+
32+
onView(withId(R.id.list)).inRoot(isDialog()).check { view, _ ->
33+
val recyclerView = view as RecyclerView
34+
val holder = requireNotNull(recyclerView.findViewHolderForAdapterPosition(0))
35+
val checkbox = holder.itemView.findViewById<CheckBox>(R.id.checkbox)
36+
// position 0 is CardState.New
37+
assertThat(checkbox.contentDescription, equalTo("New" as CharSequence))
38+
}
39+
}
40+
}
Lines changed: 40 additions & 0 deletions

0 commit comments

Comments
 (0)