我在 Jetpack Compose (1.4.2) 中设置了正常的
BasicTextField
。
如果我想粘贴之前复制的文本,该字段会出现在一个奇怪的位置(左上角)。我该如何解决这个问题?
更新:提供了
BasicTextField
实现的代码。
@Composable
fun CustomTextField(
value: String,
placeholder: String,
enabled: Boolean = true,
loading: Boolean = false,
keyboardType: KeyboardType,
update: ((String) -> Unit)? = null
) {
var focus by remember {
mutableStateOf(false)
}
BasicTextField(
value = value,
onValueChange = { new ->
update?.let {
it(new)
}
},
cursorBrush = SolidColor(Blue),
textStyle = MaterialTheme.typography.bodyMedium,
decorationBox = { inner ->
Box(
modifier = Modifier
.fillMaxWidth()
.padding(
start = 16.dp,
end = 16.dp
),
contentAlignment = Alignment.CenterStart
) {
if (value.isEmpty()) {
Text(
text = placeholder,
style = MaterialTheme.typography.bodyMedium,
color = Blue_2
)
} else {
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween,
modifier = Modifier
.fillMaxWidth()
) {
inner()
if (loading) {
Box(
modifier = Modifier
.padding(vertical = 24.dp, horizontal = 16.dp)
.size(16.dp)
) {
CircularProgressIndicator(
color = Blue_6
)
}
}
}
}
}
},
visualTransformation = if (keyboardType == KeyboardType.Password) PasswordVisualTransformation() else VisualTransformation.None,
keyboardOptions = KeyboardOptions(
keyboardType = keyboardType
),
enabled = enabled,
modifier = Modifier
.fillMaxWidth()
.shadow(
elevation = if (focus) 15.dp else 7.5.dp,
shape = RoundedCornerShape(16.dp),
clip = false,
ambientColor = Blue_6,
spotColor = Blue_6
)
.background(
if (focus) Focused else Not_Focused,
RoundedCornerShape(16.dp)
)
.height(60.dp)
.onFocusChanged {
focus = it.hasFocus
},
singleLine = true
)
}
问题出在您的占位符语句上,详细信息如下:
if (value.isEmpty()) {
Text(
text = placeholder,
style = MaterialTheme.typography.bodyMedium,
color = Blue
)
} else {
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween,
modifier = Modifier
.fillMaxWidth()
) {
//This inner function should not be a part of the value.isEmpty() condition
inner()
}
}
在
if (value.isEmpty())
条件下,您没有实现 inner()
文本字段功能。当您的文本为空时,文本字段不存在,并且粘贴菜单出现在坐标轴的原点(左上角)。
这是一个适合您的正确工作示例:
@Composable
fun CustomTextField(
value: String,
placeholder: String,
enabled: Boolean = true,
loading: Boolean = false,
keyboardType: KeyboardType,
update: ((String) -> Unit)? = null
) {
var focus by remember {
mutableStateOf(false)
}
BasicTextField(
value = value,
onValueChange = { new ->
update?.let {
it(new)
}
},
cursorBrush = SolidColor(Blue),
textStyle = MaterialTheme.typography.bodyMedium,
decorationBox = { inner ->
Box(
modifier = Modifier
.fillMaxWidth()
.padding(
start = 16.dp,
end = 16.dp
),
contentAlignment = Alignment.CenterStart
) {
inner()
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween,
modifier = Modifier
.fillMaxWidth()
) {
if (loading) {
Box(
modifier = Modifier
.padding(vertical = 24.dp, horizontal = 16.dp)
.size(16.dp)
) {
CircularProgressIndicator(
color = Blue
)
}
}
}
if (value.isEmpty()) {
Text(
text = placeholder,
style = MaterialTheme.typography.bodyMedium,
color = Blue
)
}
}
},
visualTransformation = if (keyboardType == KeyboardType.Password) PasswordVisualTransformation() else VisualTransformation.None,
keyboardOptions = KeyboardOptions(
keyboardType = keyboardType
),
enabled = enabled,
modifier = Modifier
.fillMaxWidth()
.shadow(
elevation = if (focus) 15.dp else 7.5.dp,
shape = RoundedCornerShape(16.dp),
clip = false,
ambientColor = Blue,
spotColor = Blue
)
.background(
if (focus) Color.Cyan else Color.Green,
RoundedCornerShape(16.dp)
)
.height(60.dp)
.onFocusChanged {
focus = it.hasFocus
},
singleLine = true
)
}
正如Merkost所说,你应该每次都使用Textfield的inner()函数
但是如果您希望该字段不可见,您可以使用零高度的布局可组合项进行换行。例如:
BasicTextField(...) { innerTextField ->
Box(modifier = Modifier.height(0.dp)) {
innerTextField()
}
...
}