Build apps faster with our new App builder! Check it out →

InterceptPlatformTextInput

Common

Component in Compose Ui

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.

Last updated:

Installation

dependencies {
   implementation("androidx.compose.ui:ui:1.8.0-alpha04")
}

Overloads

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

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
        )
    }
}
by @alexstyl