Is there a way to show "italic, "bold", "underline" buttons on Android keyboard? - android

I am working on an Android app in compose,
When writing text, I need to show a keaybord that has the "underline", "italic" and "bold" buttons present on top of the keyboard text.
Is there a way I can do that?
Currently, this is what I have:
val keyboardController = LocalSoftwareKeyboardController.current
var textValue by remember { mutableStateOf(TextFieldValue("Write your text...")) }
TextField(
value = textValue,
modifier = Modifier
.padding(16.dp)
.fillMaxWidth(),
placeholder = { Text(text = "John Doe") },
textStyle = TextStyle(
color = Color.Gray,
fontSize = 20.sp,
// fontWeight = FontWeight.Bold,
// textDecoration = TextDecoration.Underline
),
// Update value of textValue with the latest value of the text field
onValueChange = {
textValue = it
},
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
keyboardActions = KeyboardActions(
onDone = {
keyboardController?.hide()
// do something here
}
) )

Related

how to remove underline of outlinedtextfield compose when its focused?

When i try to enter some inputs to text field, it draws underline, how to remove this underline without change any color of outlinedtextfield.
OutlinedTextField(modifier = Modifier
.fillMaxWidth()
.padding(16.dp),value = password,
onValueChange = {
password = it},
leadingIcon = { Icon(painter = painterResource(id = R.drawable.ic_baseline_vpn_key_24), contentDescription = "icon-content")},
trailingIcon = { IconButton(onClick = { passwordVisibility = !passwordVisibility }) {
Icon(painter = icon, contentDescription = "show-password")
}},
placeholder = { Text(text = "Password",
color = Color.LightGray)},
label = { BasicText(text = "Password")},
visualTransformation = if(passwordVisibility) VisualTransformation.None else PasswordVisualTransformation()
)
You should specify the keyboardType as Password to get rid of the text underline. You can do that by using KeyboardOptions:
OutlinedTextField(
modifier = Modifier
.fillMaxWidth()
.padding(16.dp),
value = password,
onValueChange = { password = it },
leadingIcon = {
Icon(
painter = painterResource(id = R.drawable.ic_baseline_vpn_key_24),
contentDescription = "icon-content"
)
},
trailingIcon = {
IconButton(onClick = { passwordVisibility = !passwordVisibility }) {
Icon(painter = icon, contentDescription = "show-password")
}
},
placeholder = {
Text(
text = "Password",
color = Color.LightGray
)
},
label = { BasicText(text = "Password") },
visualTransformation = if (passwordVisibility) VisualTransformation.None else PasswordVisualTransformation(),
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Password // HERE
),
)
This is the crucial change:
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Password
)
The underline text is not related to color of OutlinedTextField.
It is related to the keyboardType applied. The default value is KeyboardType.Text.
Just add in your in OutlinedTextField:
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Password)

How to align leadingIcon in OutlinedTextField of jetpack compose with the value/placeholder

