Mostrar emojis

O conjunto padrão de emojis é atualizado anualmente pela Unicode, já que o uso de emojis está aumentando rapidamente em todos os tipos de apps.

Se o app exibe conteúdo da Internet ou fornece entrada de texto, é altamente recomendável oferecer suporte às fontes de emoji mais recentes. Caso contrário, os emojis mais recentes podem ser mostrados como uma pequena caixa quadrada chamada tofu (☐) ou outras sequências de emojis renderizadas incorretamente.

O Android 11 (nível 30 da API) e versões anteriores não podem atualizar a fonte de emojis. Por isso, os apps que os exibem nessas versões precisam ser atualizados manualmente.

Confira a seguir exemplos de emojis modernos.

Exemplos Versão
🫠 🫱🏼‍🫲🏿 🫰🏽 14.0 (setembro de 2021)
😶‍🌫️ 🧔🏻‍♀️ 🧑🏿‍❤️‍🧑🏾 13.1 (setembro de 2020)
🥲 🥷🏿 🐻‍❄️ 13.0 (março de 2020)
🧑🏻‍🦰 🧑🏿‍🦯 👩🏻‍🤝‍👩🏼 12.1 (outubro de 2019)
🦩 🦻🏿 👩🏼‍🤝‍👩🏻 12.0 (fevereiro de 2019)

BoM de março de 2023 (interface do Compose 1.4) oferece suporte à versão mais recente de emojis, incluindo compatibilidade com versões anteriores do Android até o nível 21 da API.

Esse suporte não exige mudanças no app. Se você usar Text e TextField (Material 2 ou TextField, BasicText e BasicTextField), vai ter suporte moderno a emojis pronto para uso.

A melhor maneira de testar os emojis mais recentes no seu app é usando um dispositivo real com o nível 30 da API ou versões anteriores.

Se você estiver usando uma solução de emojis personalizada ou precisar desativar a resolução padrão de emojis no Compose por qualquer outro motivo, use PlatformTextStyle(emojiSupportMatch):

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

Interoperabilidade

Se o app usa visualizações e o Compose no mesmo Activity, confira se você está usando as APIs adequadas para configurar emojis corretamente. As seções a seguir descrevem quando usar cada API.

Estendendo de ComponentActivity

Se o Activity se estender do ComponentActivity do Compose em vez do AppCompatActivity, siga as instruções em Suporte a emojis sem AppCompat.

Como você não está estendendo AppCompatActivity, adicione a biblioteca Emoji2 às dependências e use EmojiTextView nas visualizações em vez do widget TextView, conforme mostrado no snippet abaixo:

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
            }
        }
    }
}

Em seguida, no seu arquivo XML:

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

Estendendo de AppCompatActivity

Se o Activity se estender de AppCompatActivity, será possível usar ComposeView para chamar funções combináveis. Os emojis são renderizados corretamente nas versões do Android quando você usa elementos combináveis de texto.

Se você estiver estendendo de AppCompatActivity, infle TextView do XML para que os emojis sejam renderizados corretamente.

Isso se aplica se você estiver inflando o XML:

  • fora de ComposeView, em Activity. Observe o uso de AppCompatActivity e TextView no snippet a seguir:

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
                        }
                    }
                }
            }
        )
    }
}

Para inflar um texto com AndroidView dentro de ComposeView, use AppCompatTextView para renderizar emojis corretamente:

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 }
                        )
                    }
                }
            }
        )
    }
}

Consulte a documentação das APIs de interoperabilidade para conferir mais detalhes.

Solução de problemas

Se você estiver vendo tofu (☐) em vez do emoji, primeiro verifique se o problema é seu dispositivo de teste específico. Há alguns itens principais que você pode verificar: