Skip to content

Commit 25918d4

Browse files
authored
Merge pull request #232 from esensar/feature/229-emoji-categories
Add emoji categories to emoji list
2 parents 6fd4eb5 + 8137b71 commit 25918d4

16 files changed

+232
-22
lines changed

app/src/main/kotlin/com/simplemobiletools/keyboard/adapters/EmojisAdapter.kt

Lines changed: 42 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,39 +6,72 @@ import android.view.View
66
import android.view.ViewGroup
77
import androidx.emoji2.text.EmojiCompat
88
import androidx.recyclerview.widget.RecyclerView
9+
import com.simplemobiletools.commons.databinding.DividerBinding
10+
import com.simplemobiletools.commons.extensions.beInvisible
911
import com.simplemobiletools.keyboard.databinding.ItemEmojiBinding
12+
import com.simplemobiletools.keyboard.helpers.EmojiData
1013

11-
class EmojisAdapter(val context: Context, var items: List<String>, val itemClick: (emoji: String) -> Unit) : RecyclerView.Adapter<EmojisAdapter.ViewHolder>() {
14+
class EmojisAdapter(val context: Context, private val items: List<Item>, val itemClick: (emoji: EmojiData) -> Unit) :
15+
RecyclerView.Adapter<EmojisAdapter.ViewHolder>() {
1216
private val layoutInflater = LayoutInflater.from(context)
1317

1418
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): EmojisAdapter.ViewHolder {
15-
val view = ItemEmojiBinding.inflate(layoutInflater, parent, false).root
16-
return ViewHolder(view)
19+
return when (viewType) {
20+
ITEM_TYPE_EMOJI -> {
21+
val view = ItemEmojiBinding.inflate(layoutInflater, parent, false).root
22+
ViewHolder(view)
23+
}
24+
25+
else -> {
26+
val view = DividerBinding.inflate(layoutInflater, parent, false).root.apply { beInvisible() }
27+
ViewHolder(view)
28+
}
29+
}
1730
}
1831

1932
override fun onBindViewHolder(holder: EmojisAdapter.ViewHolder, position: Int) {
2033
val item = items[position]
21-
holder.bindView(item) { itemView ->
22-
setupEmoji(itemView, item)
34+
if (item is Item.Emoji) {
35+
holder.bindView(item) { itemView ->
36+
setupEmoji(itemView, item)
37+
}
38+
}
39+
}
40+
41+
override fun getItemViewType(position: Int): Int {
42+
return if (items[position] is Item.Emoji) {
43+
ITEM_TYPE_EMOJI
44+
} else {
45+
ITEM_TYPE_CATEGORY
2346
}
2447
}
2548

2649
override fun getItemCount() = items.size
2750

28-
private fun setupEmoji(view: View, emoji: String) {
29-
val processed = EmojiCompat.get().process(emoji)
51+
private fun setupEmoji(view: View, emoji: Item.Emoji) {
52+
val processed = EmojiCompat.get().process(emoji.value.emoji)
3053
ItemEmojiBinding.bind(view).emojiValue.text = processed
3154
}
3255

3356
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
34-
fun bindView(emoji: String, callback: (itemView: View) -> Unit): View {
57+
fun bindView(emoji: Item.Emoji, callback: (itemView: View) -> Unit): View {
3558
return itemView.apply {
3659
callback(this)
3760

3861
setOnClickListener {
39-
itemClick.invoke(emoji)
62+
itemClick.invoke(emoji.value)
4063
}
4164
}
4265
}
4366
}
67+
68+
sealed interface Item {
69+
data class Emoji(val value: EmojiData) : Item
70+
data class Category(val value: String) : Item
71+
}
72+
73+
companion object {
74+
private const val ITEM_TYPE_EMOJI = 0
75+
private const val ITEM_TYPE_CATEGORY = 1
76+
}
4477
}

app/src/main/kotlin/com/simplemobiletools/keyboard/helpers/EmojiHelper.kt

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
package com.simplemobiletools.keyboard.helpers
22

33
import android.content.Context
4+
import com.simplemobiletools.keyboard.R
45
import org.json.JSONObject
56
import java.io.InputStream
67

7-
private var cachedEmojiData: MutableList<String>? = null
8+
private var cachedEmojiData: MutableList<EmojiData>? = null
89
val cachedVNTelexData: HashMap<String, String> = HashMap()
910

1011
/**
@@ -14,18 +15,21 @@ val cachedVNTelexData: HashMap<String, String> = HashMap()
1415
* @param context The initiating view's context.
1516
* @param path The path to the asset file.
1617
*/
17-
fun parseRawEmojiSpecsFile(context: Context, path: String): MutableList<String> {
18+
fun parseRawEmojiSpecsFile(context: Context, path: String): MutableList<EmojiData> {
1819
if (cachedEmojiData != null) {
1920
return cachedEmojiData!!
2021
}
2122

22-
val emojis = mutableListOf<String>()
23+
val emojis = mutableListOf<EmojiData>()
2324
var emojiEditorList: MutableList<String>? = null
25+
var category: String? = null
2426

2527
fun commitEmojiEditorList() {
2628
emojiEditorList?.let {
2729
// add only the base emoji for now, ignore the variations
28-
emojis.add(it.first())
30+
val base = it.first()
31+
val variants = it.drop(1)
32+
emojis.add(EmojiData(category ?: "none", base, variants))
2933
}
3034
emojiEditorList = null
3135
}
@@ -36,6 +40,7 @@ fun parseRawEmojiSpecsFile(context: Context, path: String): MutableList<String>
3640
// Comment line
3741
} else if (line.startsWith("[")) {
3842
commitEmojiEditorList()
43+
category = line.replace("[", "").replace("]", "")
3944
} else if (line.trim().isEmpty()) {
4045
// Empty line
4146
continue
@@ -84,3 +89,22 @@ fun parseRawJsonSpecsFile(context: Context, path: String): HashMap<String, Strin
8489
}
8590
return cachedVNTelexData
8691
}
92+
93+
data class EmojiData(
94+
val category: String,
95+
val emoji: String,
96+
val variants: List<String>
97+
) {
98+
fun getCategoryIcon(): Int =
99+
when (category) {
100+
"people_body" -> R.drawable.ic_emoji_category_people
101+
"animals_nature" -> R.drawable.ic_emoji_category_animals
102+
"food_drink" -> R.drawable.ic_emoji_category_food
103+
"travel_places" -> R.drawable.ic_emoji_category_travel
104+
"activities" -> R.drawable.ic_emoji_category_activities
105+
"objects" -> R.drawable.ic_emoji_category_objects
106+
"symbols" -> R.drawable.ic_emoji_category_symbols
107+
"flags" -> R.drawable.ic_emoji_category_flags
108+
else -> R.drawable.ic_emoji_category_smileys
109+
}
110+
}

app/src/main/kotlin/com/simplemobiletools/keyboard/views/MyKeyboardView.kt

Lines changed: 75 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import android.content.ClipData
77
import android.content.ClipboardManager
88
import android.content.Context
99
import android.content.Intent
10+
import android.content.res.ColorStateList
1011
import android.graphics.*
1112
import android.graphics.Paint.Align
1213
import android.graphics.drawable.*
@@ -19,6 +20,7 @@ import android.util.TypedValue
1920
import android.view.*
2021
import android.view.animation.AccelerateInterpolator
2122
import android.view.inputmethod.EditorInfo
23+
import android.widget.ImageButton
2224
import android.widget.LinearLayout
2325
import android.widget.PopupWindow
2426
import android.widget.TextView
@@ -29,6 +31,9 @@ import androidx.core.animation.doOnStart
2931
import androidx.core.view.*
3032
import androidx.emoji2.text.EmojiCompat
3133
import androidx.emoji2.text.EmojiCompat.EMOJI_SUPPORTED
34+
import androidx.recyclerview.widget.GridLayoutManager
35+
import androidx.recyclerview.widget.GridLayoutManager.SpanSizeLookup
36+
import androidx.recyclerview.widget.LinearLayoutManager
3237
import com.simplemobiletools.commons.extensions.*
3338
import com.simplemobiletools.commons.helpers.ensureBackgroundThread
3439
import com.simplemobiletools.commons.helpers.isPiePlus
@@ -37,6 +42,7 @@ import com.simplemobiletools.keyboard.activities.ManageClipboardItemsActivity
3742
import com.simplemobiletools.keyboard.activities.SettingsActivity
3843
import com.simplemobiletools.keyboard.adapters.ClipsKeyboardAdapter
3944
import com.simplemobiletools.keyboard.adapters.EmojisAdapter
45+
import com.simplemobiletools.keyboard.databinding.ItemEmojiCategoryBinding
4046
import com.simplemobiletools.keyboard.databinding.KeyboardKeyPreviewBinding
4147
import com.simplemobiletools.keyboard.databinding.KeyboardPopupKeyboardBinding
4248
import com.simplemobiletools.keyboard.databinding.KeyboardViewKeyboardBinding
@@ -1468,17 +1474,16 @@ class MyKeyboardView @JvmOverloads constructor(context: Context, attrs: Attribut
14681474
emojiPaletteLabel.setTextColor(textColor)
14691475

14701476
emojiPaletteBottomBar.background = ColorDrawable(backgroundColor)
1471-
val bottomTextColor = textColor.darkenColor()
14721477
emojiPaletteModeChange.apply {
1473-
setTextColor(bottomTextColor)
1478+
setTextColor(textColor)
14741479
setOnClickListener {
14751480
vibrateIfNeeded()
14761481
closeEmojiPalette()
14771482
}
14781483
}
14791484

14801485
emojiPaletteBackspace.apply {
1481-
applyColorFilter(bottomTextColor)
1486+
applyColorFilter(textColor)
14821487
setOnTouchListener { _, event ->
14831488
when (event.action) {
14841489
MotionEvent.ACTION_DOWN -> {
@@ -1529,8 +1534,8 @@ class MyKeyboardView @JvmOverloads constructor(context: Context, attrs: Attribut
15291534
}
15301535

15311536
val emojis = fullEmojiList.filter { emoji ->
1532-
systemFontPaint.hasGlyph(emoji) || (EmojiCompat.get().loadState == EmojiCompat.LOAD_STATE_SUCCEEDED && EmojiCompat.get()
1533-
.getEmojiMatch(emoji, emojiCompatMetadataVersion) == EMOJI_SUPPORTED)
1537+
systemFontPaint.hasGlyph(emoji.emoji) || (EmojiCompat.get().loadState == EmojiCompat.LOAD_STATE_SUCCEEDED && EmojiCompat.get()
1538+
.getEmojiMatch(emoji.emoji, emojiCompatMetadataVersion) == EMOJI_SUPPORTED)
15341539
}
15351540

15361541
Handler(Looper.getMainLooper()).post {
@@ -1546,19 +1551,80 @@ class MyKeyboardView @JvmOverloads constructor(context: Context, attrs: Attribut
15461551
}
15471552
}
15481553

1549-
private fun setupEmojiAdapter(emojis: List<String>) {
1554+
private fun setupEmojiAdapter(emojis: List<EmojiData>) {
1555+
val categories = emojis.groupBy { it.category }
1556+
val allItems = mutableListOf<EmojisAdapter.Item>()
1557+
categories.entries.forEach { (category, emojis) ->
1558+
allItems.add(EmojisAdapter.Item.Category(category))
1559+
allItems.addAll(emojis.map(EmojisAdapter.Item::Emoji))
1560+
}
1561+
val checkIds = mutableMapOf<Int, String>()
1562+
keyboardViewBinding?.emojiCategoriesStrip?.apply {
1563+
weightSum = categories.count().toFloat()
1564+
val strip = this
1565+
removeAllViews()
1566+
categories.entries.forEach { (category, emojis) ->
1567+
ItemEmojiCategoryBinding.inflate(LayoutInflater.from(context), this, true).apply {
1568+
root.id = generateViewId()
1569+
checkIds[root.id] = category
1570+
root.setImageResource(emojis.first().getCategoryIcon())
1571+
root.layoutParams = LinearLayout.LayoutParams(
1572+
LinearLayout.LayoutParams.MATCH_PARENT,
1573+
LinearLayout.LayoutParams.MATCH_PARENT,
1574+
1f
1575+
)
1576+
root.setOnClickListener {
1577+
strip.children.filterIsInstance<ImageButton>().forEach {
1578+
it.imageTintList = ColorStateList.valueOf(mTextColor)
1579+
}
1580+
root.imageTintList = ColorStateList.valueOf(context.getProperPrimaryColor())
1581+
keyboardViewBinding?.emojisList?.stopScroll()
1582+
(keyboardViewBinding?.emojisList?.layoutManager as? GridLayoutManager)?.scrollToPositionWithOffset(
1583+
allItems.indexOfFirst { it is EmojisAdapter.Item.Category && it.value == category },
1584+
0
1585+
)
1586+
}
1587+
root.imageTintList = ColorStateList.valueOf(mTextColor)
1588+
}
1589+
}
1590+
}
15501591
keyboardViewBinding?.emojisList?.apply {
15511592
val emojiItemWidth = context.resources.getDimensionPixelSize(R.dimen.emoji_item_size)
15521593
val emojiTopBarElevation = context.resources.getDimensionPixelSize(R.dimen.emoji_top_bar_elevation).toFloat()
15531594

1554-
layoutManager = AutoGridLayoutManager(context, emojiItemWidth)
1555-
adapter = EmojisAdapter(context = context, items = emojis) { emoji ->
1556-
mOnKeyboardActionListener!!.onText(emoji)
1595+
layoutManager = AutoGridLayoutManager(context, emojiItemWidth).apply {
1596+
spanSizeLookup = object : SpanSizeLookup() {
1597+
override fun getSpanSize(position: Int): Int =
1598+
if (allItems[position] is EmojisAdapter.Item.Category) {
1599+
spanCount
1600+
} else {
1601+
1
1602+
}
1603+
}
1604+
}
1605+
adapter = EmojisAdapter(context = context, items = allItems) { emoji ->
1606+
mOnKeyboardActionListener!!.onText(emoji.emoji)
15571607
vibrateIfNeeded()
15581608
}
15591609

1610+
clearOnScrollListeners()
15601611
onScroll {
15611612
keyboardViewBinding!!.emojiPaletteTopBar.elevation = if (it > 4) emojiTopBarElevation else 0f
1613+
(keyboardViewBinding?.emojisList?.layoutManager as? LinearLayoutManager)?.findFirstCompletelyVisibleItemPosition()?.also { firstVisibleIndex ->
1614+
allItems
1615+
.withIndex()
1616+
.lastOrNull { it.value is EmojisAdapter.Item.Category && it.index <= firstVisibleIndex }
1617+
?.also { activeCategory ->
1618+
val id = checkIds.entries.first { it.value == (activeCategory.value as EmojisAdapter.Item.Category).value }.key
1619+
keyboardViewBinding?.emojiCategoriesStrip?.children?.filterIsInstance<ImageButton>()?.forEach {
1620+
if (it.id == id) {
1621+
it.imageTintList = ColorStateList.valueOf(context.getProperPrimaryColor())
1622+
} else {
1623+
it.imageTintList = ColorStateList.valueOf(mTextColor)
1624+
}
1625+
}
1626+
}
1627+
}
15621628
}
15631629
}
15641630
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<vector android:height="24dp" android:tint="#FFFFFF"
2+
android:viewportHeight="24" android:viewportWidth="24"
3+
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
4+
<path android:fillColor="@android:color/white" android:pathData="M19,5h-2V3H7v2H5C3.9,5 3,5.9 3,7v1c0,2.55 1.92,4.63 4.39,4.94c0.63,1.5 1.98,2.63 3.61,2.96V19H7v2h10v-2h-4v-3.1c1.63,-0.33 2.98,-1.46 3.61,-2.96C19.08,12.63 21,10.55 21,8V7C21,5.9 20.1,5 19,5zM5,8V7h2v3.82C5.84,10.4 5,9.3 5,8zM19,8c0,1.3 -0.84,2.4 -2,2.82V7h2V8z"/>
5+
</vector>
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<vector android:height="24dp" android:tint="#FFFFFF"
2+
android:viewportHeight="24" android:viewportWidth="24"
3+
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
4+
<path android:fillColor="@android:color/white" android:pathData="M21.94,4.88C21.76,4.35 21.25,4 20.68,4c-0.03,0 -0.06,0 -0.09,0H19.6l-0.31,-0.97C19.15,2.43 18.61,2 18,2h0c-0.61,0 -1.15,0.43 -1.29,1.04L16.4,4h-0.98c-0.03,0 -0.06,0 -0.09,0c-0.57,0 -1.08,0.35 -1.26,0.88c-0.19,0.56 0.04,1.17 0.56,1.48l0.87,0.52L15.1,8.12c-0.23,0.58 -0.04,1.25 0.45,1.62C15.78,9.91 16.06,10 16.33,10c0.31,0 0.61,-0.11 0.86,-0.32L18,8.98l0.81,0.7C19.06,9.89 19.36,10 19.67,10c0.27,0 0.55,-0.09 0.78,-0.26c0.5,-0.37 0.68,-1.04 0.45,-1.62l-0.39,-1.24l0.87,-0.52C21.89,6.05 22.12,5.44 21.94,4.88zM18,7c-0.55,0 -1,-0.45 -1,-1c0,-0.55 0.45,-1 1,-1s1,0.45 1,1C19,6.55 18.55,7 18,7z"/>
5+
<path android:fillColor="@android:color/white" android:pathData="M13.49,10.51c-0.43,-0.43 -0.94,-0.73 -1.49,-0.93V8h-1v1.38c-0.11,-0.01 -0.23,-0.03 -0.34,-0.03c-1.02,0 -2.05,0.39 -2.83,1.17c-0.16,0.16 -0.3,0.34 -0.43,0.53L6,10.52c-1.56,-0.55 -3.28,0.27 -3.83,1.82c0,0 0,0 0,0c-0.27,0.75 -0.23,1.57 0.12,2.29c0.23,0.48 0.58,0.87 1,1.16c-0.38,1.35 -0.06,2.85 1,3.91c1.06,1.06 2.57,1.38 3.91,1c0.29,0.42 0.68,0.77 1.16,1C9.78,21.9 10.21,22 10.65,22c0.34,0 0.68,-0.06 1.01,-0.17c0,0 0,0 0,0c1.56,-0.55 2.38,-2.27 1.82,-3.85l-0.52,-1.37c0.18,-0.13 0.36,-0.27 0.53,-0.43c0.87,-0.87 1.24,-2.04 1.14,-3.17H16v-1h-1.59C14.22,11.46 13.92,10.95 13.49,10.51zM4.67,14.29c-0.25,-0.09 -0.45,-0.27 -0.57,-0.51s-0.13,-0.51 -0.04,-0.76c0.19,-0.52 0.76,-0.79 1.26,-0.61l3.16,1.19C7.33,14.2 5.85,14.71 4.67,14.29zM10.99,19.94c-0.25,0.09 -0.52,0.08 -0.76,-0.04c-0.24,-0.11 -0.42,-0.32 -0.51,-0.57c-0.42,-1.18 0.09,-2.65 0.7,-3.8l1.18,3.13C11.78,19.18 11.51,19.76 10.99,19.94zM12.2,14.6l-0.61,-1.61c0,-0.01 -0.01,-0.02 -0.02,-0.03c-0.02,-0.04 -0.04,-0.08 -0.06,-0.12c-0.02,-0.04 -0.04,-0.07 -0.07,-0.11c-0.03,-0.03 -0.06,-0.06 -0.09,-0.09c-0.03,-0.03 -0.06,-0.06 -0.09,-0.09c-0.03,-0.03 -0.07,-0.05 -0.11,-0.07c-0.04,-0.02 -0.07,-0.05 -0.12,-0.06c-0.01,0 -0.02,-0.01 -0.03,-0.02L9.4,11.8c0.36,-0.29 0.79,-0.46 1.26,-0.46c0.53,0 1.04,0.21 1.41,0.59C12.8,12.66 12.84,13.81 12.2,14.6z"/>
6+
</vector>
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<vector android:height="24dp" android:tint="#FFFFFF"
2+
android:viewportHeight="24" android:viewportWidth="24"
3+
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
4+
<path android:fillColor="@android:color/white" android:pathData="M14.4,6L14,4H5v17h2v-7h5.6l0.4,2h7V6z"/>
5+
</vector>
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<vector android:height="24dp" android:tint="#FFFFFF"
2+
android:viewportHeight="24" android:viewportWidth="24"
3+
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
4+
<path android:fillColor="@android:color/white" android:pathData="M20,3H9v2.4l1.81,1.45C10.93,6.94 11,7.09 11,7.24v4.26c0,0.28 -0.22,0.5 -0.5,0.5h-4C6.22,12 6,11.78 6,11.5V7.24c0,-0.15 0.07,-0.3 0.19,-0.39L8,5.4V3H4v10c0,2.21 1.79,4 4,4h6c2.21,0 4,-1.79 4,-4v-3h2c1.11,0 2,-0.9 2,-2V5C22,3.89 21.11,3 20,3zM20,8h-2V5h2V8z"/>
5+
<path android:fillColor="@android:color/white" android:pathData="M4,19h16v2h-16z"/>
6+
</vector>
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<vector android:height="24dp" android:tint="#FFFFFF"
2+
android:viewportHeight="24" android:viewportWidth="24"
3+
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
4+
<path android:fillColor="@android:color/white" android:pathData="M12,3c-0.46,0 -0.93,0.04 -1.4,0.14C7.84,3.67 5.64,5.9 5.12,8.66c-0.48,2.61 0.48,5.01 2.22,6.56C7.77,15.6 8,16.13 8,16.69V19c0,1.1 0.9,2 2,2h0.28c0.35,0.6 0.98,1 1.72,1s1.38,-0.4 1.72,-1H14c1.1,0 2,-0.9 2,-2v-2.31c0,-0.55 0.22,-1.09 0.64,-1.46C18.09,13.95 19,12.08 19,10C19,6.13 15.87,3 12,3zM14,19h-4v-1h4V19zM14,17h-4v-1h4V17zM12.5,11.41V14h-1v-2.59L9.67,9.59l0.71,-0.71L12,10.5l1.62,-1.62l0.71,0.71L12.5,11.41z"/>
5+
</vector>
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<vector android:height="24dp" android:tint="#FFFFFF"
2+
android:viewportHeight="24" android:viewportWidth="24"
3+
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
4+
<path android:fillColor="@android:color/white" android:pathData="M12,4m-2,0a2,2 0,1 1,4 0a2,2 0,1 1,-4 0"/>
5+
<path android:fillColor="@android:color/white" android:pathData="M15.89,8.11C15.5,7.72 14.83,7 13.53,7c-0.21,0 -1.42,0 -2.54,0C8.24,6.99 6,4.75 6,2H4c0,3.16 2.11,5.84 5,6.71V22h2v-6h2v6h2V10.05L18.95,14l1.41,-1.41L15.89,8.11z"/>
6+
</vector>
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
<vector android:height="24dp" android:tint="#FFFFFF"
2+
android:viewportHeight="24" android:viewportWidth="24"
3+
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
4+
<path android:fillColor="@android:color/white" android:pathData="M11.99,2C6.47,2 2,6.48 2,12c0,5.52 4.47,10 9.99,10C17.52,22 22,17.52 22,12C22,6.48 17.52,2 11.99,2zM8.5,8C9.33,8 10,8.67 10,9.5S9.33,11 8.5,11S7,10.33 7,9.5S7.67,8 8.5,8zM12,18c-2.28,0 -4.22,-1.66 -5,-4h10C16.22,16.34 14.28,18 12,18zM15.5,11c-0.83,0 -1.5,-0.67 -1.5,-1.5S14.67,8 15.5,8S17,8.67 17,9.5S16.33,11 15.5,11z"/>
5+
</vector>

0 commit comments

Comments
 (0)