I have setup a normal BasicTextField
in Jetpack Compose (1.4.2).
If i want to paste a text copied earlier the field appears in a weird spot (top left corner). How can i fix this ?
Update: Provided code for BasicTextField
implementation.
@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
)
}
The problem is with your placeholder statement, here are the details:
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()
}
}
With if (value.isEmpty())
condition you are not implementing inner()
textfield function. While your text is empty the textfield does not exist and paste menu appears at the origin of the coordinate axis (top left corner).
Here is a properly working example for you:
@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
)
}