Mostrar emoji

Unicode actualiza anualmente el conjunto de emojis estándar, ya que se incrementó rápidamente su uso en todo tipo de apps.

Si tu app muestra contenido de Internet o proporciona entrada de texto, te recomendamos encarecidamente que admitas las fuentes de emojis más recientes. De lo contrario, los emojis posteriores podrían mostrarse como un cuadrado pequeño llamado tofu (☐) o como otras secuencias de emojis renderizadas de manera incorrecta.

Las versiones de Android 11 (nivel de API 30) y anteriores no pueden actualizar la fuente de emojis, por lo que las apps que los muestran en esas versiones deben actualizarse de forma manual.

Estos son algunos ejemplos de emojis modernos.

Ejemplos Versión
🫩 🪉 🇨🇶 16.0 (septiembre de 2024)
🐦‍🔥 🧑‍🧑‍🧒‍🧒 👩🏽‍🦽‍➡️ 🇲🇶 15.1 (septiembre de 2023)
🩷 🫸🏼 🐦‍⬛ 15.0 (septiembre de 2022)
🫠 🫱🏼‍🫲🏿 🫰🏽 14.0 (septiembre de 2021)
😶‍🌫️ 🧔🏻‍♀️ 🧑🏿‍❤️‍🧑🏾 13.1 (septiembre de 2020)
🥲 🥷🏿 🐻‍❄️ 13.0 (marzo de 2020)
🧑🏻‍🦰 🧑🏿‍🦯 👩🏻‍🤝‍👩🏼 12.1 (octubre de 2019)
🦩 🦻🏿 👩🏼‍🤝‍👩🏻 12.0 (febrero de 2019)

La BOM de marzo de 2023 (Compose UI 1.4) incluye compatibilidad con la versión de emoji más reciente, incluida la retrocompatibilidad con versiones anteriores de Android hasta el nivel de API 21.

Esta compatibilidad no requiere cambios en tu app. Si usas Text y TextField (Material 2 o Material 3), o bien BasicText y BasicTextField, obtendrás compatibilidad con emojis modernos de inmediato.

La mejor manera de probar los emojis más recientes en tu app es usar un dispositivo real con el nivel de API 30 o inferior.

Si usas una solución de emojis personalizados o necesitas inhabilitar la resolución de emojis predeterminada en Compose por algún otro motivo, puedes usar PlatformTextStyle(emojiSupportMatch):

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

Interoperabilidad

Si tu app usa Views y Compose en el mismo Activity, asegúrate de usar las APIs adecuadas para configurar los emojis correctamente. En las siguientes secciones, se describe cuándo usar cada API.

Extensión desde ComponentActivity

Si tu Activity extiende desde ComponentActivity de Compose en lugar de AppCompatActivity, sigue las instrucciones de Cómo admitir emojis sin AppCompat.

Como no extiendes AppCompatActivity, agrega la biblioteca Emoji2 a tus dependencias y usa EmojiTextView en tus vistas en lugar del widget TextView, como se muestra en el siguiente fragmento:

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

Luego, en tu archivo XML, haz lo siguiente:

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

Extensión desde AppCompatActivity

Si tu Activity extiende de AppCompatActivity, puedes usar ComposeView para llamar a funciones de componibilidad. Los emojis se renderizan correctamente en todas las versiones de Android cuando usas elementos componibles de Text.

Si extiendes desde AppCompatActivity, aumenta TextView desde XML para que los emojis se rendericen correctamente.

Esto se aplica si aumentas el XML:

  • fuera de ComposeView, en Activity Observa el uso de AppCompatActivity y TextView en el siguiente fragmento:

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 un texto con AndroidView dentro de ComposeView, usa AppCompatTextView para renderizar emojis correctamente:

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

Consulta la documentación de las APIs de Interoperabilidad para obtener más detalles.

Solución de problemas

Si ves tofu (☐) en lugar del emoji, primero verifica si el problema se debe a tu dispositivo de prueba específico. Estos son algunos aspectos principales que puedes verificar: