Show emoji category names

This commit is contained in:
Naveen Singh
2024-07-17 14:51:31 +05:30
parent 738a316ad3
commit e7d1017a1f
6 changed files with 92 additions and 46 deletions

View File

@@ -6,35 +6,41 @@ import android.view.View
import android.view.ViewGroup
import androidx.emoji2.text.EmojiCompat
import androidx.recyclerview.widget.RecyclerView
import org.fossify.commons.databinding.DividerBinding
import org.fossify.commons.extensions.beInvisible
import org.fossify.commons.extensions.adjustAlpha
import org.fossify.commons.extensions.getProperTextColor
import org.fossify.keyboard.databinding.ItemEmojiBinding
import org.fossify.keyboard.databinding.ItemEmojiCategoryTitleBinding
import org.fossify.keyboard.helpers.EmojiData
import org.fossify.keyboard.helpers.getCategoryTitleRes
class EmojisAdapter(
val context: Context,
val items: List<Item>,
val itemClick: (emoji: EmojiData) -> Unit
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
class EmojisAdapter(val context: Context, private val items: List<Item>, val itemClick: (emoji: EmojiData) -> Unit) :
RecyclerView.Adapter<EmojisAdapter.ViewHolder>() {
private val layoutInflater = LayoutInflater.from(context)
private val textColor = context.getProperTextColor()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): EmojisAdapter.ViewHolder {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return when (viewType) {
ITEM_TYPE_EMOJI -> {
val view = ItemEmojiBinding.inflate(layoutInflater, parent, false).root
ViewHolder(view)
}
ITEM_TYPE_EMOJI -> EmojiViewHolder(
ItemEmojiBinding.inflate(layoutInflater, parent, false).root
)
else -> {
val view = DividerBinding.inflate(layoutInflater, parent, false).root.apply { beInvisible() }
ViewHolder(view)
}
ITEM_TYPE_CATEGORY -> EmojiCategoryViewHolder(
ItemEmojiCategoryTitleBinding.inflate(layoutInflater, parent, false).root
)
else -> throw IllegalArgumentException("Unsupported view type: $viewType")
}
}
override fun onBindViewHolder(holder: EmojisAdapter.ViewHolder, position: Int) {
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
val item = items[position]
if (item is Item.Emoji) {
holder.bindView(item) { itemView ->
setupEmoji(itemView, item)
}
when (holder) {
is EmojiViewHolder -> holder.bindView(item as Item.Emoji)
is EmojiCategoryViewHolder -> holder.bindView(item as Item.Category)
}
}
@@ -48,25 +54,29 @@ class EmojisAdapter(val context: Context, private val items: List<Item>, val ite
override fun getItemCount() = items.size
private fun setupEmoji(view: View, emoji: Item.Emoji) {
val processed = EmojiCompat.get().process(emoji.value.emoji)
ItemEmojiBinding.bind(view).emojiValue.text = processed
}
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
fun bindView(emoji: Item.Emoji, callback: (itemView: View) -> Unit): View {
return itemView.apply {
callback(this)
inner class EmojiViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
fun bindView(emoji: Item.Emoji) {
val processed = EmojiCompat.get().process(emoji.emojiData.emoji)
itemView.apply {
ItemEmojiBinding.bind(this).emojiValue.text = processed
setOnClickListener {
itemClick.invoke(emoji.value)
itemClick.invoke(emoji.emojiData)
}
}
}
}
inner class EmojiCategoryViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
fun bindView(category: Item.Category) {
ItemEmojiCategoryTitleBinding.bind(itemView).emojiCategoryTitle.apply {
text = context.getString(getCategoryTitleRes(category.value))
setTextColor(textColor.adjustAlpha(0.6f))
}
}
}
sealed interface Item {
data class Emoji(val value: EmojiData) : Item
data class Emoji(val emojiData: EmojiData) : Item
data class Category(val value: String) : Item
}

View File

@@ -94,17 +94,31 @@ data class EmojiData(
val category: String,
val emoji: String,
val variants: List<String>
) {
fun getCategoryIcon(): Int =
when (category) {
"people_body" -> R.drawable.ic_emoji_category_people
"animals_nature" -> R.drawable.ic_emoji_category_animals
"food_drink" -> R.drawable.ic_emoji_category_food
"travel_places" -> R.drawable.ic_emoji_category_travel
"activities" -> R.drawable.ic_emoji_category_activities
"objects" -> R.drawable.ic_emoji_category_objects
"symbols" -> R.drawable.ic_emoji_category_symbols
"flags" -> R.drawable.ic_emoji_category_flags
else -> R.drawable.ic_emoji_category_smileys
}
}
)
fun getCategoryIconRes(category: String): Int =
when (category) {
"people_body" -> R.drawable.ic_emoji_category_people
"animals_nature" -> R.drawable.ic_emoji_category_animals
"food_drink" -> R.drawable.ic_emoji_category_food
"travel_places" -> R.drawable.ic_emoji_category_travel
"activities" -> R.drawable.ic_emoji_category_activities
"objects" -> R.drawable.ic_emoji_category_objects
"symbols" -> R.drawable.ic_emoji_category_symbols
"flags" -> R.drawable.ic_emoji_category_flags
else -> R.drawable.ic_emoji_category_smileys
}
fun getCategoryTitleRes(category: String) =
when (category) {
"people_body" -> R.string.people_and_body
"animals_nature" -> R.string.animals_and_nature
"food_drink" -> R.string.food_and_drink
"travel_places" -> R.string.travel_and_places
"activities" -> R.string.activities
"objects" -> R.string.objects
"symbols" -> R.string.symbols
"flags" -> R.string.flags
else -> R.string.smileys_and_emotions
}

View File

@@ -1576,16 +1576,17 @@ class MyKeyboardView @JvmOverloads constructor(context: Context, attrs: Attribut
allItems.add(EmojisAdapter.Item.Category(category))
allItems.addAll(emojis.map(EmojisAdapter.Item::Emoji))
}
val checkIds = mutableMapOf<Int, String>()
keyboardViewBinding?.emojiCategoriesStrip?.apply {
weightSum = categories.count().toFloat()
val strip = this
removeAllViews()
categories.entries.forEach { (category, emojis) ->
categories.entries.forEach { (category, _) ->
ItemEmojiCategoryBinding.inflate(LayoutInflater.from(context), this, true).apply {
root.id = generateViewId()
checkIds[root.id] = category
root.setImageResource(emojis.first().getCategoryIcon())
root.setImageResource(getCategoryIconRes(category))
root.layoutParams = LinearLayout.LayoutParams(
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.MATCH_PARENT,

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<org.fossify.commons.views.MyTextView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/emoji_category_title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingHorizontal="@dimen/small_margin"
android:paddingTop="@dimen/smaller_margin"
android:textAllCaps="true"
android:textSize="@dimen/emoji_category_title_text_size"
tools:text="@string/smileys_and_emotions" />

View File

@@ -19,4 +19,5 @@
<dimen name="label_text_size">16sp</dimen> <!-- text size used at keys with longer labels, like "123" -->
<dimen name="emoji_text_size">30sp</dimen>
<dimen name="emoji_category_text_size">14sp</dimen>
<dimen name="emoji_category_title_text_size">13sp</dimen>
</resources>

View File

@@ -38,6 +38,15 @@
<string name="start_sentences_capitalized">Start sentences with a capital letter</string>
<!-- Emojis -->
<string name="emojis">Emojis</string>
<string name="smileys_and_emotions">Smileys and emotions</string>
<string name="people_and_body">People and body</string>
<string name="animals_and_nature">Animals and nature</string>
<string name="food_and_drink">Food and drink</string>
<string name="travel_and_places">Travel and places</string>
<string name="activities">Activities</string>
<string name="objects">Objects</string>
<string name="symbols">Symbols</string>
<string name="flags">Flags</string>
<!-- Voice Input -->
<string name="voice_typing_method">Voice typing method</string>
<string name="switch_to_voice_typing">Switch to voice typing</string>