I am new to jetpack compose, I want my app to load the Exo two light font so I override the material typography like this,
val exoTwoLight = FontFamily(
Font(R.font.exo_two_light),
Font(R.font.exo_two_light, FontWeight.Bold)
)
val exoTwoLightTypography = Typography(
h1 = TextStyle(
fontFamily = exoTwoLight,
fontWeight = FontWeight.Bold,
fontSize = 96.sp
),
h2 = TextStyle(
fontFamily = exoTwoLight,
fontWeight = FontWeight.Bold,
fontSize = 60.sp
),
h3 = TextStyle(
fontFamily = exoTwoLight,
fontWeight = FontWeight.Bold,
fontSize = 48.sp
),
h4 = TextStyle(
fontFamily = exoTwoLight,
fontWeight = FontWeight.Bold,
fontSize = 34.sp
),
h5 = TextStyle(
fontFamily = exoTwoLight,
fontWeight = FontWeight.Bold,
fontSize = 20.sp
),
h6 = TextStyle(
fontFamily = exoTwoLight,
fontWeight = FontWeight.Bold,
fontSize = 12.sp
),
subtitle1 = TextStyle(
fontFamily = exoTwoLight,
fontWeight = FontWeight.Normal,
fontSize = 16.sp
),
subtitle2 = TextStyle(
fontFamily = exoTwoLight,
fontWeight = FontWeight.Medium,
fontSize = 14.sp
),
body1 = TextStyle(
fontFamily = exoTwoLight,
fontWeight = FontWeight.Normal,
fontSize = 16.sp
),
body2 = TextStyle(
fontFamily = exoTwoLight,
fontWeight = FontWeight.Normal,
fontSize = 14.sp
),
button = TextStyle(
fontFamily = exoTwoLight,
fontWeight = FontWeight.Medium,
fontSize = 14.sp,
),
caption = TextStyle(
fontFamily = exoTwoLight,
fontWeight = FontWeight.Normal,
fontSize = 12.sp,
),
overline = TextStyle(
fontFamily = exoTwoLight,
fontWeight = FontWeight.Normal,
fontSize = 10.sp,
)
)
Now when I try to load an input field in the app I can see that placeholder and leading icons are not aligned at all
I tried to customize the placeholder as it is required as a composable
By customization, I mean adding top padding of 2/4 dp to the placeholder
Row(modifier = Modifier.padding(top=10.dp)) {
OutlinedTextField(
leadingIcon = {
Icon(
painter = painterResource(id = R.drawable.gallery_icon),
contentDescription = "",
tint = colorResource(R.color.teal_200),
modifier = Modifier.clickable {
}
)
},
placeholder = {
Text(
text = "Placeholder",
style = MaterialTheme.typography.button,
modifier = Modifier.padding(top = 3.dp)
)
},
modifier = Modifier.fillMaxWidth(),
readOnly = false,
value = sampleValue,
onValueChange = {
sampleValue = it
},
maxLines = 1,
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Next),
)
}
It only solves the issue for the placeholder but values seem to be misaligned
This is the complete code
var sampleValue by remember {
mutableStateOf("")
}
Column{
Row(modifier = Modifier.padding(top=10.dp)){
OutlinedTextField(
leadingIcon = {
if (true) {
Icon(
painter = painterResource(id = R.drawable.capture_more_images),
contentDescription = "",
tint = colorResource(R.color.teal_200),
modifier = Modifier.clickable {
}
)
} else {
Icon(
painter = painterResource(id = R.drawable.capture_more_images),
contentDescription = "",
tint = colorResource(R.color.disabled)
)
}
},
placeholder = {
Row(
modifier = Modifier.height(24.dp),
verticalAlignment = Alignment.CenterVertically
){
Text(
text = "Placeholder",
style = MaterialTheme.typography.button
)
}
},
modifier = Modifier.fillMaxWidth(),
readOnly = false,
value = sampleValue,
onValueChange = {
sampleValue = it
},
maxLines = 1,
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Next),
)
}
Row(modifier = Modifier.padding(top=10.dp)) {
OutlinedTextField(
leadingIcon = {
Icon(
painter = painterResource(id = R.drawable.gallery_icon),
contentDescription = "",
tint = colorResource(R.color.teal_200),
modifier = Modifier.clickable {
}
)
},
placeholder = {
Text(
text = "Placeholder",
style = MaterialTheme.typography.button,
modifier = Modifier.padding(top = 3.dp)
)
},
modifier = Modifier.fillMaxWidth(),
readOnly = false,
value = sampleValue,
onValueChange = {
sampleValue = it
},
maxLines = 1,
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Next),
)
}
Row(modifier = Modifier.padding(top=10.dp)) {
OutlinedTextField(
placeholder = {
Text(
text = "Placeholder",
style = MaterialTheme.typography.button,
)
},
modifier = Modifier.fillMaxWidth(),
value = sampleValue,
onValueChange = {
sampleValue = it
}
)
}
}
I want that placeholder to be aligned vertically centered ( without giving any top padding ) with the leading icon what is the solution?
The solution to this is to set the singleLine property of the TextField to true. Like this:
TextField(
singleLine = true,
placeholder = {
Text(text = "Search for reminders")
},
leadingIcon = {
Icon(
painter = painterResource(id = R.drawable.search_icon),
tint = MaterialTheme.colorScheme.outline,
contentDescription = "Back button"
)
}
)
Many icons have built-in padding on one or more sides. To compensate for this, you can adjust the icon's position using the offset modifier. Set it some positive or negative value:
placeholder = {
Row(
modifier = Modifier.height(24.dp).offset(y = 5.dp),
verticalAlignment = Alignment.CenterVertically
){
Text(
text = "Placeholder",
style = MaterialTheme.typography.button
)
}
}

How to remove underline from BasicTextField?

How I can remove underline from my TextField? I don't want to use different TextField()
val style = TextStyle(
color = MaterialTheme.colors.primary,
fontSize = 16.sp,
fontWeight = FontWeight.SemiBold,
textDecoration = TextDecoration.None,
textAlign = TextAlign.Center
)
BasicTextField(
modifier = Modifier
.fillMaxWidth()
.align(Alignment.Center),
textStyle = style,
value = value,
onValueChange = { value = it },
singleLine = true
)

How to display a value for a TextField with a fixed height

