handwritingHandler
Modifier in Compose Foundation
Configures an element to act as a stylus handwriting handler which can handle text input from a handwriting session which was triggered by stylus handwriting on a handwriting detector.
When this element gains focus, if there is an ongoing stylus handwriting delegation which was triggered by stylus handwriting on a handwriting detector, this element will receive text input from the handwriting session via its input connection.
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, a [handwritingDetector]
modifier can be applied to the fake text input field to configure it as a detector, and this
modifier can be applied to the real text input field. The callback
implementation for the fake
text field's [handwritingDetector] modifier is typically the same as the onClick
implementation
its [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.
Last updated:
Installation
dependencies {
implementation("androidx.compose.foundation:foundation:1.8.0-alpha04")
}
Overloads
fun Modifier.handwritingHandler(): Modifier
Code Example
HandwritingDetectorSample
@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()
}
}
}
}
}
}