It`s padding is to large!what can i delete them?
TextField(
value = text,
textStyle = TextStyle(
color = Color.Red,
textDecoration = TextDecoration.None
),
onValueChange = {
text = it
},
placeholder = {
Text(text = "请输入设备序列号", color = Color.Gray)
},
singleLine = true,
activeColor = Color.Yellow,
modifier = Modifier.padding(1.dp),
backgroundColor = Color.Transparent
)
this is my code.please help me !
You can use BasicTextField to take control over it.
var value by rememberSaveable { mutableStateOf("") }
BasicTextField(
cursorBrush = SolidColor(Color.White),
value = value,
onValueChange = { value = it },
textStyle = TextStyle(color = Color.White),
decorationBox = { innerTextField ->
Row(modifier = Modifier.fillMaxWidth()) {
if (value.isEmpty()) {
Text(text = "Placeholder", color = Color.White)
}
}
innerTextField()
}
)
Related
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.
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
)
)
}
I'm trying to put a drop down for US states that uses a TextField and a TextField in a Row and the second TextField (zip) does not show up. What am I doing wrong?
Here is how I'm declaring the row:
Row (Modifier.fillMaxWidth()) {
StateSelection(
onFormChanged = onFormChanged,
selectedLocation = selectedLocation,
label = "State"
)
Spacer(modifier = Modifier.width(8.dp))
ShippingField(
modifier = modifier,
onFormChanged = onFormChanged,
formType = FormType.SHIPPING_ZIP,
label = "Zip",
valueField = selectedLocation.zipCode
)
}
StatesDropDown:
#Composable
fun StateSelection(
onFormChanged: (FormType, String) -> Unit,
selectedLocation: Address,
label: String
) {
// State variables
val statesMap = AddressUtils.mapOfAmericanStatesToValue
var stateName: String by remember { mutableStateOf(selectedLocation.shippingState) }
var expanded by remember { mutableStateOf(false)}
val focusManager = LocalFocusManager.current
Box(contentAlignment = Alignment.CenterStart) {
Row(
Modifier
.padding(vertical = 8.dp)
.clickable {
expanded = !expanded
}
.padding(8.dp),
horizontalArrangement = Arrangement.Start,
verticalAlignment = Alignment.CenterVertically
) { // Anchor view
TextField(
modifier = Modifier
.fillMaxWidth(),
value = stateName,
onValueChange = {
onFormChanged(FormType.SHIPPING_COUNTRY, it)
},
label = { Text(text = label) },
textStyle = MaterialTheme.typography.subtitle1,
singleLine = true,
trailingIcon = {
IconButton(onClick = { expanded = true }) {
Icon(imageVector = Icons.Filled.ArrowDropDown, contentDescription = "")
}
},
keyboardActions = KeyboardActions(onNext = { focusManager.moveFocus(FocusDirection.Down) }),
keyboardOptions = KeyboardOptions(
imeAction = ImeAction.Done,
keyboardType = KeyboardType.Text
),
colors = TextFieldDefaults.textFieldColors(
cursorColor = MaterialTheme.colors.secondary,
textColor = MaterialTheme.colors.onPrimary,
focusedIndicatorColor = MaterialTheme.colors.secondary,
backgroundColor = MaterialTheme.colors.secondaryVariant
)
) // state name label
DropdownMenu(expanded = expanded, onDismissRequest = {
expanded = false
}) {
statesMap.asIterable().iterator().forEach {
val (key, value) = it
DropdownMenuItem(onClick = {
expanded = false
stateName = key
onFormChanged(FormType.SHIPPING_STATE, key)
},
modifier = Modifier.fillMaxWidth()) {
Text(text = key)
}
}
}
}
}
}
ZipCode:
#Composable
fun ShippingField(
modifier: Modifier,
onFormChanged: (FormType, String) -> Unit,
formType: FormType,
label: String,
valueField: String
) {
val focusManager = LocalFocusManager.current
var state by rememberSaveable {
mutableStateOf(valueField)
}
TextField(modifier = modifier
.background(MaterialTheme.colors.primaryVariant)
.fillMaxWidth(),
value = state,
onValueChange = {
state = it
onFormChanged(formType, it)
},
label = { Text(text = label) },
textStyle = MaterialTheme.typography.subtitle1,
singleLine = true,
keyboardActions = KeyboardActions(onNext = { focusManager.moveFocus(FocusDirection.Down) }),
keyboardOptions = KeyboardOptions(
imeAction = ImeAction.Next,
keyboardType = KeyboardType.Text
),
colors = TextFieldDefaults.textFieldColors(
cursorColor = MaterialTheme.colors.secondary,
textColor = MaterialTheme.colors.onPrimary,
focusedIndicatorColor = MaterialTheme.colors.secondary,
backgroundColor = MaterialTheme.colors.secondaryVariant
)
)
}
Row (Modifier.fillMaxWidth()) {
StateSelection(
modifier = Modifier.weight(1f)
...
)
Spacer(modifier = Modifier.width(8.dp))
ShippingField(
modifier = Modifier.weight(1f),
...
)
}
You should do it like above, and then pass the modifier to your composables below. Weight distributes and fills max width evenly on your composables
You have to remove the modifier = Modifier.fillMaxWidth() in the 1st TextField in the StatesDropDown composable.
I've developed a textInput composable with a trailing icon, and I'd like to clear the textInput when the icon is clicked. How can I access the textInput value, so that I can clear it?
#Composable
fun TextInput(
myVal: String,
label: String,
placeholder: String="",
helperText: String="",
errorText: String="",
onValueChange : (String) -> Unit){
val hasError = !errorText.isNullOrEmpty()
val helperColor = if (hasError)
Color(0xFFfe392f)
else
Color(0xFF5c6a79)
Row() {
Column() {
TextField(
colors = TextFieldDefaults.textFieldColors(
backgroundColor = Color.Transparent,
textColor = Color(0xFF011e41),
cursorColor = Color(0xFF011e41),
focusedLabelColor = Color(0xFF011e41),
unfocusedLabelColor = Color(0xFF011e41),
unfocusedIndicatorColor = Color(0xFFebeced),
focusedIndicatorColor = Color(0xFF011e41),
errorCursorColor = Color(0xFFfe392f),
errorIndicatorColor = Color(0xFFfe392f),
errorLabelColor = Color(0xFFfe392f)
),
value = myVal,
onValueChange = onValueChange,
label = { Text(label) },
placeholder = { Text(placeholder) },
isError = hasError,
trailingIcon = {Icon(Icons.Filled.Email, contentDescription = "sdsd", modifier = Modifier.offset(x= 10.dp).clickable {
//What should I do here?
})}
)
Text(
modifier = Modifier.padding(8.dp),
text = if (hasError) errorText else helperText,
fontSize = 12.sp,
color = helperColor,
)
}
}
}
it's used like this:
var text by remember { mutableStateOf("") }
TextInput(myVal = text, label = "label", helperText = "", errorText = "my error") {text = it}
You can use the trailingIcon attribute with a custom clickable modifier.
Something like:
var text by rememberSaveable { mutableStateOf("") }
TextField(
value = text,
onValueChange = { text = it },
trailingIcon = {
Icon(Icons.Default.Clear,
contentDescription = "clear text",
modifier = Modifier
.clickable {
text = ""
}
)
}
)
If you are using a TextFieldValue:
val content = "content"
var text by rememberSaveable(stateSaver = TextFieldValue.Saver) {
mutableStateOf(TextFieldValue(content))
}
TextField(
value = text,
onValueChange = { text = it },
trailingIcon = {
Icon(Icons.Default.Clear,
contentDescription = "clear text",
modifier = Modifier
.clickable {
text = TextFieldValue("")
}
)
}
)
the click handler of your trailing icon has to call the TextField's onValueChange with an empty string:
...
trailingIcon = {
Icon(
Icons.Filled.Email,
contentDescription = "sdsd",
modifier = Modifier
.offset(x= 10.dp)
.clickable {
//just send an update that the field is now empty
onValueChange("")
}
)
}
...
Use trailingIcon Composable property with IconButton to match the background selector of the icon with the rest of the theme. You can also put empty condition to display it only when there is some input in the text field.
Below is sample code snippet:
var text by remember { mutableStateOf ("") }
TextField(
trailingIcon = {
when {
text.isNotEmpty() -> IconButton(onClick = {
text = ""
}) {
Icon(
imageVector = Icons.Filled.Clear,
contentDescription = "Clear"
)
}
}
}
)
This shall achieve this
//Caller
val text by remember { mutableStateOf (...) }
TextInput(text, ..., ...,)
//Composable
#Composable
fun TextInput(text, ..., ...){
val textState by remember { mutableStateOf (text) }
TextField(
value = textState,
trailingIcon = {
Icon(..., Modifier.clickable { textState = "" })
}
}
I have a Jetpack Compose (Beta04) BasicTextField (with decorationBox). How can I clear the focus?
I have tried with focusRequester but this doesn't works:
val focusRequester = remember { FocusRequester() }
// ...
BasicTextField(modifier = Modifier.focusRequester(focusRequester), /* ... */)
// ...
placesFocusRequester.freeFocus()
To clear focus from the currently focused component you can use the FocusManager.clearFocus method:
val focusRequester = remember { FocusRequester() }
val focusManager = LocalFocusManager.current
var value by rememberSaveable { mutableStateOf("initial value") }
BasicTextField(
value = value,
onValueChange = { value = it },
decorationBox = { innerTextField ->
Row(
Modifier
.background(Color.LightGray, RoundedCornerShape(percent = 30))
.padding(16.dp)
.focusRequester(focusRequester)
) {
//...
innerTextField()
}
}
)
Button(onClick = { focusManager.clearFocus() }) {
Text("Clear focus")
}
#Composable
fun InputEditText(
value: String,
modifier: Modifier,
onValueChange: (String) -> Unit,
textStyle: TextStyle, hintTextStyle:
TextStyle, placeHolderString: String = "",
enabled: Boolean = true, readOnly: Boolean = false,
singleLine: Boolean = false,
maxLines: Int = Int.MAX_VALUE,
keyboardOptions: KeyboardOptions = KeyboardOptions.Default,
keyboardActions: KeyboardActions = KeyboardActions.Default,
cursorColor: Color = Color.Black,
imageVector: ImageVector,
iconTint: Color = Color.Gray,
backColor: Color = Color.White,
borderColor: Color = Color.LightGray,
showPassword: Boolean = false,
backGroundShape: Shape = RectangleShape,
passwordVisible: MutableState,
error: String,
howError: Boolean = false
) {
BasicTextField(
visualTransformation = if (showPassword) {
if (!passwordVisible.value) VisualTransformation.None else PasswordVisualTransformation()
} else { VisualTransformation.None },
value = value,
onValueChange = onValueChange,
modifier = modifier,
textStyle = textStyle,
decorationBox = { innerTextField ->
Column {
Row(
modifier = Modifier
.background(backColor, backGroundShape)
.border( width = 1.dp, color = if (showError) Color.Red else borderColor, backGroundShape )
.padding(14.dp)
.fillMaxWidth(),
horizontalArrangement = Arrangement.Start,
verticalAlignment = CenterVertically
) {
Icon(
imageVector = imageVector,
contentDescription = null,
tint = iconTint,
modifier = Modifier.padding(end = 6.dp)
)
if (value.isEmpty()) {
Text(
text = placeHolderString,
color = hintTextStyle.color,
fontSize = hintTextStyle.fontSize,
fontStyle = hintTextStyle.fontStyle,
fontFamily = hintTextStyle.fontFamily,
textAlign = hintTextStyle.textAlign,
fontWeight = hintTextStyle.fontWeight,
style = hintTextStyle
)
}
innerTextField()
if (showPassword) {
Column(
modifier = Modifier.fillMaxWidth(),
verticalArrangement = Arrangement.Bottom,
horizontalAlignment = Alignment.End
) {
Image(
painter = painterResource(
id = if (!passwordVisible.value)
R.drawable.ic_baseline_visibility_off_24
else R.drawable.ic_baseline_visibility_24
),
contentDescription = "Cart button icon",
modifier = Modifier
.size(24.dp)
.clickable {
passwordVisible.value = !passwordVisible.value
},
colorFilter = ColorFilter.tint(color = iconTint)
)
}
}
if (showError) {
Column(
modifier = Modifier.fillMaxWidth(),
verticalArrangement = Arrangement.Bottom,
horizontalAlignment = Alignment.End
) {
Icon(
imageVector = Icons.Filled.Info,
contentDescription = null,
tint = Color.Red,
modifier = Modifier.padding(end = 6.dp)
)
}
}
}
if (showError) {
Row(modifier = Modifier.fillMaxWidth()) {
Text(
text = error,
modifier = Modifier.fillMaxWidth(),
style = TextStyle(
color = Color.Red,
fontFamily = FontFamily.SansSerif,
fontSize = 11.sp,
textAlign = TextAlign.Start,
)
)
}
}
}
},
enabled = enabled,
readOnly = readOnly,
singleLine = singleLine,
maxLines = maxLines,
keyboardOptions = keyboardOptions,
keyboardActions = keyboardActions,
cursorBrush = SolidColor(cursorColor)
)
}