New Compose Multiplatform components arrived on Composables UICheck it out →

InterceptPlatformTextInput

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.7.0-beta03")
}

Overloads

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

Code Examples

InterceptPlatformTextInputSample

@Composable
@Sampled
@OptIn(ExperimentalComposeUiApi::class
@Suppress("UNUSED_PARAMETER"
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

@Sampled
@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
        )
    }
}