InterceptPlatformTextInput

Composable Function

Common
@ExperimentalComposeUiApi
@Composable
fun InterceptPlatformTextInput(
    interceptor: PlatformTextInputInterceptor,
    content: @Composable () -> Unit,
)

Intercept all calls to PlatformTextInputSession.startInputMethod from below where this composition local is provided with the given PlatformTextInputInterceptor.

If a different interceptor instance is passed between compositions while a text input session is active, the upstream session will be torn down and restarted with the new interceptor. The downstream session (i.e. the call to PlatformTextInputSession.startInputMethod) will not be cancelled and the request will be re-used to pass to the new interceptor.

Code Examples

InterceptPlatformTextInputSample

@Suppress("UNUSED_PARAMETER")
@OptIn(ExperimentalComposeUiApi::class)
@Composable
fun InterceptPlatformTextInputSample() {
    var text by remember { mutableStateOf("") }
    InterceptPlatformTextInput(
        interceptor = { request, nextHandler ->
            // Create a new request to wrap the incoming one with some custom logic.
            val modifiedRequest =
                object : PlatformTextInputMethodRequest {
                    override fun createInputConnection(outAttributes: EditorInfo): InputConnection {
                        val inputConnection = request.createInputConnection(outAttributes)
                        // After the original request finishes initializing the EditorInfo we can
                        // customize it. If we needed to we could also wrap the InputConnection
                        // before
                        // returning it.
                        updateEditorInfo(outAttributes)
                        return inputConnection
                    }
                    fun updateEditorInfo(outAttributes: EditorInfo) {
                        // Your code here, e.g. set some custom properties.
                    }
                }
            // Send our wrapping request to the next handler, which could be the system or another
            // interceptor up the tree.
            nextHandler.startInputMethod(modifiedRequest)
        }
    ) {
        BasicTextField(value = text, onValueChange = { text = it })
    }
}

disableSoftKeyboardSample

@OptIn(ExperimentalComposeUiApi::class)
fun disableSoftKeyboardSample() {
    /**
     * A function that disables the soft keyboard for any text field within its content.
     *
     * The keyboard is re-enabled by removing this modifier or passing `disable = false`.
     */
    @Composable
    fun DisableSoftKeyboard(disable: Boolean = true, content: @Composable () -> Unit) {
        InterceptPlatformTextInput(
            interceptor = { request, nextHandler ->
                // If this flag is changed while an input session is active, a new lambda instance
                // that captures the new value will be passed to InterceptPlatformTextInput, which
                // will automatically cancel the session upstream and restart it with this new
                // interceptor.
                if (!disable) {
                    // Forward the request to the system.
                    nextHandler.startInputMethod(request)
                } else {
                    // This function has to return Nothing, and since we don't have any work to do
                    // in this case, we just suspend until cancelled.
                    awaitCancellation()
                }
            },
            content = content,
        )
    }
}