Home > Software engineering >  Cannot calculate specific dimensions for composable TextField
Cannot calculate specific dimensions for composable TextField

Time:12-30

I am trying to create multiple items to encapsulate the specific behavior of every component but I cannot specify the dimensions for every view.

I want a Textfield with an X icon on its right

        setContent {
        Surface(
            modifier = Modifier
                .fillMaxSize()
                .background(color = white)
                .padding(horizontal = 15.dp)
        ) {
                Row(horizontalArrangement = Arrangement.spacedBy(15.dp)) {
                    Searcher(
                        modifier = Modifier.weight(1f),
                        onTextChanged = { },
                        onSearchAction = { }
                    )
                    Image(
                        painter = painterResource(id = R.drawable.ic_close),
                        contentDescription = null,
                        colorFilter = ColorFilter.tint(blue)
                    )
                }

            }
        }

The result should be something like this:

enter image description here

The Searcher component is the following

@Composable
fun Searcher(
    modifier: Modifier = Modifier,
    onTextChanged: (String) -> Unit,
    onSearchAction: () -> Unit
) {
    Row(
        modifier = modifier
            .background(bg_black_opacity)
            .drawBehind {
                drawLine(
                    color = pink,
                    start = Offset(0f, size.height),
                    end = Offset(size.width, size.height),
                    strokeWidth = 10f
                )
            }
    ) {
        SearcherField(
            onTextChanged = onTextChanged,
            onSearchAction = onSearchAction,
            modifier = Modifier.weight(1f)
        )

        CircularSearch(
            modifier = Modifier
                .padding(horizontal = 10.dp)
                .align(CenterVertically)
        )
    }
}

and the SearcherField:

@Composable
fun SearcherField(
    modifier: Modifier = Modifier,
    onTextChanged: (String) -> Unit,
    onSearchAction: () -> Unit
) {

    val emptyText = stringResource(id = R.string.empty_text)
    var fieldText by remember { mutableStateOf(emptyText) }

    TextField(
        value = fieldText,
        onValueChange = { value ->
            fieldText = value
            if (value.length > 2)
                onTextChanged(value)
        },
        singleLine = true,
        textStyle = Typography.h5.copy(color = White),
        colors = TextFieldDefaults.textFieldColors(
            cursorColor = White,
            focusedIndicatorColor = Transparent,
            unfocusedIndicatorColor = Transparent,
            backgroundColor = Transparent
        ),
        trailingIcon = {
            if (fieldText.isNotEmpty()) {
                IconButton(onClick = {
                    fieldText = emptyText
                }) {
                    Icon(
                        imageVector = Icons.Default.Close,
                        contentDescription = emptyText
                    )
                }
            }
        },
        placeholder = {
            Text(
                text = stringResource(id = R.string.dondebuscas),
                style = Typography.h5.copy(color = White)
            )
        },
        keyboardOptions = KeyboardOptions(imeAction = ImeAction.Search),
        keyboardActions = KeyboardActions(
            onSearch = {
                onSearchAction()
            }
        ),
        modifier = modifier.fillMaxWidth()
    )
}

But I don´t know why, but the component Searcher looks like this

enter image description here

It´s all about the placeholder that seems to be resized for not having enough space because if I remove the placeholder, the component looks perfect.

enter image description here

Everything is in one line, not having a placeholder of two lines. I m trying to modify the size of every item but I am not able to get the expected result and I don´t know if the problem is just about the placeholder.

How can I solve it?

Thanks in advance!

CodePudding user response:

Add maxlines = 1 to the placeholder Text's parameters.

Your field is single -lune but your text is multi-line. I think it creates conflict in implementation.

CodePudding user response:

Okay... I find that the problem is about the trailing icon. Is not visible when there is no text in the TextField but is still occupying some space in the view, that´s why the placeholder cannot occupy the entire space. The solution is the following.

    val trailingIconView = @Composable {
        IconButton(onClick = {
            fieldText = emptyText
        }) {
            Icon(
                imageVector = Icons.Default.Close,
                contentDescription = emptyText
            )
        }
    }

Create a variable with the icon and set it to the TextField only when is required

trailingIcon = if (fieldText.isNotEmpty()) trailingIconView else null,

With that, the trailing icon will be "gone" instead of "invisible" (the old way).

Still have a lot to learn.

  • Related