If I put down a specific value for height, then my value for the text field moves somewhere, I can't understand why.
But if I don't set the height values, then everything is displayed in order
Here is my code:
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier
.fillMaxWidth()
// .size(40.dp)
.background(color = LightGray20, shape = RoundedCornerShape(6.dp))
.padding(6.dp)
) {
TextField(
modifier = Modifier.width(80.dp),
// .height(28.dp),
value = product.quantity.toString(),
onValueChange = {
it.toDoubleOrNull()?.let { value -> quantityChangeHandler(product, value) }
},
textStyle = LocalTextStyle.current.copy(textAlign = TextAlign.End, fontSize = 16.sp),
maxLines = 1,
keyboardOptions = KeyboardOptions(
keyboardType = KeyboardType.Number,
imeAction = ImeAction.Done
),
keyboardActions = KeyboardActions(
onDone = { localFocusManager.clearFocus() }
),
shape = RoundedCornerShape(8.dp),
colors = TextFieldDefaults.textFieldColors(
focusedIndicatorColor = Color.Transparent,
unfocusedIndicatorColor = Color.Transparent,
disabledIndicatorColor = Color.Transparent,
),
)
Text(
text = description,
fontSize = 16.sp,
maxLines = 1,
modifier = Modifier.padding(start = 2.dp)
)
}
Here is the my design what i want to do:
Here what i find about paddings:

Jetpack compose: Setting ImeAction does not close or change focus for the keyboard

