I have an OutlinedTextField with DropdownMenu inside it I want that after pressing on the item inside the DropdownMenu list, the value of the item started to be inside the OutlinedTextField being also adjusted by width depending of how long the text is. How I can do it ?
Update (14.02.2022)
By default OutlinedTextField uses OutlinedTextFieldLayout which contains BasicTextField with defaultMinSize Modifier parameter.
BasicTextField(
value = value,
modifier = modifier
.then(
if (decoratedLabel != null) {
Modifier.padding(top = OutlinedTextFieldTopPadding)
} else {
Modifier
}
)
.defaultMinSize(
minWidth = MinWidth,
minHeight = MinHeight
)
...
/** The default min width applied for a TextField and OutlinedTextField. Note that you can override it by applying Modifier.widthIn directly on a text field. */
val MinWidth = 280.dp
To make the width be Intrinsic Min I should have to duplicate 3 files (TextField.kt, TextFieldImpl.kt, OutlinedTextField.kt) from Compose library and make my own OutlinedTextField with these changes in OutlinedTextFieldLayout component:
@Composable
internal fun OutlinedFormTextFieldLayout(
modifier: Modifier,
value: TextFieldValue,
onValueChange: (TextFieldValue) -> Unit,
enabled: Boolean,
readOnly: Boolean,
keyboardOptions: KeyboardOptions,
keyboardActions: KeyboardActions,
textStyle: TextStyle,
singleLine: Boolean,
maxLines: Int = Int.MAX_VALUE,
visualTransformation: VisualTransformation,
interactionSource: MutableInteractionSource,
decoratedPlaceholder: @Composable ((Modifier) -> Unit)?,
decoratedLabel: @Composable (() -> Unit)?,
leading: @Composable (() -> Unit)?,
trailing: @Composable (() -> Unit)?,
leadingColor: Color,
trailingColor: Color,
labelProgress: Float,
indicatorWidth: Dp,
indicatorColor: Color,
cursorColor: Color,
shape: Shape
) {
val textWidth = remember { mutableStateOf(0) }
val labelSize = remember { mutableStateOf(Size.Zero) }
fun Modifier.widthIntrinsicSizeMinModifier() = width(IntrinsicSize.Min)
fun Modifier.widthTextWidthModifier() = width(textWidth.value.dp)
if (textWidth.value == 0) {
modifier.then(Modifier.widthIntrinsicSizeMinModifier())
} else {
modifier.then(Modifier.widthTextWidthModifier())
}
BasicTextField(
value = value,
modifier = modifier
.then(
if (decoratedLabel != null) {
Modifier.padding(top = OutlinedTextFieldTopPadding)
} else {
Modifier
}
)
.onSizeChanged {
textWidth.value = it.width
}, ...
With these changes we don't have a default width anymore but we still have some spacing left from the right side
Update(15.02.2022)
Don't duplicate files from @Compose library. Some of the API call won't work. In my case textColor and background set was not working for my custom OutlinedFormTextField where for OutlinedTextField everything was working fine:
colors = TextFieldDefaults.outlinedTextFieldColors(
textColor = Color.Red,
backgroundColor = backgroundColor.value
...
I also found that instead of overwriting the files which related to OutlinedTextField somehow you can just wrap your OutlinedTextField with Row component and set in it:
Modifier.defaultMinSize(minWidth = 1.dp)
It will remove the huge minWidth that Compose suggest by default but the extra spacing after the label is still exist.
Does anyone knows how to remove it ?

