Hello all, I am struggling to implement an onClic...
# compose
b
Hello all, I am struggling 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 the click animation to still happen. This is the layout I used that worked:
Copy code
<com.google.android.material.textfield.TextInputEditText
            android:id="@+id/editText"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:focusable="true"
            android:focusableInTouchMode="false"
            android:textIsSelectable="false"
            android:cursorVisible="false"
            android:clickable="false"
            android:inputType="textNoSuggestions"
            android:text='@{value}'
            android:onClick="@{() -> clickListener.invoke() }"/>
Trying to detect the click in Compose:
Copy code
TextField(
  value = text,
  onValueChange = { text = it },
  modifier = Modifier
    .clickable(enabled = true, onClick = {
      Log.i("TextField", "clicked")
    })
)
However onClick never fires
z
Do you actually need it to be a text field then? Could you just use a
Text
instead?
1
b
@Zach Klippenstein (he/him) [MOD] its an edit form with all edit fields, I would like to preserve the styling of TextField
z
(you don’t need to tag people in threads they’ve replied to, they’ll always get notified 🙂 )
👍 1
Have you looked at the documentation for
TextField
? The
enabled
and
readOnly
parameters look promising.
b
I have, I don’t want it to be read only or disabled, as I would like to see the click animation, and then handle the click.
Even so, .clickable.onClick is never firing
z
What if you use the decorator and wrap the text field in a clickable
Box
inside that? (Just shooting in the dark here)
b
No worries, shooting the in dark myself, I appreciate the help. Turns out for UX, readOnly is very close to what I want, its just that the click handler is not fired.
z
You could drop down into the
pointerInput
modifier and try intercepting the touch events in an earlier pass.
b
This works:
Copy code
modifier = Modifier
  .onFocusChanged {
    if (it.isFocused) {
      // perform action
    }
  }
Not perfect, as that only works if I remove focus after click, assuming someone might try to click again. Messing around with
Copy code
.pointerInput(Unit) {
  detectTapGestures(onTap = {
    // tapped
  })
}
With no luck either. Seems odd, maybe a bug or feature that is blocking taps propagating back up to a TextField component?
z
There are 3 distinct passes for touch events. The default is the middle one. You might need to grab the events in an earlier pass.
b
Ok, not sure how to do that, researching now…
z
Can’t remember the API off the top of my head, but if you dig into the imp.ementation of
detectTapGestures
a few layers i think you’ll find it