Removing default padding from TextField in version 1.2.0 includeFontPadding - android

compose_version = 1.2.0
kotlin 1.7.0
I am trying to remove the TextField. As I am using it with a trailing icon. So I can't use the BasicTextField as it doesn't have the trailing icon.
I am using version 1.2.0 and I was thinking that the includeFontPadding was false by default. However, that didn't work. So I tried to explicitly try and set it as follows:
textStyle = TextStyle(
platformStyle = PlatformTextStyle(
includeFontPadding = true
))
However, this didn't work either. So just wondering about the version 1.2.0 and removing the default padding.
Column(modifier = Modifier
.fillMaxWidth()
.background(color = Color.White)
.border(width = 2.dp, shape = RoundedCornerShape(4.dp), color = Color.LightGray)
.height(56.dp)) {
Text(
modifier = Modifier
.fillMaxWidth()
.padding(start = 16.dp),
text = "Gender (optional)")
TextField(
textStyle = TextStyle(
platformStyle = PlatformTextStyle(
includeFontPadding = true
)),
colors = TextFieldDefaults.textFieldColors(backgroundColor = Color.White),
modifier = Modifier
.fillMaxWidth(),
value = rememberMobileCode,
onValueChange = { newMobileCode ->
rememberMobileCode = newMobileCode
},
trailingIcon = {
Icon(dropdownIcon, contentDescription = "dropdown icon", modifier = Modifier.clickable {
rememberIsExpanded = !rememberIsExpanded
})
},
singleLine = true,
readOnly = true
)
}

Starting with 1.2.0 you can use the BasicTextField + TextFieldDecorationBox.
You can set the trailingIcon and you can use the contentPadding attribute to change the paddings:
val colors = TextFieldDefaults.textFieldColors()
BasicTextField(
value = text,
onValueChange = { text = it },
modifier = Modifier
.fillMaxWidth()
.background(
color = colors.backgroundColor(enabled).value,
shape = RoundedCornerShape(8.dp)
),
interactionSource = interactionSource,
enabled = enabled,
singleLine = singleLine
) {
TextFieldDefaults.TextFieldDecorationBox(
value =text,
innerTextField = it,
singleLine = singleLine,
enabled = enabled,
visualTransformation = VisualTransformation.None,
label = { Text(text = "label") },
trailingIcon = {
IconButton(onClick = { }) {
Icon(imageVector = Icons.Filled.Clear, contentDescription = "Clear")
}
},
placeholder = { /* ... */ },
interactionSource = interactionSource,
// change the padding
contentPadding = TextFieldDefaults.textFieldWithoutLabelPadding(
top = 2.dp, bottom = 2.dp
)
)
}

Related

Extra inner padding in TextField in jetpack compose

