Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jetpack Compose: TextField clickable does not work

for some reason Compose TextField's click listener does not work for me.

@Composable
    private fun ExposedDropdown(
        modifier: Modifier,
        list: List<String>,
        priority: Int
    ) {
        var expanded by remember { mutableStateOf(false) }
        Column(modifier) {
            OutlinedTextField(
                value = list[priority],
                onValueChange = { },
                readOnly = true,
                singleLine = true,
                label = { Text(stringResource(id = R.string.status)) },
                modifier = Modifier
                    .fillMaxWidth()
                    .clickable { Timber.i("Not working :(") }
                    .onFocusChanged { if (it.isFocused) expanded = !expanded },
                trailingIcon = {
                    Icon(
                        imageVector = Icons.Outlined.ArrowDropDown,
                        contentDescription = null,
                        modifier = Modifier
                            .clickable { expanded = !expanded }
                            .padding(16.dp)
                    )
                }
            )
            DropdownMenu(
                expanded = expanded,
                onDismissRequest = { expanded = false }
            ) {
                list.forEach { label ->
                    DropdownMenuItem(onClick = {
                        viewModel.setPriority(list.indexOf(label))
                        expanded = false
                    }) {
                        Text(text = label)
                    }
                }
            }
        }
    }

As you can see I come up with bad solution using onFocusChanged but it does not work well.

For those who need context, I'm trying to do ExposedDropdown but I want it to open when I click anywhere on TextField

like image 379
androboy Avatar asked Dec 31 '22 14:12

androboy


2 Answers

with compose 1.0.2 it works by default. Need to add line enabled = false

Example

@Composable
fun SelectableTextField(
    modifier: Modifier = Modifier,
    textValue: String,
    onClick: () -> Unit
) {
    TextField(
        value = textValue,
        onValueChange = {},
        modifier = modifier
            .fillMaxWidth()
            .clickable { onClick() },
        enabled = false
    )
}

to remove ripple effect, use such extension

inline fun Modifier.noRippleClickable(crossinline onClick: () -> Unit): Modifier =
    composed {
        clickable(indication = null,
            interactionSource = remember { MutableInteractionSource() }) {
            onClick()
        }
    }
like image 156
Sergei S Avatar answered Jan 02 '23 03:01

Sergei S


Another possible workaround can be this:

import kotlinx.coroutines.flow.collect

TextField(
    value = ...,
    onValueChange = { ... },
    interactionSource = remember { MutableInteractionSource() }
        .also { interactionSource ->
            LaunchedEffect(interactionSource) {
                interactionSource.interactions.collect {
                    if (it is PressInteraction.Release) {
                        // works like onClick
                    }
                }
            }
        }
)

like image 23
beigirad Avatar answered Jan 02 '23 02:01

beigirad