los*_*ion 22 android kotlin android-jetpack-compose android-compose-textfield
我正在尝试为 Compose TextField 实现 onClick 处理程序。当前功能是处理文本字段单击,但禁用手动编辑字段。对于我的用例,我想处理点击并执行其他操作。我想保持 TextField 的外观和感觉,并希望焦点动画也能发生。
readOnly 属性为我提供了从 UX 角度来看我想要的内容,但是当我单击 TextField 时,不会调用 onClick 处理程序。
TextField(
value = text,
onValueChange = { text = it},
readOnly = true,
modifier = Modifier
.clickable(onClick = {
Log.i("TextField", "Clicked")
})
)
Run Code Online (Sandbox Code Playgroud)
我也尝试过使用pointerInput,我怎么也遇到同样的问题。
TextField(
value = text,
onValueChange = { text = it},
readOnly = true,
modifier = Modifier
.pointerInput(Unit) {
detectTapGestures(onTap = {
Log.i("TextField", "Clicked")
}
}
)
Run Code Online (Sandbox Code Playgroud)
由于 Compose 如此之新,很难判断这是一个错误还是有意为之。
Gab*_*tti 19
使用readOnly = true
仍TextField
处于启用状态,第一次单击会将焦点移至该字段。您必须执行双击才能处理您的onClick
功能。
否则你可以使用该enabled
属性:
TextField(
enabled = false,
modifier = Modifier.clickable(onClick = {/* ... */})
)
Run Code Online (Sandbox Code Playgroud)
就像是:
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)
)
)
Run Code Online (Sandbox Code Playgroud)
Zak*_*ikh 18
也许检测文本字段中的点击事件的更好方法是使用交互源。
步骤 1: -创建交互源
val source = remember {
MutableInteractionSource()
}
Run Code Online (Sandbox Code Playgroud)
第 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))
)
Run Code Online (Sandbox Code Playgroud)
步骤:3-收集加压流量作为状态并观察其变化。
if ( source.collectIsPressedAsState().value)
onClicked()
Run Code Online (Sandbox Code Playgroud)
use*_*924 12
正确的答案是使用interactions
ofInteractionSource
而不是collectIsPressedAsState
!最后一个只是检查您何时点击某物,但它忽略了您甚至没有松开手指的事实
TextField(
value = ...,
onValueChange = { ... },
interactionSource = remember { MutableInteractionSource() }
.also { interactionSource ->
LaunchedEffect(interactionSource) {
interactionSource.interactions.collect {
if (it is PressInteraction.Release) {
// works like onClick
}
}
}
}
)
Run Code Online (Sandbox Code Playgroud)
对我来说,最重要的答案似乎有一个主要问题。
if ( source.collectIsPressedAsState().value)
onClicked()
Run Code Online (Sandbox Code Playgroud)
onClicked()
即使按下也会触发,canceled
因为您没有等待按下后看到结束状态。当您滚动时,如果您的触摸位置与文本字段相同,则会触发 onClick,我确信 99% 的情况下这都是不需要的交互。
val pressedState=source.interactions.collectAsState(
initial = PressInteraction.Cancel(PressInteraction.Press(Offset.Zero)))
if (pressedState.value is PressInteraction.Release)
{
dropDownExpanded.value = true
onClick?.invoke()
source.tryEmit(PressInteraction.Cancel(PressInteraction.Press(Offset.Zero)))
}
Run Code Online (Sandbox Code Playgroud)
如果你这样做,它会消除滚动时不需要的 onClick
归档时间: |
|
查看次数: |
11861 次 |
最近记录: |