I have a TextField to enter the amount as follows:
#OptIn(ExperimentalMaterialApi::class)
#Composable
fun AmountTextField(
modifier: Modifier,
sendMoneyViewModel: SendMoneyViewModel,
isReadOnly: Boolean,
focusManager: FocusManager
) {
val paymentAmount = sendMoneyViewModel.paymentAmount.collectAsState()
val focusRequester = remember { FocusRequester() }
LaunchedEffect(Unit) {
focusRequester.requestFocus()
}
val interactionSource = remember { MutableInteractionSource() }
Row(
modifier = modifier,
horizontalArrangement = Arrangement.Center,
verticalAlignment = Alignment.CenterVertically
) {
Spacer(modifier = Modifier.weight(1f))
Text(
modifier = Modifier.wrapContentWidth(),
text = stringResource(id = R.string.rupee_symbol),
color = Black191919,
fontSize = 36.sp,
fontFamily = composeFontFamily,
fontWeight = getFontWeight(FontWeightEnum.EXTRA_BOLD)
)
BasicTextField(
modifier = Modifier
.focusRequester(focusRequester)
.background(color = YellowFFFFEAEA)
.height(IntrinsicSize.Min)
.width(IntrinsicSize.Min)
.clipToBounds(),
value = paymentAmount.value,
onValueChange = {
sendMoneyViewModel.onAmountValueChanged(it)
},
interactionSource = interactionSource,
visualTransformation = CurrencyMaskTransformation(SendMoneyViewModel.AMOUNT_MAX_LENGTH),
singleLine = true,
textStyle = TextStyle(
color = Black191919,
fontSize = 36.sp,
fontFamily = composeFontFamily,
fontWeight = getFontWeight(FontWeightEnum.EXTRA_BOLD),
textAlign = TextAlign.Center
),
keyboardActions = KeyboardActions(onDone = {
if (paymentAmount.value.isNotBlank()) {
focusManager.moveFocus(FocusDirection.Next)
}
}),
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Number, autoCorrect = false, imeAction = ImeAction.Next
),
readOnly = isReadOnly
) {
TextFieldDefaults.TextFieldDecorationBox(
value = paymentAmount.value,
visualTransformation = CurrencyMaskTransformation(SendMoneyViewModel.AMOUNT_MAX_LENGTH),
innerTextField = it,
singleLine = true,
enabled = !isReadOnly,
interactionSource = interactionSource,
contentPadding = PaddingValues(0.dp),
placeholder = { AmountFieldPlaceholder() },
colors = TextFieldDefaults.textFieldColors(
backgroundColor = Color.Transparent,
cursorColor = Color.Black,
focusedIndicatorColor = Color.Transparent,
unfocusedIndicatorColor = Color.Transparent
)
)
}
Spacer(modifier = Modifier.weight(1f))
}
}
#Composable
fun AmountFieldPlaceholder() {
Box(modifier = Modifier.fillMaxWidth(), contentAlignment = Alignment.Center) {
Text(
modifier = Modifier
.wrapContentWidth()
.align(Alignment.Center),
text = "0",
fontSize = 36.sp,
fontFamily = composeFontFamily,
fontWeight = getFontWeight(FontWeightEnum.EXTRA_BOLD),
color = GreyE3E5E5,
textAlign = TextAlign.Center
)
}
}
Initially it looks like this:
After typing "12", it's looking like this:
You can see that text "1" is cutting off.
Ideally it should look like this after typing 1234567:
But apart from actual text size, it has extra inner padding also from start and end. So it can be unexpectedly scrolled as follows:
Why TextField is having extra inner padding from start and end. Due to this, text is cutting while typing.
I have tried many solutions like:
Resizeable BasicTextField in Jetpack Compose
I also tried to set WindowInsets, but nothing is working.
I will suggest using View's EditText here since it provides lots of flexibility in terms of customization.
I have pasted the code on Paste Bin https://pastebin.com/Z1hS7xns
Update: wrap buildAmountEditText() with remember{} otherwise it'll be created every time there's new message string
#Composable
fun AmountTextField(
amount: String,
onAmountChange: (String) -> Unit
) {
Row(
horizontalArrangement = Arrangement.SpaceAround,
verticalAlignment = Alignment.CenterVertically
) {
Text(
text = stringResource(R.string.rupee_symbol),
style = MaterialTheme.typography.h2.copy(
color = Color(0xFF191919),
fontWeight = FontWeight.ExtraBold
)
)
val titleField = remember {
buildAmountEditText(
context = LocalContext.current,
amount = amount,
onAmountChange = onAmountChange,
placeholder = "0",
focusChangeListener = { _, hasFocus ->
// do something with focus
},
paddingValues = PaddingValues(0)
)
}
AndroidView(factory = { titleField })
}
}
Remove singleLine property or set it as false. This is the simplest solution.

TextField is cutting text at the bottom because default padding

I almost completely successfully implemented the custom search component I needed, but I have one last problem. I need my component to be only 45dp to match the designer's requirements, but at that height, due to the TextField padding, it's clipping the text on top. I leave you below a screenshot of what is happening and the code I have. Is there any way to resolve this?
I'm new to Jetpack Compose and that's all I need to close this component.
#Preview
#Composable
fun SearchTextField() {
val state = remember { mutableStateOf(TextFieldValue("")) }
TextField(
value = state.value,
onValueChange = { value -> state.value = value },
textStyle = TextStyle18Normal,
placeholder = {
Text(text = stringResource(id = R.string.search), style = TextStyle18Normal)
},
trailingIcon = {
Image(
painter = painterResource(id = R.drawable.ic_search),
contentDescription = ""
)
},
singleLine = true,
shape = RoundedCornerShape(Dimen13),
colors = TextFieldDefaults.textFieldColors(
cursorColor = Color.DarkGray,
trailingIconColor = colorResource(id = R.color.purple),
backgroundColor = Color.White,
focusedIndicatorColor = Color.Transparent,
unfocusedIndicatorColor = Color.Transparent,
disabledIndicatorColor = Color.Transparent
),
modifier = Modifier
.width(Dimen320)
.height(Dimen45)
)
}
If I remove the .height(45) my problem is solved, but the component is not correct.
The TextField has hardcoded paddings.
Starting with 1.2.0 you can use the BasicTextField together with the TextFieldDecorationBox. With the contentPadding attribute you can define custom vertical paddings.
Something like:
val colors = TextFieldDefaults.textFieldColors(backgroundColor = White)
BasicTextField(
value = value,
onValueChange = onValueChange,
textStyle = TextStyle.Default.copy(fontSize = 18.sp),
modifier = modifier
.background(
color = colors.backgroundColor(enabled).value,
shape = RoundedCornerShape(13.dp). //rounded corners
)
.indicatorLine(
enabled = enabled,
isError = false,
interactionSource = interactionSource,
colors = colors,
focusedIndicatorLineThickness = 0.dp, //to hide the indicator line
unfocusedIndicatorLineThickness = 0.dp //to hide the indicator line
)
.height(45.dp),
interactionSource = interactionSource,
enabled = enabled,
singleLine = singleLine
) {
TextFieldDefaults.TextFieldDecorationBox(
value = value,
innerTextField = it,
singleLine = singleLine,
enabled = enabled,
visualTransformation = VisualTransformation.None,
trailingIcon = { /* ... */ },
placeholder = { /* ... */ },
interactionSource = interactionSource,
// keep horizontal paddings but change the vertical
contentPadding = TextFieldDefaults.textFieldWithoutLabelPadding(
top = 0.dp, bottom = 0.dp
)
)
}

