3-step guide to adding emojis — Jetpack Emoji Picker

Today, we will learn how we can add an emoji picker in Android applications using Jetpack Emoji Picker
The following three steps are all we need to incorporate EmojiPickerView
into our application
- Add the dependency to your app-level
build.gradle
file
OR
You can directly add the dependency if you are not using the version catalog yet
dependencies {
implementation "androidx.emoji2:emojipicker:$version"
}
2. Add EmojiPickerView
to layout file
<?xml version="1.0" encoding="UTF-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp">
<!-- Other views-->
<androidx.emoji2.emojipicker.EmojiPickerView
android:id="@+id/emoji_picker"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginTop="32dp"
android:layout_weight="1"
app:emojiGridRows="5"
app:emojiGridColumns="6" />
<!-- Other views-->
</LinearLayout>
Use findViewByID/ViewBinding
to access a view from an activity/fragment
OR
- Using
AndroidViewBinding
composable, we can use it in compose-based UIs
@Composable
fun Emoji2View() {
AndroidViewBinding(Emoji2ViewBindingBinding::inflate) {
emojiPicker.setOnEmojiPickedListener {
editText.append(it.emoji)
}
}
}
OR
- The
AndroidView
can be used if you’re not interested in 🛑layout
at all and want to go all in with compose
@Composable
fun EmojiPickerView() {
var emojiViewItem by remember {
mutableStateOf(EmojiViewItem("😀", emptyList()))
}
Column {
AndroidView(
modifier = Modifier.fillMaxWidth(),
factory = {
EmojiPickerView(it)
.apply {
// setting row $columns - Optional
emojiGridColumns = 9
emojiGridRows = 6f
// set pick listener
setOnEmojiPickedListener { item ->
emojiViewItem = item
}
}
}) {
}
Text(text = emojiViewItem.emoji)
}
}
3. Set the EmojiPickedListener
on EmojiPickerView
— XML-based UI
class MainActivity : ComponentActivity() {
private lateinit var emoji2ViewBindingBinding: Emoji2ViewBindingBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
emoji2ViewBindingBinding = Emoji2ViewBindingBinding.inflate(layoutInflater).also {
setContentView(it.root)
}
emoji2ViewBindingBinding.emojiPicker.setOnEmojiPickedListener { emojiViewItem ->
// TODO. use selected emojiViewItem here
}
}
Implementing custom RecentEmojiProvider
- The Emoji picker already has a default
RecentEmojiProvider
, you can find the code here 👇
- We can customize the implementation by calling
setRecentEmojiProvider(recentEmojiProvider: RecentEmojiProvider)
.
Custom Recent emoji provider 🧑💻
class CustomRecentEmojiProvider(context: Context) : RecentEmojiAsyncProvider {
private val sharedPreferences by lazy {
context.getSharedPreferences(RECENT_EMOJI_LIST_PREF_NAME, Context.MODE_PRIVATE)
}
private val emoji2Frequency: MutableMap<String, Int> by lazy {
sharedPreferences.getString(CUSTOM_EMOJI_FREQ_PREF_KEY, null)?.split(SPLIT_CHAR)
?.associate { entry ->
entry.split(VALUE_DELIMITER, limit = 2)
.let { value -> value[0] to value[1].toInt() }
}?.toMutableMap() ?: mutableMapOf()
}
override fun getRecentEmojiListAsync(): ListenableFuture<List<String>> =
Futures.immediateFuture(emoji2Frequency.toList().sortedByDescending { it.second }
.map { it.first })
override fun recordSelection(emoji: String) {
emoji2Frequency[emoji] = (emoji2Frequency[emoji] ?: 0) + 1
saveToPreferences()
}
private fun saveToPreferences() {
sharedPreferences.edit(commit = true) {
putString(CUSTOM_EMOJI_FREQ_PREF_KEY, emoji2Frequency.entries.joinToString(SPLIT_CHAR))
}
}
companion object {
private const val CUSTOM_EMOJI_FREQ_PREF_KEY = "pref_key_custom_emoji_freq"
private const val RECENT_EMOJI_LIST_PREF_NAME = "emoji2_preferences"
private const val SPLIT_CHAR = ","
private const val VALUE_DELIMITER = "="
}
}
Set RecentEmojiProvider
emojiPicker.setRecentEmojiProvider(
RecentEmojiProviderAdapter(
CustomRecentEmojiProvider(applicationContext)
)
)
Demo
