---
title: "handwritingDetector"
description: "Configures an element to act as a handwriting detector which detects stylus handwriting and
delegates handling of the recognised text to another element.

Stylus movement on the element will start a handwriting session, and trigger the [callback]. The
[callback] implementation is expected to show and focus a text input field with a
[handwritingHandler] modifier which can handle the recognized text from the handwriting session.

A common use case is a component which looks like a text input field but does not actually
support text input itself, and clicking on this fake text input field causes a real text input
field to be shown. To support handwriting initiation in this case, this modifier can be applied
to the fake text input field to configure it as a detector, and a [handwritingHandler] modifier
can be applied to the real text input field. The [callback] implementation is typically the same
as the `onClick` implementation for the fake text field's [clickable] modifier, which shows and
focuses the real text input field.

This function returns a no-op modifier on API levels below Android U (34) as stylus handwriting
is not supported."
type: "modifier"
---

<div class='type'>Compose Modifier</div>

<a id='references'></a>
<div class='sourceset sourceset-android'>Android</div>


```kotlin
fun Modifier.handwritingDetector(callback: () -> Unit) =
    if (isStylusHandwritingSupported) {
        this.stylusHoverIcon(handwritingPointerIcon, false, HandwritingBoundsExpansion)
            .then(HandwritingDetectorElement(callback))
    } else {
        this
    }
```


Configures an element to act as a handwriting detector which detects stylus handwriting and
delegates handling of the recognised text to another element.

Stylus movement on the element will start a handwriting session, and trigger the `callback`. The
`callback` implementation is expected to show and focus a text input field with a
`handwritingHandler` modifier which can handle the recognized text from the handwriting session.

A common use case is a component which looks like a text input field but does not actually
support text input itself, and clicking on this fake text input field causes a real text input
field to be shown. To support handwriting initiation in this case, this modifier can be applied
to the fake text input field to configure it as a detector, and a `handwritingHandler` modifier
can be applied to the real text input field. The `callback` implementation is typically the same
as the `onClick` implementation for the fake text field's `clickable` modifier, which shows and
focuses the real text input field.

This function returns a no-op modifier on API levels below Android U (34) as stylus handwriting
is not supported.

#### Parameters

| | |
| --- | --- |
| callback | a callback which will be triggered when stylus handwriting is detected |




## Code Examples
### HandwritingDetectorSample
```kotlin
@Composable
fun HandwritingDetectorSample() {
    var openDialog by remember { mutableStateOf(false) }
    val focusRequester = remember { FocusRequester() }
    Column(
        Modifier.imePadding().requiredWidth(300.dp).verticalScroll(rememberScrollState()),
        verticalArrangement = Arrangement.Center,
        horizontalAlignment = Alignment.CenterHorizontally,
    ) {
        Text(
            "This is not an actual text field, but it is a handwriting detector so you can use " +
                "a stylus to write here."
        )
        Spacer(Modifier.size(16.dp))
        Text(
            "Fake text field",
            Modifier.fillMaxWidth()
                .handwritingDetector { openDialog = !openDialog }
                .padding(4.dp)
                .border(
                    1.dp,
                    MaterialTheme.colors.onSurface.copy(alpha = ContentAlpha.disabled),
                    RoundedCornerShape(4.dp),
                )
                .padding(16.dp),
            color = MaterialTheme.colors.onSurface.copy(alpha = ContentAlpha.medium),
        )
    }
    if (openDialog) {
        Dialog(onDismissRequest = { openDialog = false }) {
            Card(modifier = Modifier.width(300.dp), shape = RoundedCornerShape(16.dp)) {
                Column(
                    modifier = Modifier.padding(24.dp),
                    verticalArrangement = Arrangement.Center,
                    horizontalAlignment = Alignment.CenterHorizontally,
                ) {
                    Text("This text field is a handwriting handler.")
                    Spacer(Modifier.size(16.dp))
                    val state = remember { TextFieldState() }
                    BasicTextField(
                        state = state,
                        modifier =
                            Modifier.fillMaxWidth()
                                .focusRequester(focusRequester)
                                .handwritingHandler(),
                        decorator = { innerTextField ->
                            Box(
                                Modifier.padding(4.dp)
                                    .border(
                                        1.dp,
                                        MaterialTheme.colors.onSurface,
                                        RoundedCornerShape(4.dp),
                                    )
                                    .padding(16.dp)
                            ) {
                                innerTextField()
                            }
                        },
                    )
                }
            }
            val windowInfo = LocalWindowInfo.current
            LaunchedEffect(windowInfo) {
                snapshotFlow { windowInfo.isWindowFocused }
                    .collect { isWindowFocused ->
                        if (isWindowFocused) {
                            focusRequester.requestFocus()
                        }
                    }
            }
        }
    }
}
```

