Rich media input from the keyboard in Compose

Rich media input from the keyboard in Compose

Hey Composers πŸ‘‹πŸ», if you're also a fan of Jetpack Compose and working on an application that needs to interact with rich media input then finally it's available. Especially, if you're working on a chat application and also using Jetpack Compose, then this is gonna solve a use case for you.


In the View system, the API for Receiving rich content was already there. But there was no such straightforward API support for compose.

Imagine we are building a chat app in which users can select GIFs or images from Keyboard and these media will be directly sent on chat.

Unfortunately, while using Compose components' TextField APIs, this was not supported, and if a user tried to insert a media, a toast used shown as below:

I tried to achieve this a lot with various approaches like wrapping TextField composable inside ComposeView or AbstractComposeView and trying to establish a connection between the text field and the keyboard with onCreateInputConnection, but no luck!

The feature request was there on the issues-tracker for a long time but there was no workaround for this. The only thing that worked was wrapping View-basedEditTextinsideAndroidView but it was not gonna help much.

Now πŸŽ‰

Finally, after a long wait, In Jetpack Compose 1.7.x there is an API that can support rich media content handling.

A new Modifier has been introduced for this: Modifier.receiveContent(). In this modifier, we can specify what kind of content we wish to handle (for example: Image, plain text, HTML, or anything else). A variety of content could be received from another app through Drag-and-Drop, Copy/Paste, or from the Software Keyboard.

Let's see how can we receive content from a keyboard (for our chat app use case).

Code πŸ§‘πŸ»β€πŸ’»

You might have used BasicTextField or TextField. A new foundation API has been introduced for the text field: BasicTextField2. This has been improvised and created to replace the existing BasicTextField and is currently an experimental API to use.

So instead of Text or BasicTextField, use BasicTextField2 and use the modifier receiveContent along with it to get the rich content from keyboard input:

In modifier receiveContent, first, you need to specify what type of content you want to get. MediaType holds the MIME type. As needed, you can specify your MIME type. Second is lambda which gets invoked when content is selected (in this case, content will be selected from the keyboard). Lambda has a parameter TransferableContent that contain data, metadata, etc.

That's it! Once you handle the media retrieval through Uri, you're good to go πŸŽ‰.

How simple it was, wasn't it? πŸ˜€

You can explore receiveContent Modifier for other use cases like drag-and-drop, or from clipboard, or getting different types of files, etc.

You can refer to the following sample app project to try this out:

Final notes

As commented here, there are no plans from official teams to support this BasicTextField because it's going to be deprecated and replaced with BasicTextField2. So if you need this to fulfill a use case, you anyway have to migrate to the new text field composable.

Awesome 🀩. I trust you've picked up some valuable insights from this. If you like this write-up, do share it πŸ˜‰, because...

"Sharing is Caring"

Thank you! πŸ˜„

Let's catch up on X or visit my site to know more about me 😎.


Did you find this article valuable?

Support Shreyas Patil by becoming a sponsor. Any amount is appreciated!