BasicTextField doesn't move up title on focus

Hi this is my BasicTextField :
fun TextFieldRow(data: TextFieldData) {
val interactionSource = remember { MutableInteractionSource() }
val text by data.text.observeAsState("")
Row(
modifier = Modifier
.fillMaxWidth()
.padding(start = 20.dp, end = 20.dp, top = 17.dp)
) {
BasicTextField(
value = text,
onValueChange = {
data.text.value = it
},
modifier = Modifier
.padding(vertical = 6.dp)
.fillMaxWidth()
.indicatorLine(
enabled = true,
isError = false,
interactionSource = interactionSource,
colors = TextFieldDefaults.textFieldColors()
)
) { innerTextField ->
TextFieldDefaults.TextFieldDecorationBox(
value = text,
innerTextField = innerTextField,
enabled = true,
singleLine = true,
visualTransformation = VisualTransformation.None,
interactionSource = interactionSource,
contentPadding = TextFieldDefaults.textFieldWithLabelPadding(start = 4.dp),
label = { Text(text = data.label) }
)
}
}
}
I set the label in the TextFieldDecorationBox. It work well when I type some letters (the title goes up), but when I just take focus, the title stay in the middle. Any help ?
EDIT
I would like something like that, the reason why I use BasicTextField instead of TextField is because I want to manage padding.
You can change innerTextField like;
BasicTextField(
//
){ innerTextField ->
Box{
if(text.value.isEmpty())
Text(
text = "Title",
color = Color.Black.copy(alpha = 0.5f)
)
innerTextField()
}
}

Why BasicTextField (in compose) doesn't work well?

