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
)
}
}
}