Emoji.kt Core provides Kotlin/Multiplatform support for:
-
Displaying emoji with system font.
Such as:"Hello ${Emoji.Wink}, have a great day ${Emoji.WavingHand.mediumDark}, ${Emoji.RedHeart} you!"
. -
Parsing a
String
to locate and extract its emojis.
Such as:finder.findEmoji("Hello π, have a great day ππΎ, β€οΈ you!")
. -
Listing Emojis.
With:Emoji.all()
. -
Parsing a
String
with short-codes and emoticons.
Such as:catalog.replace("Hello :wink:, have a great day :waving-hand~medium-dark:, <3 you!")
. -
Getting emoji information.
Such as:Emoji.Wink.details.description
. -
Exploring emoji by groups & subgroups.
With:Emoji.allEmojiGroups()
andEmoji.subgroupsOf(group)
.
Emoji.Compose provides Compose/Multiplatform support for:
-
Displaying Emoji with Noto vector images.
With:TextWithNotoImageEmoji(text)
. -
Displaying Emoji with Noto vector animations.
With:TextWithNotoAnimatedEmoji(text)
. -
Using system font if supported and reverting to Noto images if it is not (on Wasm).
With:TextWithPlatformEmoji(text)
. -
Handling how images & animations are downloaded.
With:ProvideEmojiDownloader(myDownloadFunction) { content() }
.
implementation("org.kodein.emoji:emoji-kt:2.0.1")
You can insert Emoji in a Kotlin String with the Emoji
companion object extensions:
val str = "Hello ${Emoji.Wink}, have a great day ${Emoji.WavingHand}, ${Emoji.RedHeart} you!"
Some emoji can be specialized with skin tones:
val str = "Hello ${Emoji.Wink}, have a great day ${Emoji.WavingHand.mediumDark}, ${Emoji.RedHeart} you!"
To parse a String with emojis, you first need to create an EmojiFinder
.
Caution
|
Note that creating an
Note that |
You can then use this EmojiFinder
to extract emojis in your strings:
val emojiFinder = withContext(Dispatchers.Default) { EmojiFinder() }
val str = "Hello π, have a great day ππΎ, β€οΈ you!"
emojiFinder.findEmoji(str).forEach { found ->
println("Found \"${found.emoji.details.description}\" at ${found.start}.")
}
You can access a list of all known emoji with Emoji.all()
.
Caution
|
Note that creating the list of all known emoji with
|
val allEmoji = withContext(Dispatchers.Default) { Emoji.all() }
To parse a String, with short-codes and emoticons you first need to create an EmojiTemplateCatalog
.
Caution
|
Note that creating an
Note that |
To create the EmojiTemplateCatalog
, you need to pass to its constructor the list obtained with Emoji.all
.
val allEmoji = withContext(Dispatchers.Default) { Emoji.all() }
val emojiCatalog = withContext(Dispatchers.Default) { EmojiTemplateCatalog(allEmoji) }
val str = emojiCatalog.replace("Hello :wink:, have a great day :waving-hand~medium-dark:, <3 you!")
An emoji can be described with:
-
A simple short-code, such as
:wink:
-
A short-code with one skin tone, such as
:waving-hand~medium-dark:
-
A short-code with two skin tones, such as
:people-holding-hands~medium-light,medium-dark:
You can add your own short-codes and emoticons when constructing the EmojiTemplateCatalog
:
val emojiCatalog = withContext(Dispatchers.Default) {
EmojiTemplateCatalog(allEmoji) {
addAlias("hello", Emoji.WavingHand)
addEmoticon("^^'", Emoji.GrinSweat)
}
}
All emojis are described through their Emoji.Details
data class.
You can access:
-
emoji.details.string
: The UTF-16 String containing the emoji. -
emoji.details.description
: The description of this emoji as given by the Unicode standard. -
emoji.details.unicodeVersion
: The emoji unicode definition minimum version where this emoji appears. -
emoji.details.aliases
: The list of emoji aliases, as defined by the Unicode standard and the Noto font. -
emoji.details.emoticons
: The list of emoticons that links to that emoji (such as;)
or^_^;
. -
emoji.details.notoAnimated
: Whether this emoji is provided as an animation by the Noto font. -
emoji.details.codePoints()
: The list of Unicode code-points of this emoji.
You can get:
-
All emoji groups:
val groups: List<String> = Emoji.allGroups()
-
All emoji groups and subrougps:
val groups: List<Pair<String, String>> = Emoji.allSubgroups()
-
All emoji subrougps of a group:
val groups: List<String> = Emoji.subgroupsOf(group)
-
All emoji of a group:
val groupEmoji: List<Emoji> = Emoji.allOf(group)
-
All emoji of a subgroup:
val groupEmoji: List<Emoji> = Emoji.allOf(group, subgroup)
implementation("org.kodein.emoji:emoji-compose-m2:2.0.1") // With compose.material
// OR
implementation("org.kodein.emoji:emoji-compose-m3:2.0.1") // With compose.material3
Note
|
Emoji.Compose is not needed if you simply wish to display platform Emojis in a Compose application.
|
The first time you use emoji composable functions, the emoji service will need to initialise, which may take a few milliseconds. You can initialise the emoji service ahead of time so that even the first emoji composable function invocation will be instantaneous:
@Composable
fun App() {
remember { EmojiService.initialize() } //(1)
AppContent()
}
-
Service initialization happens in the background and will not block the UI thread.
You can display an Emoji Image with NotoImageEmoji
:
NotoImageEmoji(Emoji.Wink, Modifier.fillMaxSize())
You can display a String by replacing all of its emojis by images downloaded from the Noto font image library.
TextWithNotoImageEmoji(
text = "Hello ${Emoji.Wink}, have a great day ${Emoji.WavingHand.mediumDark}, ${Emoji.RedHeart} you!"
)
Note that if you want to use short-codes and emoticons, you need to parse the string with String.withEmoji
first:
TextWithNotoImageEmoji(
text = "Hello :wink:, have a great day :waving-hand~medium-dark:, <3 you!".withEmoji()
)
Instead of using Noto images, you can use animations, if the emoji supports it.
NotoAnimatedEmoji(Emoji.Wink, Modifier.fillMaxSize())
TextWithNotoAnimatedEmoji(
"Hello ${Emoji.Wink}, have a great day ${Emoji.WavingHand.mediumDark}, ${Emoji.RedHeart} you!"
)
Note
|
If the emoji does not support animation, than it will be displayed as a still image. |
At the moment, Compose Wasm does not support displaying system font emoticons.
To circumvent that, WithPlatformEmoji
changes the provided text only on Wasm to insert images instead of font emoticons.
On all other platforms, however, the emoji will not be replaced.
WithPlatformEmoji(
"Hello ${Emoji.Wink}, have a great day ${Emoji.WavingHand.mediumDark}, ${Emoji.RedHeart} you!"
) { text, inlineContent ->
Text(text = text, inlineContent = inlineContent)
}
Emoji.Compose does not depend on a particular HTTP library. It therefore offers the simplest of downloader: no retry support, no cache or offline support, etc.
If you are using Ktor, Coil, or any other multiplatform HTTP library, you can easily use it in Emoji.Compose:
ProvideEmojiDownloader(
download = {
val response = ktorClient.get(it.url)
response.body<ByteArray>()
}
) {
App()
}
If you want to manipulate the annotatedString produced by the TextWith*Emoji
functions, you can instead use the With*Emoji
functions:
WithNotoImageEmoji(
"Hello ${Emoji.Wink}, have a great day ${Emoji.WavingHand.mediumDark}, ${Emoji.RedHeart} you!"
) { text, inlineContent -> //(1)(2)
// ...
}
-
text:
AnnotatedString
-
inlineContent:
Map<String, InlineTextContent>
The EmojiService
is the global reference to the EmojiFinder
and EmojiTemplateCatalog
used by this library.
You can access it with:
-
@Composable fun EmojiService.get(): EmojiService?
-
suspend fun EmojiService.await(): EmojiService
.
Before accessing it, you can add your own aliases and emoticons to the catalog:
EmojiService.catalogBuilder = {
addAlias("hello", Emoji.WavingHand)
addEmoticon("^^'", Emoji.GrinSweat)
}