diff --git a/Alkitab/src/main/java/yuku/alkitab/base/verses/VerseTextCompose.kt b/Alkitab/src/main/java/yuku/alkitab/base/verses/VerseTextCompose.kt index e0610d5fd..ab68d0f23 100644 --- a/Alkitab/src/main/java/yuku/alkitab/base/verses/VerseTextCompose.kt +++ b/Alkitab/src/main/java/yuku/alkitab/base/verses/VerseTextCompose.kt @@ -69,6 +69,13 @@ class VerseTextComposeView @JvmOverloads constructor( attrs: AttributeSet? = null, ) : AbstractComposeView(context, attrs) { + init { + // The AndroidComposeView child is focusable, and a ListView row with a + // focusable descendant gets no item clicks or long clicks. The text is + // display-only, so nothing inside needs focus. + descendantFocusability = FOCUS_BLOCK_DESCENDANTS + } + /** The appearance snapshot [bind] took, or null until the first bind. */ internal var state by mutableStateOf(null) private set diff --git a/Alkitab/src/test/java/yuku/alkitab/base/verses/VerseTextComposeTest.kt b/Alkitab/src/test/java/yuku/alkitab/base/verses/VerseTextComposeTest.kt index dc06a2bfc..c9777acd6 100644 --- a/Alkitab/src/test/java/yuku/alkitab/base/verses/VerseTextComposeTest.kt +++ b/Alkitab/src/test/java/yuku/alkitab/base/verses/VerseTextComposeTest.kt @@ -1,20 +1,26 @@ package yuku.alkitab.base.verses import android.content.Context +import android.os.Looper +import android.view.ViewGroup import android.widget.LinearLayout import android.widget.TextView +import androidx.appcompat.app.AppCompatActivity import androidx.compose.ui.graphics.Color import androidx.compose.ui.text.AnnotatedString import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.style.TextDecoration import androidx.test.core.app.ApplicationProvider import org.junit.Assert.assertEquals +import org.junit.Assert.assertFalse import org.junit.Assert.assertSame import org.junit.Assert.assertTrue import org.junit.Before import org.junit.Test import org.junit.runner.RunWith +import org.robolectric.Robolectric import org.robolectric.RobolectricTestRunner +import org.robolectric.Shadows import org.robolectric.annotation.Config import yuku.afw.storage.Preferences import yuku.alkitab.base.S @@ -174,6 +180,26 @@ class VerseTextComposeTest { assertEquals(4, checkNotNull(row.findViewById(R.id.lSnippet).state).maxLines) } + @Test + fun `an attached Compose slot leaves its row free of focusables so a ListView still delivers item clicks`() { + setComposeVerseItem(true) + val activity = Robolectric.buildActivity(AppCompatActivity::class.java).setup().get() + activity.setTheme(androidx.appcompat.R.style.Theme_AppCompat) + val row = rowWithSnippet() + + VerseTextSlot.of(row, R.id.lSnippet).setText( + textSizeMult = 1f, + legacy = { throw AssertionError("the TextView branch must not run") }, + compose = { AnnotatedString("tap me") }, + ) + activity.setContentView(row, ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT)) + Shadows.shadowOf(Looper.getMainLooper()).idle() + + val composeView = row.findViewById(R.id.lSnippet) + assertEquals(1, composeView.childCount) + assertFalse(row.hasExplicitFocusable()) + } + @Test fun `a color override replaces the reader's verse color for a checked row`() { setComposeVerseItem(true)