I'm trying to use BasicTextField with TextAlignment.End for RTL. it's my code:
val textState = remember { mutableStateOf(TextFieldValue("")) }
val shape = RoundedCornerShape(CornerSize(4.dp))
BasicTextField(
value = textState.value,
onValueChange = { newText -> textState.value = newText },
textStyle = LocalTextStyle.current.copy(
color = ColorPrimaryDarkText,
fontWeight = FontWeight.Medium,
textAlign = TextAlign.End,
fontSize = 14.sp,
),
maxLines = 1,
singleLine = true,
modifier = Modifier
.fillMaxWidth()
.padding(32.dp, 0.dp)
.clip(shape)
.background(color = Color.White),
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Text,
imeAction = ImeAction.Done
),
decorationBox = { innerTextField ->
Row(
modifier = Modifier
.fillMaxWidth()
.background(Color.White, shape)
.padding(8.dp),
) {
if (textState.value.text.isEmpty()) {
Text(
text = "hint",
textAlign = TextAlign.End,
fontWeight = FontWeight.Medium,
modifier = Modifier.fillMaxWidth(),
fontSize = 14.sp,
)
} else {
innerTextField()
}
}
}
)
it's OK when it's empty but it's not working well when you try to type anything (it's starting to type from center):
Remove the textAlign = TextAlign.End and use something like:
CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Rtl ) {
BasicTextField( /* your code */)
}
Otherwise if you want to use your code add horizontalArrangement = Arrangement.End in Row in the decorationBox parameter:
decorationBox = { innerTextField ->
Row(
modifier = Modifier
.fillMaxWidth()
.background(Color.White, shape)
.padding(8.dp),
horizontalArrangement = Arrangement.End){
//your code
}

How to remove indicator line of TextField in Androidx Compose Material?

I would like to remove the purple line/indicator (see the following image) of TextField.
Is that possible or should I create my own custom TextField to achieve that?
This has been changed in the recent Jetpack Compose UI Beta release 1.0.0-beta01 now you can pass the
TextFieldDefaults with desired colors.
colors = TextFieldDefaults.textFieldColors(
focusedIndicatorColor = Color.Transparent,
disabledIndicatorColor = Color.Transparent,
unfocusedIndicatorColor = Color.Transparent,
backgroundColor = Color.LightGray,
)
example
TextField(
value = searchText,
onValueChange = { Log.d(HOME_COMPONENT, it) },
label = { Text(text = "Search") },
shape = RoundedCornerShape(10.dp),
leadingIcon = {
Image(
painter = painterResource(id = R.drawable.ic_search),
contentDescription = "search"
)
},
colors = TextFieldDefaults.textFieldColors(
focusedIndicatorColor = Color.Transparent,
disabledIndicatorColor = Color.Transparent,
unfocusedIndicatorColor = Color.Transparent,
backgroundColor = Color.LightGray,
)
)
image:
or if you want to customize the component according to your UI/UX then use the BasicTextField
#Composable
fun ToolbarComponent() {
var searchText by remember { mutableStateOf("") }
Row(
modifier = Modifier
.padding(16.dp)
.fillMaxWidth(), verticalAlignment = Alignment.CenterVertically
) {
Icon(
painter = painterResource(id = R.drawable.ic_search),
contentDescription = "search",
modifier = Modifier.size(20.dp),
tint = iconTintColor
)
Spacer(modifier = Modifier.size(16.dp))
BasicTextField(
value = searchText,
onValueChange = { searchText = it },
modifier = Modifier
.background(shape = RoundedCornerShape(10.dp), color = Color.LightGray)
.fillMaxWidth()
.padding(16.dp),
decorationBox = {
Text(text = "Search")
}
)
}
}
Starting with 1.2.0-alpha04 you can use the TextFieldDecorationBox together with BasicTextField to build a custom text field based on Material Design text fields.
In your case you can apply the indicatorLine modifier to define the focusedIndicatorLineThickness and the unfocusedIndicatorLineThickness parameters:
var text by remember { mutableStateOf("") }
val singleLine = true
val enabled = true
val interactionSource = remember { MutableInteractionSource() }
BasicTextField(
value = text,
onValueChange = { text = it },
modifier = Modifier
.indicatorLine(enabled, false,
interactionSource,
TextFieldDefaults.textFieldColors(),
focusedIndicatorLineThickness = 0.dp,
unfocusedIndicatorLineThickness = 0.dp
)
.background(
TextFieldDefaults.textFieldColors().backgroundColor(enabled).value,
TextFieldDefaults.TextFieldShape
)
.width(TextFieldDefaults.MinWidth),
singleLine = singleLine,
interactionSource = interactionSource
) { innerTextField ->
TextFieldDecorationBox(
value = text,
innerTextField = innerTextField,
enabled = enabled,
singleLine = singleLine,
visualTransformation = VisualTransformation.None,
interactionSource = interactionSource,
label = { Text("Label") }
)
}
Otherwise you can use TextField defining these attributes:
focusedIndicatorColor
unfocusedIndicatorColor
disabledIndicatorColor
Something like:
TextField(
....
colors = TextFieldDefaults.textFieldColors(
backgroundColor = .....,
focusedIndicatorColor = Transparent,
unfocusedIndicatorColor = Transparent)
)
If You use TextField in that you can give the activeColor to Color.Transparent
Note: activeColor is not only for indicator, its for label bottom indicator and cursor
Ex:
var text: String by mutableStateOf("")
TextField(value = text, onValueChange = {
text = it
}, activeColor = Color.Transparent)
As per the document, activeColor is
activeColor the color of the label, bottom indicator and the cursor
when the text field is in focus
If you want to use your own you can try BaseTextField
Actually (version alpha 7) this is the easiest version I have found to remove Divider.
Set activeColor and inactiveColor to Color.Transparent in order to hide the indicator line under the TextField, whatever his state.
If you add only inactiveColor to Color.Transparent, the line will be invisible only when TextField is not focused
Add textStyle = TextStyle(color = Color.White) in order to display the color, whenever if the TextField is focused or not.
This solution will remove the line, but also the cursor indicator. It's not the best for the moment but it's also the alpha actually on Compose.
TextField(
value = MyValue,
onValueChange = { },
textStyle = TextStyle(color = Color.White),
activeColor = Color.Transparent,
inactiveColor = Color.Transparent,
shape = RoundedCornerShape(20)
)

Categories

Resources