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.
Before
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-basedEditText
insideAndroidView
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: https://github.com/PatilShreyas/ComposeKeyboardMediaInput
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 π.