How to create multiline text area in jetpack compose - android

I want to create the following textfield. But there are no samples on the internet for the same, neither in material documentation

#Composable
fun Textarea() {
val text = rememberSaveable { mutableStateOf("") }
TextField(
value = text.value,
onValueChange = { text.value = it }, modifier = Modifier
.fillMaxWidth()
.height(100.dp)
.padding(10.dp)
.border(width = 1.dp, color = Color.Black, shape = RoundedCornerShape(8.dp))
)
}
You can change the size and customize it as you want as per your requirement.

Related

How to get OutlinedTextField with gradient boarder in Jetpack Compose?

I'm trying to get an OutlinedTextField with gradient border like this one:
But I can add only a single color to the outline,
OutlinedTextField(
value = email,
onValueChange = {email = it},
label = { Text(text = "Email Address") },
modifier = Modifier
.fillMaxWidth(.8f)
.padding(4.dp),
colors = TextFieldDefaults.outlinedTextFieldColors(unfocusedBorderColor = Color.Green)
)
If I add a border with modifier then the gradient is applied to the border, not to the outline:
Modifier.border(width = 1.dp, brush = gradient, shape = RoundedCornerShape(12.dp))
How can I add gradient color to the outline?
so far that i know OutlinedTextField does't support gradient border. But if really want to use gradient border in text field you can try BasicTextField
var name by remember {
mutableStateOf("")
}
BasicTextField(
value = name,
onValueChange = { name = it },
cursorBrush = Brush.horizontalGradient(listOf(Color.Red, Color.Green)),
modifier = Modifier
.fillMaxWidth(),
decorationBox = { innerTextField ->
Row(
modifier = Modifier
.fillMaxWidth()
.border(
brush = Brush.horizontalGradient(listOf(Color.Green, Color.Blue)),
width = 1.dp,
shape = CircleShape
)
.padding(16.dp)
) {
Icon(Icons.Default.Email, contentDescription = "")
Spacer(modifier = Modifier.padding(3.dp))
innerTextField()
}
}
)
and this is the final result
you can learn more about basic text field by looking the sample
[BasicTextField Samples][2]

Why the keyboard overlaps the content of my view when the keyboard is opened

I am using Android Compose to implement new UI in my app. Unfortunately the content of my view is hidden when the keyboard is opened.
Please find below some details :
#Composable
private fun OnBoardingAddressScreen() {
var address by remember { mutableStateOf("") }
val space = 35.dp
val horizontalPadding = resources.getDimension(R.dimen.horizontal_padding).dp
Column(modifier = Modifier.fillMaxSize()) {
OnBoardingTopContent()
Spacer(modifier = Modifier.size(space))
OnboardingAddressContent(
address = address,
onAddressChange = { address = it },
onBoardingButtonClick =
{
},
horizontalPadding
)
}
}
#Composable
private fun OnboardingAddressContent(
address: String,
onAddressChange: (String) -> Unit,
onBoardingButtonClick: () -> Unit,
horizontalPadding: Dp
) {
Column(modifier = Modifier
.fillMaxSize()) {
Text(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = horizontalPadding),
fontSize = 35.sp,
maxLines = 3,
text = "Welcome", fontWeight = FontWeight.Bold
)
Image(
modifier = Modifier
.align(alignment = Alignment.CenterHorizontally)
.size(330.dp, 330.dp),
painter = painterResource(R.drawable.onboarding_image),
contentDescription = null
)
OutlinedTextField(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = horizontalPadding),
value = address,
onValueChange = onAddressChange,
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text),
label = { Text("Your content") }
)
Box(modifier = Modifier.fillMaxSize()){
Image(
modifier = Modifier.align(Alignment.BottomStart),
painter = painterResource(R.drawable.onboarding_bottom_background),
contentDescription = null
)
Button(
modifier = Modifier
.fillMaxWidth()
.height(56.dp)
.align(Alignment.BottomCenter)
.padding(horizontal = horizontalPadding),
shape = RoundedCornerShape(10.dp),
content = { Text("Navigate") },
onClick = onBoardingButtonClick
)
}
}
}
And here the result :
Please notice :
I am using android:windowSoftInputMode="adjustPan" in my manifest and tried using android:windowSoftInputMode="adjustResize" but I still have the issue
Thank you in advance for your help
You can add an empty layout in the bottom of your screen when the keyboard will show then you will show the empty layout and when the keyboard is gone then you can hide the empty layout.
Can you check this link that provided from google : https://google.github.io/accompanist/insets/#animated-insets-support
ProvideWindowInsets(windowInsetsAnimationsEnabled = true) {
// content
}
and
OutlinedTextField(
// other params,
modifier = Modifier.navigationBarsWithImePadding()
)
Our problems seems to be very similar. I created some kind of tutorial basing on my code. Hope it will help:
(Compose UI) - Keyboard (IME) overlaps content of app

How change OutlineTextField border width in Android Jetpack Compose?

My code:
OutlinedTextField(
value = state.value,
onValueChange = { state.value = it },
modifier = Modifier.fillMaxWidth().padding(start = 30.dp, end = 30.dp),
label = { Text(text = "Something", fontSize = 14.sp) },
shape = RoundedCornerShape(12.dp),
)
I want to increase the border width so that the colors focusedBorderColor, disabledBorderColor are supported.
Outline border is defined as a constant value in OutlinedTextField.
private val IndicatorUnfocusedWidth = 1.dp
private val IndicatorFocusedWidth = 2.dp
There is no direct way to override these values.
So, you have to create complete custom TextField Composables if you need to achieve dynamic border width.
You can copy-paste the complete code in OutlinedTextField.kt and TextFieldImpl.kt and modify them as required to create the custom Composables.
You can change OutlinedTextField border like this
var hasFocus by remember { mutableStateOf(false) }
OutlinedTextField(
modifier = modifier
.border(
width = 1.dp,
color = if (hasFocus) Color.Red else Color.Unspecified
)
.onFocusChanged { focusState -> hasFocus = focusState.hasFocus },
colors = TextFieldDefaults.outlinedTextFieldColors(
focusedBorderColor = Color.Unspecified,
unfocusedBorderColor = Color.Unspecified
)
)
Another solution is to use BaseTextField instead of OutlinedTextField

How remove extra padding above Jetpack Compose OutlinedTextField?

I'm trying to put OutlinedTextField into the Column after Box element like this
#Composable
fun Header() {
Column {
Box(
modifier = Modifier
.border(1.dp, Color.Cyan)
) {
Text("Header")
}
OutlinedTextField(
modifier = Modifier
.fillMaxWidth()
.border(1.dp, Color.Cyan),
value = "",
onValueChange = {},
placeholder = {
Text("Enter header")
}
)
}
}
Borders added to see exact size of elements. It looks like this
with extra 8dp padding above, but when I use TextField instead of OutlinedTextField there are no extra space
#Composable
fun Header() {
Column {
Box(
modifier = Modifier
.border(1.dp, Color.Cyan)
) {
Text("Header")
}
TextField(
modifier = Modifier
.fillMaxWidth()
.border(1.dp, Color.Cyan),
value = "",
onValueChange = {},
placeholder = {
Text("Enter header")
}
)
}
}
I need to know why it is happening and how to solve it
Version of library is "androidx.compose.material:material:1.0.0-alpha10"
The Padding above OutlinedTextField is there because the label moves to the top when in focus, which requires space.
If you don't want this feature, you can create your own outlined text field composable by modifying BasicTextField.

Jetpack Compose: Custom TextField design

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(
...
...
)

Categories

Resources