【问题标题】:Android Jetpack Compose, How to get Semantics from Another Composable?Android Jetpack Compose,如何从另一个 Composable 获取语义?
【发布时间】: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


【解决方案1】:

你对#3 的想法是正确的。不过,您必须在顶层框中这样做。

val intercepter by remember { mutableStateOf(RequestDisallowInterceptTouchEvent()) }
    Box(modifier = Modifier.pointerInteropFilter(intercepter) { motionEvent -> true }) {content}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-01-05
    • 1970-01-01
    • 2023-02-16
    • 1970-01-01
    • 2021-02-19
    • 2022-09-25
    • 2023-01-24
    相关资源
    最近更新 更多