【问题标题】:Detect click in Compose TextField检测 Compose TextField 中的点击
【发布时间】:2021-05-11 19:44:01
【问题描述】:

我正在尝试为 Compose TextField 实现 onClick 处理程序。当前功能是处理 TextField 单击但禁用手动编辑该字段。对于我的用例,我想处理点击并做其他事情。我想保持 TextField 的外观和感觉,并希望焦点动画也发生。

readOnly 属性从 UX 角度为我提供了我想要的东西,但是当我单击 TextField 时,不会调用 onClick 处理程序。

TextField(
  value = text,
  onValueChange = { text = it},
  readOnly = true,
  modifier = Modifier
    .clickable(onClick = {
      Log.i("TextField", "Clicked")
    })
)

我也尝试过使用pointerInput,我怎么也遇到了同样的问题。

TextField(
  value = text,
  onValueChange = { text = it},
  readOnly = true,
  modifier = Modifier
    .pointerInput(Unit) {
      detectTapGestures(onTap = {
        Log.i("TextField", "Clicked")
      }
    }
)

由于 Compose 如此新,很难判断这是一个错误还是有意为之。

【问题讨论】:

    标签: android kotlin android-jetpack-compose


    【解决方案1】:

    也许在文本字段中检测点击事件的更好方法是使用交互源。

    第 1 步:- 创建交互源

     val source = remember {
        MutableInteractionSource()
    }
    

    第 2 步:- 将其传递到文本字段

     OutlinedTextField(
        value = text,
        readOnly = true,
        onValueChange = {},
        textStyle = MaterialTheme.typography.body1.copy(
            lineHeight = if (isFocused) 25.sp else TextUnit.Unspecified,
            fontWeight = if (isFocused) FontWeight.SemiBold else FontWeight.Normal
        ),
        label = {
            Text(
                text = label,
                fontWeight = if (isFocused) FontWeight.SemiBold else FontWeight.Normal,
                style = MaterialTheme.typography.caption
            )
        },
        interactionSource = source,
        colors = TextFieldDefaults.outlinedTextFieldColors(
            textColor = if (isFocused) MaterialTheme.colors.primary else LocalContentColor.current
        ),
        maxLines = if (isFocused) Int.MAX_VALUE else 2,
        modifier = Modifier
            .padding(
                start = COUNTER_WIDTH + 16.dp,
                top = padding,
                bottom = padding,
                end = 16.dp
            )
            .fillMaxWidth()
            .verticalScroll(enabled = isFocused, state = rememberScrollState())
            .animateContentSize(animationSpec = tween(DURATION))
    )
    

    步骤:3- 收集压流作为状态并观察其变化。

     if ( source.collectIsPressedAsState().value)
            onClicked()
    

    【讨论】:

    • 恕我直言,这似乎是最准确的答案,没有任何副作用或解决方法。
    【解决方案2】:

    使用readOnly = trueTextField 仍处于启用状态,并且第一次单击会将焦点移至该字段。你必须双击来处理你的onClick函数。

    否则你可以使用enabled属性:

       TextField(
            enabled = false,
            modifier = Modifier.clickable(onClick = {/* ... */})
        )
    

    类似:

    TextField(
        value = text,
        onValueChange = { text = it},
        enabled = false,
        modifier = Modifier
            .clickable { text= "Clicked"},
        colors = TextFieldDefaults.textFieldColors(
            disabledTextColor = LocalContentColor.current.copy(LocalContentAlpha.current),
            disabledLabelColor =  MaterialTheme.colors.onSurface.copy(ContentAlpha.medium)
        )
    )
    

    【讨论】:

    • 听起来我只需要想办法将文本和标签颜色恢复为非禁用。
    • @lostintranslation 是的。我已经用一个示例更新了答案,将disabledTextColordisabledLabelColor 恢复为默认的非禁用颜色。
    • 谢谢。出于好奇,有没有办法附加我自己的在使用 readOnly 时有效的点击处理程序?我试图沿着这条路线走,但没有取得多大成功。
    • @lostintranslation 抱歉,我只能在字段中双击才能使用您的代码。
    猜你喜欢
    • 2020-01-10
    • 1970-01-01
    • 2021-03-04
    • 1970-01-01
    • 2021-11-14
    • 2022-11-21
    • 2022-06-15
    • 1970-01-01
    • 2020-07-21
    相关资源
    最近更新 更多