【发布时间】:2023-02-22 04:50:16
【问题描述】:
介绍
我制作了一个包装器,使 Composable 具有禁用外观,并防止将点击事件传递给它。
@Composable
fun DisableOverlay(enabled: Boolean, alpha: Float = 0.45F, content: @Composable () -> Unit) {
if (enabled) {
content()
} else {
Box(
modifier = Modifier
.wrapContentWidth()
.wrapContentHeight()
.alpha(alpha)
) {
content()
Box(modifier = Modifier
.matchParentSize()
.clickable(enabled = false){
//absorb the clicks
}
)
}
}
}
下面是一个示例用法。
DisableOverlay(enabled = false) {
Column{
Text(text = "Some Text")
}
}
问题
它工作正常,但在辅助功能阅读器 (TalkBack) 开启时存在一些问题。读者不会在某些设备上阅读 content 可组合项。它会读取 Pixel 设备上的文本,但不会读取三星设备上的文本。我在 Pixel 设备上注意到它读取文本内容但不遵守其上设置的任何语义,即 contentDescription。
例如,读者不会阅读这个Text上的“我的内容描述”。
DisableOverlay(enabled = false) {
Column{
Text(text = "Some Text",
modifier = Modifier.semantics {
contentDescription = "my content description"
})
}
}
尝试的解决方案 1(失败)
我在与可组合内容重叠的 Box 上添加了 clearAndSetSemantics。我的理论是读者可以忽略该元素而只读出content。这没有用,读者完全跳过了内容。
fun DisableOverlay(enabled: Boolean, alpha: Float = 0.45F, content: @Composable () -> Unit) {
if (enabled) {
content()
} else {
Box(
modifier = Modifier
.wrapContentWidth()
.wrapContentHeight()
.alpha(alpha)
) {
content()
Box(modifier = Modifier
.matchParentSize()
.clearAndSetSemantics {
}
.clickable(enabled = false){
//absorb the clicks
}
)
}
}
}
尝试解决方案 2(失败)
我找到了一个名为 invisibleToUser() 的属性。这与解决方案 1 中的 clearAndSetSemantics 具有相同的效果。
.semantics {
invisibleToUser()
}
尝试解决方案 3(失败)
我查找了一种使用空白 pointerInput 实现来禁用点击事件的不同方法。由于没有 clickable 修饰符,可访问性读取器读出 content 可组合项并遵循其语义。
但是有一个交易破坏者。虽然这个被阻止的触摸事件可访问性读者仍然能够选择它。
@Composable
fun DisableOverlay(enabled: Boolean, alpha: Float = 0.45F, content: @Composable () -> Unit) {
if (enabled) {
content()
} else {
Box(
modifier = Modifier
.wrapContentWidth()
.wrapContentHeight()
.alpha(alpha)
) {
content()
Box(modifier = Modifier
.matchParentSize()
.pointerInput(Unit){
//absorb the clicks
}
)
}
}
}
想法 1
如果我在与 content 重叠的 Box 上设置 contentDescription,读者会按预期阅读它。理想情况下,我不想通过contentDescription,我只想从content 中提取语义并直接读出来。这可能吗?
@Composable
fun DisableOverlay(enabled: Boolean, alpha: Float = 0.45F, content: @Composable () -> Unit) {
if (enabled) {
content()
} else {
Box(
modifier = Modifier
.wrapContentWidth()
.wrapContentHeight()
.alpha(alpha)
) {
content()
Box(modifier = Modifier
.matchParentSize()
.clickable(enabled = false){
//absorb the clicks
}
.semantics {
contentDescription = "test"
}
)
}
}
}
想法 2
我的总体目标是通过将 Composable 包装在另一个 Composable 中来禁用 Composable。如果有人对上述问题有替代解决方案,请告诉我。
感谢您阅读我的问题。
【问题讨论】:
-
添加了
Attempted Solution 3这失败了但是它越来越接近了。
标签: android android-jetpack-compose