Показывать эмодзи

Стандартный набор эмодзи ежегодно обновляется Unicode, поскольку эмодзи все чаще используются в приложениях всех типов.

Если в вашем приложении есть контент из интернета или поле для ввода текста, мы настоятельно рекомендуем добавить поддержку последних шрифтов эмодзи. В противном случае эмодзи могут отображаться в виде небольшого квадрата, который называется тофу (☐), или других некорректных последовательностей.

В Android 11 (уровень API 30) и более ранних версиях шрифт эмодзи не обновляется, поэтому приложения, в которых он используется, нужно обновлять вручную.

Ниже приведены примеры современных эмодзи.

Примеры Версия
🫩 🪉 🇨🇶 16.0 (сентябрь 2024 г.)
🐦‍🔥 🧑‍🧑‍🧒‍🧒 👩🏽‍🦽‍➡️ 🇲🇶 15.1 (сентябрь 2023 г.)
🩷 🫸🏼 🐦‍⬛ 15.0 (сентябрь 2022 г.)
🫠 🫱🏼‍🫲🏿 🫰🏽 14.0 (сентябрь 2021 г.)
😶‍🌫️ 🧔🏻‍♀️ 🧑🏿‍❤️‍🧑🏾 13.1 (сентябрь 2020 г.)
🥲 🥷🏿 🐻‍❄️ 13.0 (март 2020 г.)
🧑🏻‍🦰 🧑🏿‍🦯 👩🏻‍🤝‍👩🏼 12.1 (октябрь 2019 г.)
🦩 🦻🏿 👩🏼‍🤝‍👩🏻 12.0 (февраль 2019 г.)

BOM за март 2023 г. (Compose UI 1.4) поддерживает последнюю версию эмодзи, включая обратную совместимость с более старыми версиями Android вплоть до API 21.

Для этого не нужно вносить изменения в приложение. Если вы используете Text и TextField (Material 2 или Material 3) или BasicText и BasicTextField, поддержка современных эмодзи будет доступна по умолчанию.

Лучший способ протестировать последние эмодзи в приложении – использовать реальное устройство с API 30 или ниже.

Если вы используете собственное решение для эмодзи или вам нужно отключить разрешение эмодзи по умолчанию в Compose по любой другой причине, вы можете использовать PlatformTextStyle(emojiSupportMatch):

Text(
    text = "Hello $EMOJI_TEXT",
    style = TextStyle(
        platformStyle = PlatformTextStyle(
            emojiSupportMatch = EmojiSupportMatch.None
        )/* ... */
    )
)

Совместимость

Если в вашем приложении используются и представления, и Compose в одном и том же Activity, убедитесь, что вы используете правильные API для настройки эмодзи. Ниже описано, в каких случаях следует использовать каждый из этих API.

Расширение с ComponentActivity

Если ваш класс Activity расширяет Compose ComponentActivity, а не AppCompatActivity, следуйте инструкциям в разделе Поддержка эмодзи без AppCompat.

Поскольку вы не расширяете AppCompatActivity, добавьте библиотеку Emoji2 в зависимости и используйте EmojiTextView в представлениях вместо виджета TextView, как показано в следующем фрагменте кода:

class MainActivity : ComponentActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val emojiTextView: EmojiTextView = findViewById(R.id.emoji_text_view)
        emojiTextView.text = getString(R.string.emoji_text_view, EMOJI_TEXT)

        val composeView: ComposeView = findViewById(R.id.compose_view)

        composeView.apply {
            setContent {
                // compose code
            }
        }
    }
}

Затем в XML-файле:

<androidx.emoji2.widget.EmojiTextView
    android:id="@+id/emoji_text_view"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    />

Расширение с AppCompatActivity

Если ваш класс Activity наследуется от AppCompatActivity, вы можете использовать ComposeView для вызова composable-функций. При использовании composable-функций Text эмодзи корректно отображаются в разных версиях Android.

Если вы расширяете AppCompatActivity, распакуйте TextView из XML, чтобы эмодзи отображались правильно.

Если вы используете XML, выполните следующие действия:

  • вне ComposeView, в Activity. Обратите внимание на использование AppCompatActivity и TextView в следующем фрагменте кода:

class MyActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val emojiTextView: TextView = findViewById(R.id.emoji_text_view)
        emojiTextView.text = getString(R.string.emoji_text_view, EMOJI_TEXT)

        val composeView: ComposeView = findViewById(R.id.compose_view)

        composeView.apply {
            setContent {
                // compose code
            }
        }
    }
}

class MyActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setContentView(
            ComposeView(this).apply {
                setContent {
                    Column {
                        Text(EMOJI_TEXT)

                        AndroidViewBinding(ExampleViewBinding::inflate) {
                            emojiTextView.text = EMOJI_TEXT
                        }
                    }
                }
            }
        )
    }
}

Чтобы развернуть текст с AndroidView внутри ComposeView, используйте AppCompatTextView для правильного отображения эмодзи:

class MyActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        setContentView(
            ComposeView(this).apply {
                setContent {
                    Column {
                        Text(EMOJI_TEXT)

                        AndroidView(
                            factory = { context -> AppCompatTextView(context) },
                            update = { it.text = EMOJI_TEXT }
                        )
                    }
                }
            }
        )
    }
}

Подробную информацию можно найти в документации по API для обеспечения совместимости.

Устранение неполадок

Если вместо эмодзи вы видите тофу (☐), сначала проверьте, не связана ли проблема с вашим тестовым устройством. Вот что можно проверить: