我正在致力于辅助功能实现(盲人残疾),一旦用户向左或向右滑动以将焦点移到 LazyRow 中的项目上,我需要知道列表中当前处于辅助功能焦点中的项目索引。
我有这样一个暗示:
LazyRow(
state = listState,
modifier = modifier,
flingBehavior = rememberSnapFlingBehavior(lazyListState = listState)
) {
itemsIndexed(items = episodes, key = { index, _ ->
"$CARD_KEY$index"
}) { index, item ->
item.apply {
CustomCard(
episode = item.episode,
modifier = Modifier
.wrapContentWidth()
.background(
BrandedTheme._ui_core__bottomsheet__backgroundColor
)
.onFocusChanged {
if (it.isFocused) {
if (listState.isScrollInProgress.not() && selectedEpisodeIndex != -1) {
GlobalScope.launch {
listState.scrollToItem(index = index)
}
}
}
}
.wrapContentHeight()
.semantics(mergeDescendants = true) {
isTraversalGroup = true
traversalIndex = -1f
},
index = index
)
}
}
}
因此,列表中的每个项目都有一个具有属性 -
onFocusChanged
的修饰符,问题是该事件仅在列表初始化时触发,但是当用户移动辅助功能焦点(通过向左/向右滑动)时,我看到(在屏幕上)下一个项目获得焦点,但在代码中 onFocusChanged
未触发。
我在这里缺少什么?
UPD
添加了
onFocusEvent()
和focusTarget()
,现在好像我收到了更改元素的事件,但有2个问题:
Inactive
(无活动状态)。 LazyRow(
state = listState,
modifier = modifier,
flingBehavior = rememberSnapFlingBehavior(lazyListState = listState)
) {
itemsIndexed(items = episodes, key = { index, _ ->
"$CARD_KEY$index"
}) { index, item ->
item.apply {
CustomCard(
episode = item.episode,
modifier = Modifier
.wrapContentWidth()
.onFocusEvent {
Log.e("HERE", "111 onFocusEvent: $index :: $it")
}
.background(
BrandedTheme._ui_core__bottomsheet__backgroundColor
)
.onFocusChanged {
if (it.isFocused) {
if (listState.isScrollInProgress.not() && selectedEpisodeIndex != -1) {
GlobalScope.launch {
listState.scrollToItem(index = index)
}
}
}
}
.focusTarget()
.wrapContentHeight()
.semantics(mergeDescendants = true) {
isTraversalGroup = true
traversalIndex = -1f
},
index = index
)
}
}
}
我的另一个想法是创建一个自定义
rememberSnapFlingBehavior
,因为我注意到在辅助功能模式下,屏幕上的焦点会切换并拉动下一个元素,但它不会将其置于屏幕中心(尽管这在没有辅助功能的情况下也可以工作)模式)。但最终这个想法也没能实现。
如果我没记错的话,Compose 默认情况下不会将焦点更改传播到父可组合项(以提高性能)。在您的情况下,您可能需要通过从父可组合项传递回调函数来手动传播焦点更改。
此外,当 traversalIndex 设置为 -1f 时,我认为该项目不包含在可访问性焦点遍历中,这也可能是您问题的一部分。作为黑暗中的一击,你尝试过设置
traversalIndex = index.toFloat()
吗?