Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Detect click in Compose TextField

I am trying to implement an onClick handler for a Compose TextField. Current functionality is to handle the TextField click but disable manually editing of the field. For my use case I would like to handle the click and do something else. I would like to keep the look and feel of a TextField, and would like the focus animation to also happen.

the readOnly property gives me what I want from a UX perspective, however when I click on the TextField the onClick handler is not called.

TextField(
  value = text,
  onValueChange = { text = it},
  readOnly = true,
  modifier = Modifier
    .clickable(onClick = {
      Log.i("TextField", "Clicked")
    })
)

I have also tried to use pointerInput, how I am having the same problem.

TextField(
  value = text,
  onValueChange = { text = it},
  readOnly = true,
  modifier = Modifier
    .pointerInput(Unit) {
      detectTapGestures(onTap = {
        Log.i("TextField", "Clicked")
      }
    }
)

With Compose being so new its hard to tell if this is a bug or intended.

like image 780
lostintranslation Avatar asked May 11 '21 19:05

lostintranslation


1 Answers

Maybe the better way to detect click events in text field is using interaction source.

step 1 : - Create an interaction source

 val source = remember {
    MutableInteractionSource()
}

step 2: - pass it to text field

 OutlinedTextField(
    value = text,
    readOnly = true,
    onValueChange = {},
    textStyle = MaterialTheme.typography.body1.copy(
        lineHeight = if (isFocused) 25.sp else TextUnit.Unspecified,
        fontWeight = if (isFocused) FontWeight.SemiBold else FontWeight.Normal
    ),
    label = {
        Text(
            text = label,
            fontWeight = if (isFocused) FontWeight.SemiBold else FontWeight.Normal,
            style = MaterialTheme.typography.caption
        )
    },
    interactionSource = source,
    colors = TextFieldDefaults.outlinedTextFieldColors(
        textColor = if (isFocused) MaterialTheme.colors.primary else LocalContentColor.current
    ),
    maxLines = if (isFocused) Int.MAX_VALUE else 2,
    modifier = Modifier
        .padding(
            start = COUNTER_WIDTH + 16.dp,
            top = padding,
            bottom = padding,
            end = 16.dp
        )
        .fillMaxWidth()
        .verticalScroll(enabled = isFocused, state = rememberScrollState())
        .animateContentSize(animationSpec = tween(DURATION))
)

step: 3- collect pressed flow as state and observe changes to it.

 if ( source.collectIsPressedAsState().value)
        onClicked()
like image 104
Sheikh Zakir Ahmad Avatar answered Oct 15 '22 01:10

Sheikh Zakir Ahmad