Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

remove default padding on jetpack compose textfield

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)

enter image description here enter image description here

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
    ),
)
like image 349
nesibeyyubov Avatar asked Jul 31 '21 07:07

nesibeyyubov


People also ask

What is Mutablestateof in jetpack compose?

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.

What is LazyColumn in jetpack compose?

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.

How do I get TextField value in jetpack compose?

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.

When to Use remember jetpack compose?

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.


4 Answers

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.

like image 150
Philip Dukhov Avatar answered Oct 24 '22 02:10

Philip Dukhov


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.

like image 29
jeran Avatar answered Oct 24 '22 04:10

jeran


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()
        }
    )
}
like image 32
nesibeyyubov Avatar answered Oct 24 '22 02:10

nesibeyyubov


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))
}
like image 2
Pepijn Avatar answered Oct 24 '22 03:10

Pepijn