I'm using Jetpack compose 1.0.0-alpha07. I made a login screen that contains two TextFields customized using other composables.
However, setting ImeAction in keyboardOptions does not seem to work. For instance ImeAction.Next does not move focus to the next TextField. I think I should do something to make it possible, but no document or article has talked even briefly about ImeOptions. Here's the code I have for the screen:
Login composable:
EmailEdit(onChange = { email.value = it })
PasswordEdit(onChange = { password.value = it })
EmailEdit:
#Composable
fun EmailEdit(onChange: (String) -> Unit) {
val t = remember { mutableStateOf("") }
TextField(
value = t.value,
onValueChange = { value ->
t.value = value
onChange(value)
},
leadingIcon = { Icon(asset = Icons.Default.Email) },
label = { Text(text = "Email") },
maxLines = 1,
keyboardOptions = KeyboardOptions(
imeAction = ImeAction.Next, // ** Go to next **
keyboardType = KeyboardType.Email
),
visualTransformation = VisualTransformation.None
)
} errorHint = "Not a valid email"
)
}
PassEdit:
#Composable
fun PasswordEdit(onChange: (String) -> Unit) {
val t = remember { mutableStateOf("") }
TextField(
value = t.value,
onValueChange = { value ->
t.value = value
onChange(value)
},
leadingIcon = { Icon(asset = Icons.Default.Security) },
label = { Text(text = "Password") },
maxLines = 1,
keyboardOptions = KeyboardOptions(
imeAction = ImeAction.Done, // ** Done. Close the keyboard **
keyboardType = KeyboardType.Text
),
visualTransformation = PasswordVisualTransformation()
)
}
To perform Done and Next what code should I add?
You can use
keyboardOptions: software keyboard options that contains configuration such as KeyboardType and ImeAction
keyboardActions when the input service emits an IME action, the corresponding callback is called
For Done:
You can use the LocalSoftwareKeyboardController to interact with the keyboard.
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
keyboardActions = KeyboardActions(
onDone = {keyboardController?.hide()}
)
For Next:
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Next),
keyboardActions = KeyboardActions(
onNext = { focusRequester.requestFocus() }
)
Something like:
val (focusRequester) = FocusRequester.createRefs()
val keyboardController = LocalSoftwareKeyboardController.current
TextField(
value = text,
onValueChange = {
text = it
},
label = { Text("Label") },
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Next),
keyboardActions = KeyboardActions(
onNext = { focusRequester.requestFocus() }
)
)
TextField(
value = text,
onValueChange = {
text = it
},
modifier = Modifier.focusRequester(focusRequester),
label = { Text("Label") },
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
keyboardActions = KeyboardActions(
onDone = { keyboardController?.hide() }
)
)
You can use LocalFocusManager.
val localFocusManager = LocalFocusManager.current
Inside parent composable of your fields.
To move focus to next field:
localFocusManager.moveFocus(FocusDirection.Down)
Inside onNext of KeyboardActions to move focus in specific direction such as left, right, up and down.
To clear focus:
localFocusManager.clearFocus()
Inside onDone of KeyboardActions to clear focus.
Email Field :
OutlinedTextField(
value = userId,
onValueChange = { userId = it },
label = { Text("Email") },
modifier = Modifier.fillMaxWidth(),
singleLine = true,
leadingIcon = {
Icon(
painter = painterResource(id = R.drawable.ic_account),
contentDescription = "ID"
)
},
colors = TextFieldDefaults.outlinedTextFieldColors(
focusedBorderColor = Color.Gray,
unfocusedBorderColor = Color.LightGray,
focusedLabelColor = Color(0xffcc0000)
),
keyboardOptions =
KeyboardOptions(
keyboardType = KeyboardType.Text,
imeAction = ImeAction.Next
),
keyboardActions = KeyboardActions(onNext = {
localFocusManager.moveFocus(FocusDirection.Down)
})
)
Password Field :
OutlinedTextField(
value = password,
onValueChange = { password = it },
label = { Text("Password") },
modifier = Modifier.fillMaxWidth(),
singleLine = true,
leadingIcon = {
Icon(
painter = painterResource(id = R.drawable.ic_password),
contentDescription = "Password"
)
},
colors = TextFieldDefaults.outlinedTextFieldColors(
focusedBorderColor = Color.Gray,
unfocusedBorderColor = Color.LightGray,
focusedLabelColor = Color(0xffcc0000)
),
keyboardOptions =
KeyboardOptions(
keyboardType = KeyboardType.Password,
imeAction = ImeAction.Done
),
keyboardActions = KeyboardActions(onDone = {
localFocusManager.clearFocus()
})
)
Tried with version 1.0.1
use the onImeActionPerformed parameter.
For Done:
TextField(
onImeActionPerformed = { _, controller ->
controller?.hideSoftwareKeyboard()
}
)
For Next:
val focusRequester = remember { FocusRequester() }
TextField(
onImeActionPerformed = { _, _ ->
focusRequester.requestFocus()
}
)
TextField(
modifier = Mofifier.focusRequester(focusRequester)
)
Here's a working example:
val focusRequester = remember { FocusRequester() }
val email = remember { mutableStateOf("") }
TextField(
value = email.value,
onValueChange = { email.value = it },
imeAction = ImeAction.Next,
onImeActionPerformed = { _, _ -> focusRequester.requestFocus() }
)
val password = remember { mutableStateOf("") }
TextField(
value = password.value,
onValueChange = { password.value = it },
imeAction = ImeAction.Done,
onImeActionPerformed = { _, controller -> controller?.hideSoftwareKeyboard() },
modifier = Modifier.focusRequester(focusRequester)
)
Documentation:
FocusRequestModifier: https://developer.android.com/reference/kotlin/androidx/compose/ui/FocusRequesterModifier
TextField: https://developer.android.com/reference/kotlin/androidx/compose/material/package-summary#TextField(kotlin.String,%20kotlin.Function1,%20androidx.compose.ui.Modifier,%20androidx.compose.ui.text.TextStyle,%20kotlin.Function0,%20kotlin.Function0,%20kotlin.Function0,%20kotlin.Function0,%20kotlin.Boolean,%20androidx.compose.ui.text.input.VisualTransformation,%20androidx.compose.foundation.text.KeyboardOptions,%20kotlin.Int,%20kotlin.Function2,%20kotlin.Function1,%20androidx.compose.foundation.InteractionState,%20androidx.compose.ui.graphics.Color,%20androidx.compose.ui.graphics.Color,%20androidx.compose.ui.graphics.Color,%20androidx.compose.ui.graphics.Color,%20androidx.compose.ui.graphics.Shape)
With Compose in this instance you need to create a set of references to each focusable text field on your screen as below (textField1, textField2) and get a reference to the keyboardController.
Then you can add a type of action to your keyboard options signalling how the action button should look when the keyboard is displayed.
In the keyboardActions parameter, you can call a function on the specified IME action - in this case i've stated I want textField2 to take focus when the keyboard action button is pressed. You assign the references in the Modifier.focusRequester parameter in the TextField.
Lastly, to make your first TextField take focus when the screen appears, you call a DisposableEffect function where you specify you would like textField1 to take focus when the screen is first displayed.
val (textField1, textField2) = remember { FocusRequester.createRefs() }
val keyboardController = LocalSoftwareKeyboardController.current
TextField(
modifier = Modifier.focusRequester(textField1),
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Next),
keyboardActions = KeyboardActions( onNext = {textField2.requestFocus()}
),
)
TextField(
modifier = Modifier.focusRequester(textField2),
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
keyboardActions = KeyboardActions( onDone = {
keyboardController?.hide()}
),
)
DisposableEffect(Unit) {
textField1.requestFocus()
onDispose { }
}

Categories

Resources