I want to customize TextField
composable in Jetpack Compose. I am trying to achieve the result in the image below, but somehow TextField
has some default paddings which i couldn't find how to change values of. I want to remove default paddings and customize it
(The image on the right one is the result i achieved. I drew a border so that you can see it has padding, btw below that TextField
are just Text
composables, they aren't TextFields
)
Below is my TextField
code
TextField(
value = "",
onValueChange = {},
modifier = Modifier
.weight(1F)
.padding(0.dp)
.border(width = 1.dp, color = Color.Red),
placeholder = {
Text(
"5555 5555 5555 5555", style = TextStyle(
color = Color.Gray
)
)
},
colors = TextFieldDefaults.textFieldColors(
backgroundColor = Color.Transparent,
unfocusedIndicatorColor = Color.Transparent,
focusedIndicatorColor = Color.Transparent
),
)
If you want to change the state of TextField and also update the UI, you can use a MutableState . Compose observes any reads and writes to the MutableState object and triggers a recomposition to update the UI.
A LazyColumn is a vertically scrolling list that only composes and lays out the currently visible items. It's similar to a Recyclerview in the classic Android View system.
To read value entered in TextField in Android Compose, declare a variable, and assign this variable the value in the TextField whenever there is a change in the value. The same process holds for reading value entered in OutlineTextField composable.
remember can be used to store both mutable and immutable objects. Note: remember stores objects in the Composition, and forgets the object when the composable that called remember is removed from the Composition.
You can use BasicTextField
, it's a plain text field without any decorations. Note that it doesn't have placeholder/hint too, you have to implement those by yourself if you need.
BasicTextField(value = "", onValueChange = {}, Modifier.fillMaxWidth())
Since 1.2.0-alpha04 it's much easier to make your BasicTextField
look like TextField
or OutlinedTextField
. You can copy source code of TextField
, which is pretty short since most of logic was moved into TextFieldDefaults.TextFieldDecorationBox
, and pass the needed padding value into contentPadding
parameter of TextFieldDefaults.TextFieldDecorationBox
.
In the latest alpha release (androidx.compose.material:material:1.2.0-alpha04) they exposed TextFieldDefaults.TextFieldDecorationBox
.
This is the implementation of the decorationBox
composable used in the material TextField
implementation.
You can use it as follows:
val interactionSource = remember { MutableInteractionSource() }
BasicTextField(
value = value,
onValueChange = onValueChange,
modifier = modifier,
visualTransformation = visualTransformation,
interactionSource = interactionSource,
enabled = enabled,
singleLine = singleLine,
) { innerTextField ->
TextFieldDefaults.TextFieldDecorationBox(
value = value,
visualTransformation = visualTransformation,
innerTextField = innerTextField,
singleLine = singleLine,
enabled = enabled,
interactionSource = interactionSource,
contentPadding = PaddingValues(0.dp), // this is how you can remove the padding
)
}
This will allow you to remove the padding but still get the rest of the features that come with TextField
.
Remember to use the same MutableInteractionSource
for both the BasicTextField
and the TextFieldDefaults.TextFieldDecorationBox
.
The official documentation I linked to above shows more examples if its usage.
Thank you all, i did use BasicTextField and achieved the result i wanted :)
@Composable
fun BottomOutlineTextField(placeholder: String, value: String, onValueChange: (String) -> Unit) {
BasicTextField(
modifier = Modifier.fillMaxWidth(),
value = value,
onValueChange = onValueChange,
textStyle = TextStyle(
color = if (isSystemInDarkTheme()) Color(0xFF969EBD) else Color.Gray
),
decorationBox = { innerTextField ->
Row(modifier = Modifier.fillMaxWidth()) {
if (value.isEmpty()) {
Text(
text = placeholder,
color = if (isSystemInDarkTheme()) Color(0xFF969EBD) else Color.Gray,
fontSize = 14.sp
)
}
}
innerTextField()
}
)
}
I wanted to cut off the 16.dp at the start. I managed to this in the following way:
BoxWithConstraints(modifier = Modifier
.clipToBounds()
) {
TextField(modifier = Modifier
.requiredWidth(maxWidth+16.dp)
.offset(x=(-8).dp))
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With