Alvin Dizon
07/02/2024, 1:54 PMTextInputLayout/TextInputEditText
(see image) to a Composable that looks like an OutlinedTextField
, but its label
should be within the outlines instead of being on the outlines themselves, when the user types something on the text field. I've come up with something that uses BasicTextField2
with TextFieldDefaults.DecorationBox
as its decorator:
@Composable
fun CustomTextField(
isError: Boolean,
textFieldState: TextFieldState,
labelResId: Int,
modifier: Modifier = Modifier
) {
val borderColor = if (isError) {
Error900
} else {
AccentBlue50
}
BasicTextField2(
modifier = modifier
.border(
width = 1.dp,
color = borderColor,
RoundedCornerShape(4.dp)
),
state = textFieldState,
lineLimits = TextFieldLineLimits.SingleLine,
textStyle = LocalTypography.current.body,
decorator = {
Column(Modifier.padding(4.dp)) {
TextFieldDefaults.DecorationBox(
value = textFieldState.text.toString(),
innerTextField = it,
enabled = true,
singleLine = true,
visualTransformation = VisualTransformation.None,
interactionSource = remember { MutableInteractionSource() },
isError = false,
label = {
Text(
stringResource(id = labelResId),
style = LocalTypography.current.body,
color = SandGray
)
},
leadingIcon = null,
trailingIcon = null,
colors =
TextFieldDefaults.colors(
focusedContainerColor = Color.White,
unfocusedContainerColor = Color.White,
focusedIndicatorColor = Color.Transparent,
unfocusedIndicatorColor = Color.Transparent,
focusedTextColor = DarkGray,
unfocusedTextColor = DarkGray
),
contentPadding = TextFieldDefaults.contentPaddingWithLabel(),
)
}
}
)
}
So far, it looks okay when unfocused, but I want the label to fully animate to its final position as soon as the text field gains focus (see video). This animation only happens when the user begins to type. Has anyone here done something similar?Alvin Dizon
07/02/2024, 1:58 PMAlvin Dizon
07/03/2024, 3:05 AMDecorationBox
, and just controlling the visibility of two Texts
as label and placeholder:
@Composable
fun CustomTextField(
isError: Boolean,
textFieldState: TextFieldState,
labelResId: Int,
modifier: Modifier = Modifier
) {
val borderColor = if (isError) Error900 else AccentBlue50
var isPlaceholderVisible by remember { mutableStateOf(true) }
Box(
modifier = modifier
.onFocusChanged { if (it.isFocused) isPlaceholderVisible = false }
.border(width = 1.dp, color = borderColor, RoundedCornerShape(4.dp))
.padding(vertical = 14.dp, horizontal = 15.dp)
,
contentAlignment = Alignment.Center
) {
if (isPlaceholderVisible) {
Text(
modifier = Modifier
.fillMaxWidth().padding(bottom = 2.dp),
text = stringResource(id = labelResId),
style = LocalTypography.current.body,
color = SandGray,
textAlign = TextAlign.Start
)
}
Column(horizontalAlignment = Alignment.Start) {
if (!isPlaceholderVisible) {
Text(
modifier = Modifier
.fillMaxWidth(),
text = stringResource(id = labelResId),
style = LocalTypography.current.smallNormal,
color = SandGray,
textAlign = TextAlign.Start
)
}
BasicTextField2(
modifier = Modifier.fillMaxWidth(),
state = textFieldState,
lineLimits = TextFieldLineLimits.SingleLine,
textStyle = LocalTypography.current.body
)
}
}
}