So I was checking out this document here https://developer.android.com/jetpack/compose/text#enter-modify-text
I have managed to create a text field (EditText) Using:
#Composable
fun EmailField() {
var text by remember { mutableStateOf("") }
TextField(
colors = TextFieldDefaults.textFieldColors(
textColor = Color.White,
focusedIndicatorColor = Color.White,
focusedLabelColor = Color.White
),
value = text,
onValueChange = { text = it },
label = { Text("Email") }
)
}
Now I want to set the drawableStart which we had in XML. So is there any such equivalent or other way to achieve?
I want to create something like this:
Any help or lead is appreciated
You can use the leadingIcon attribute:
TextField(
value = text,
onValueChange = { text = it },
leadingIcon = {
Icon(Icons.Filled.Email,
"contentDescription",
modifier = Modifier.clickable { /* .. */})}
)
Related
What I want:
I want my OutlinedTextField to be always focused or disable the ability to focus.
I want the OutlinedTextField to be RoundedCornerShape but when I use background it goes out of the shape.
My Code:
Column(modifier = Modifier
.weight(1f)
.background(Color.Gray)
.clip(RoundedCornerShape(35.dp))
) {
OutlinedTextField(
value = "12",
onValueChange = {},
readOnly = true,
shape = RoundedCornerShape(35.dp),
textStyle = LocalTextStyle.current.copy(textAlign = TextAlign.End),
leadingIcon = { Icon(painter = painterResource(id = R.drawable.ic_coin), contentDescription = null)},
modifier = Modifier
)
}
Using enabled = false the text field will be neither editable nor focusable, the input of the text field will not be selectable, visually text field will appear in the disabled UI state readOnly.
To change the background color use the attribute backgroundColor in the TextFieldDefaults.outlinedTextFieldColors parameter:
OutlinedTextField(
value = "12",
onValueChange = {},
enabled = false,
shape = RoundedCornerShape(35.dp),
textStyle = LocalTextStyle.current.copy(textAlign = TextAlign.End),
colors = TextFieldDefaults.outlinedTextFieldColors(
backgroundColor = Color.Gray,
disabledTextColor= LocalContentColor.current.copy(LocalContentAlpha.current),
)
)
If you want to wrap the component in a Column change the order of the modifiers:
Column(modifier = Modifier
.clip(RoundedCornerShape(35.dp))
.background(Color.Gray)
){
//....
}
If you want to change the border width you have to use the version 1.2.x and the OutlinedTextFieldDecorationBox specifying the border attribute:
BasicTextField(
//....
) {
OutlinedTextFieldDecorationBox(
border = {
TextFieldDefaults.BorderBox(
//...
unfocusedBorderThickness = 4.dp,
focusedBorderThickness = 4.dp
)
}
)
}
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()
}
)
Hi I need to remove the underline in my TextField because it look ugly when the TextField is circular. I have sat the activeColor to transparent, but then the cursor wont show (because it's transparent). How can I remove the underline/activeColor and keep the cursor?
Here is my Circular TextField code:
#Composable
fun SearchBar(value: String) {
// we are creating a variable for
// getting a value of our text field.
val inputvalue = remember { mutableStateOf(TextFieldValue()) }
TextField(
// below line is used to get
// value of text field,
value = inputvalue.value,
// below line is used to get value in text field
// on value change in text field.
onValueChange = { inputvalue.value = it },
// below line is used to add placeholder
// for our text field.
placeholder = { Text(text = "Firmanavn") },
// modifier is use to add padding
// to our text field, and a circular border
modifier = Modifier.padding(all = 16.dp).fillMaxWidth().border(1.dp, Color.LightGray, CircleShape),
shape = CircleShape,
// keyboard options is used to modify
// the keyboard for text field.
keyboardOptions = KeyboardOptions(
// below line is use for capitalization
// inside our text field.
capitalization = KeyboardCapitalization.None,
// below line is to enable auto
// correct in our keyboard.
autoCorrect = true,
// below line is used to specify our
// type of keyboard such as text, number, phone.
keyboardType = KeyboardType.Text,
),
// below line is use to specify
// styling for our text field value.
textStyle = TextStyle(color = Color.Black,
// below line is used to add font
// size for our text field
fontSize = TextUnit.Companion.Sp(value = 15),
// below line is use to change font family.
fontFamily = FontFamily.SansSerif),
// below line is use to give
// max lines for our text field.
maxLines = 1,
// active color is use to change
// color when text field is focused.
activeColor = Color.Gray,
// single line boolean is use to avoid
// textfield entering in multiple lines.
singleLine = true,
// inactive color is use to change
// color when text field is not focused.
inactiveColor = Color.Transparent,
backgroundColor = colorResource(id = R.color.white_light),
// trailing icons is use to add
// icon to the end of tet field.
trailingIcon = {
Icon(Icons.Filled.Search, tint = colorResource(id = R.color.purple_700))
},
)
You can define these attributes to apply a Transparent color:
focusedIndicatorColor
unfocusedIndicatorColor
disabledIndicatorColor
Something like:
TextField(
//..
colors = TextFieldDefaults.textFieldColors(
textColor = Color.Gray,
disabledTextColor = Color.Transparent,
backgroundColor = Color.White,
focusedIndicatorColor = Color.Transparent,
unfocusedIndicatorColor = Color.Transparent,
disabledIndicatorColor = Color.Transparent
)
)
Starting with 1.2.0 you can also use the new OutlinedTextFieldDecorationBox together with BasicTextField customizing the border or the indicator line.
val interactionSource = remember { MutableInteractionSource() }
val enabled = true
val singleLine = true
val colors = TextFieldDefaults.outlinedTextFieldColors()
BasicTextField(
value = value,
onValueChange = onValueChange,
modifier = modifier,
// internal implementation of the BasicTextField will dispatch focus events
interactionSource = interactionSource,
enabled = enabled,
singleLine = singleLine
) {
TextFieldDefaults.OutlinedTextFieldDecorationBox(
value = value,
visualTransformation = VisualTransformation.None,
innerTextField = it,
// same interaction source as the one passed to BasicTextField to read focus state
// for text field styling
interactionSource = interactionSource,
enabled = enabled,
singleLine = singleLine,
// update border thickness and shape
border = {
TextFieldDefaults.BorderBox(
enabled = enabled,
isError = false,
colors = colors,
interactionSource = interactionSource,
shape = CircleShape,
unfocusedBorderThickness = 1.dp,
focusedBorderThickness = 1.dp
)
}
)
}
Also you can use a TextFieldDecorationBox applying the indicatorLine modifier specifying the focusedIndicatorLineThickness and unfocusedIndicatorLineThickness values:
val colors = TextFieldDefaults.textFieldColors(
backgroundColor = White,
focusedIndicatorColor = Gray)
BasicTextField(
modifier = Modifier
.border(1.dp, Color.LightGray, CircleShape)
.indicatorLine(
enabled = enabled,
isError = false,
colors = colors,
interactionSource = interactionSource,
focusedIndicatorLineThickness = 0.dp,
unfocusedIndicatorLineThickness = 0.dp
)
.background(colors.backgroundColor(enabled).value, CircleShape),
) {
TextFieldDecorationBox(
//...
colors = colors
)
}
If you don't need TextField parameters / functions like collapsing label, placeholder, etc. you can use a layer of Text / BasicTextField to create a SearchField (which is a suggested workaround according to issue FilledTextField: can't remove bottom indicator ):
#Composable
fun Search(
hint: String,
endIcon: ImageVector? = Icons.Default.Cancel,
onValueChanged: (String) -> Unit,
) {
var textValue by remember { mutableStateOf(TextFieldValue()) }
Surface(
shape = RoundedCornerShape(50),
color = searchFieldColor
) {
Box(
modifier = Modifier
.preferredHeight(40.dp)
.padding(start = 16.dp, end = 12.dp),
contentAlignment = Alignment.CenterStart
)
{
if (textValue.text.isEmpty()) {
Text(
text = "Search...",
style = MaterialTheme.typography.body1.copy(color = MaterialTheme.colors.onSurface.copy(ContentAlpha.medium)),
)
}
Row(
verticalAlignment = Alignment.CenterVertically
) {
BasicTextField(
modifier = Modifier.weight(1f),
value = textValue,
onValueChange = { textValue = it; onValueChanged(textValue.text) },
singleLine = true,
cursorColor = YourColor,
)
endIcon?.let {
AnimatedVisibility(
visible = textValue.text.isNotEmpty(),
enter = fadeIn(),
exit = fadeOut()
) {
Image(
modifier = Modifier
.preferredSize(24.dp)
.clickable(
onClick = { textValue = TextFieldValue() },
indication = null
),
imageVector = endIcon,
colorFilter = iconColor
)
}
}
}
}
}
}
In general, most components in Jetpack Compose seem to be very easy to customize.
However, the same cannot be said for the TextField. For example, say that I wanted to make something like this:
One would think that simply wrapping the BaseTextField would work. However, it appears that there has been a bug in the BaseTextField component, and I have opened an issue. This bug will not permit the user to focus the text field after focusing-away from it once already, until the component is re-rendered.
Citing this, I attempted to customize the OutlinedTextField and TextField components, but am not able to customize them to look like the image above. Were it not for the fact that the cursor color uses the activeColor property, I could make it work.
What would be a proper work-around to create a usable text field that looks like the above?
You can use the TextField:
removing the label with label = null
applying custom color with the TextFieldDefaults.textFieldColors parameter to hide the indicator.
adding in the onValueChange a function to fix the max number of characters as described here
Finally use a Column to add 2 Text composables to complete the external label and counter text.
Something like:
var text by remember { mutableStateOf("") }
val maxChar = 5
Column(){
//External label
Text(
text = "Label",
modifier = Modifier.fillMaxWidth(),
textAlign = TextAlign.Start,
color = Blue
)
TextField(
value = text,
onValueChange = {
if (it.length <= maxChar) text = it
},
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 4.dp),
shape = RoundedCornerShape(8.dp),
trailingIcon = {
Icon(Icons.Filled.Add, "", tint = Blue)
},
colors = TextFieldDefaults.textFieldColors(
backgroundColor = ....,
focusedIndicatorColor = Color.Transparent, //hide the indicator
unfocusedIndicatorColor = .....)
)
//counter message
Text(
text = "${text.length} / $maxChar",
textAlign = TextAlign.End,
color = Blue,
style = MaterialTheme.typography.caption, //use the caption text style
modifier = Modifier.fillMaxWidth()
)
By this exemple you can learn a lot. With 1.0.0 you can do like this:
Column {
var textState by remember { mutableStateOf("") }
val maxLength = 110
val lightBlue = Color(0xffd8e6ff)
val blue = Color(0xff76a9ff)
Text(
text = "Caption",
modifier = Modifier
.fillMaxWidth()
.padding(bottom = 4.dp),
textAlign = TextAlign.Start,
color = blue
)
TextField(
modifier = Modifier.fillMaxWidth(),
value = textState,
colors = TextFieldDefaults.textFieldColors(
backgroundColor = lightBlue,
cursorColor = Color.Black,
disabledLabelColor = lightBlue,
focusedIndicatorColor = Color.Transparent,
unfocusedIndicatorColor = Color.Transparent
),
onValueChange = {
if (it.length <= maxLength) textState = it
},
shape = RoundedCornerShape(8.dp),
singleLine = true,
trailingIcon = {
if (textState.isNotEmpty()) {
IconButton(onClick = { textState = "" }) {
Icon(
imageVector = Icons.Outlined.Close,
contentDescription = null
)
}
}
}
)
Text(
text = "${textState.length} / $maxLength",
modifier = Modifier
.fillMaxWidth()
.padding(top = 4.dp),
textAlign = TextAlign.End,
color = blue
)
}
Well, until the issue I mentioned is resolved, the choices are:
Roll back to Compose version 1.0.0-alpha04 (issue was introduced in alpha05)
Add a border to a TextField or OutlinedTextField as so:
TextField(
value = myValue,
onValueChange = myOnChange,
modifier = Modifier.clip(myShape).border(5.dp, myColor)
)
In addition to Gabriele Mariotti's Answer
If you like to have custom color for your cursor, you can achieve it using:
Column(){
//External label
Text(
...
...
)
TextField(
...
...
colors = TextFieldDefaults.textFieldColors(
backgroundColor = ...,
focusedIndicatorColor = ...,
unfocusedIndicatorColor = ...,
cursorColor = Color.Black)
)
//counter message
Text(
...
...
)
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)
)