La Vista previa para desarrolladores de Android 11 ya está disponible. Pruébala y comparte tus comentarios.

Compatibilidad con emojis

La biblioteca de compatibilidad EmojiCompat tiene como objetivo mantener los dispositivos Android actualizados con los últimos emojis. Evita que tu app muestre caracteres de emojis faltantes en forma de ☐, lo que indica que tu dispositivo no tiene una fuente para mostrar el texto. Gracias al uso de la biblioteca de compatibilidad EmojiCompat, los usuarios de tu app no necesitan esperar a que las actualizaciones del SO Android obtengan los últimos emojis.

Dispositivos que muestran emojis
Figura 1: Comparación de emojis

Consulta los siguientes recursos relacionados:

  • App de ejemplo de compatibilidad de emojis Java | Kotlin

¿Cómo funciona EmojiCompat?

La biblioteca de compatibilidad EmojiCompat proporciona clases para implementar la asistencia de emojis retrocompatibles en dispositivos con Android 4.4 (API nivel 19) y versiones posteriores. Puedes configurar EmojiCompat con fuentes empaquetadas o descargables. Para obtener más información sobre la configuración, consulta las siguientes secciones:

EmojiCompat identifica emojis para un determinado CharSequence; los sustituye con EmojiSpans si es necesario; y, por último, renderiza los glifos emoji. En la Figura 2, se demuestra este proceso.

Proceso de EmojiCompat
Figura 2: Proceso de EmojiCompat

Cómo configurar fuentes para descargar

La configuración de fuentes para descargar usa esa función de la biblioteca de compatibilidad para descargar una fuente de emojis. También actualiza los metadatos de emojis que la biblioteca de compatibilidad EmojiCompat necesita para mantenerse actualizada con las últimas versiones de la especificación Unicode.

Cómo agregar dependencias a la biblioteca de compatibilidad

Para usar la biblioteca de compatibilidad EmojiCompat, debes modificar las dependencias de ruta de clase del proyecto de tu app en tu entorno de desarrollo.

Para agregar una biblioteca de compatibilidad al proyecto de tu aplicación:

  1. Abre el archivo build.gradle de tu aplicación.
  2. Agrega la biblioteca de compatibilidad a la sección dependencies.
    dependencies {
        ...
        implementation "com.android.support:support-emoji:28.0.0"
    }
    

Cómo inicializar la configuración de fuentes para descargar

Debes inicializar EmojiCompat para cargar los metadatos y el tipo de letra. Como el proceso de inicialización puede tardar un poco, se ejecuta en un subproceso en segundo plano.

Para inicializar EmojiCompat con la configuración de fuentes para descargar, realiza los siguientes pasos:

  1. Crea una instancia de la clase FontRequest y proporciona la autoridad del proveedor de fuentes, el paquete del proveedor de fuentes, la consulta de fuentes y una lista de conjuntos de hashes para el certificado. Para obtener más información sobre FontRequest, consulta la sección Cómo usar la función Fuentes para descargar de forma de programática en la documentación Fuentes para descargar.
  2. Crea una instancia de FontRequestEmojiCompatConfig y proporciona instancias de Context y FontRequest.
  3. Inicializa EmojiCompat llamando al método init() y pasa la instancia de FontRequestEmojiCompatConfig.
  4. Kotlin

        class MyApplication : Application() {
    
            override fun onCreate() {
                super.onCreate()
                val fontRequest = FontRequest(
                        "com.example.fontprovider",
                        "com.example",
                        "emoji compat Font Query",
                        CERTIFICATES
                )
                val config = FontRequestEmojiCompatConfig(this, fontRequest)
                EmojiCompat.init(config)
            }
        }
        

    Java

        public class MyApplication extends Application {
          @Override
           public void onCreate() {
             super.onCreate();
             FontRequest fontRequest = new FontRequest(
               "com.example.fontprovider",
               "com.example",
               "emoji compat Font Query",
               CERTIFICATES);
             EmojiCompat.Config config = new FontRequestEmojiCompatConfig(this, fontRequest);
             EmojiCompat.init(config);
           }
        }
        
  5. Usa widgets EmojiCompat en los XML de diseño. Si estás usando AppCompat, consulta la sección Cómo usar los widgets EmojiCompat con AppCompat.
  6.     <android.support.text.emoji.widget.EmojiTextView
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"/>
    
        <android.support.text.emoji.widget.EmojiEditText
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"/>
    
        <android.support.text.emoji.widget.EmojiButton
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"/>
        

Para obtener más información sobre cómo configurar EmojiCompat con la configuración de fuentes para descargar, ve a la app de muestra de compatibilidad de emojis Java | Kotlin.

Componentes de la biblioteca

Componentes de la biblioteca en el proceso de EmojiCompat
Figura 3: Componentes de biblioteca en el proceso de EmojiCompat
Widgets: EmojiEditText, EmojiTextView y EmojiButton
Implementaciones de widgets predeterminadas para usar EmojiCompat con TextView, EditText y Button.
EmojiCompat
Superficie pública principal de la biblioteca de compatibilidad. Realiza todas las llamadas externas y coordina con las otras partes del sistema.
EmojiCompat.Config
Configura la instancia singleton que se creará.
EmojiSpan
Una subclase ReplacementSpan que reemplaza el carácter (secuencias) y renderiza el glifo.
EmojiCompat Fuente
EmojiCompat usa una fuente para mostrar emojis. Esta fuente es una versión modificada de la fuente de emojis para Android. La fuente se modifica de la siguiente manera:
  • A fin de ofrecer retrocompatibilidad para renderizar emojis, todos los caracteres de emojis se representan con un único punto de código Unicode en el Área de uso privado complementario A de Unicode que comienza con U+F0001.
  • Los metadatos de emojis adicionales se insertan en un formato binario en la fuente y se analizan en tiempo de ejecución mediante EmojiCompat. Los datos se incorporan en la tabla meta de la fuente, con la etiqueta privada Emji.

Opciones de configuración

Puedes usar la instancia EmojiCompat para modificar el comportamiento EmojiCompat. Puedes usar los siguientes métodos de la clase base para establecer la configuración:

Kotlin

    val config = FontRequestEmojiCompatConfig(...)
            .setReplaceAll(true)
            .setEmojiSpanIndicatorEnabled(true)
            .setEmojiSpanIndicatorColor(Color.GREEN)
            .registerInitCallback(object: EmojiCompat.InitCallback() {
                ...
            })
    

Java

    EmojiCompat.Config config = new FontRequestEmojiCompatConfig(...)
           .setReplaceAll(true)
           .setEmojiSpanIndicatorEnabled(true)
           .setEmojiSpanIndicatorColor(Color.GREEN)
           .registerInitCallback(new InitCallback() {...})

    

Cómo agregar objetos de escucha de inicialización

Las clases EmojiCompat y EmojiCompat proporcionan métodos registerInitCallback() y unregisterInitCallback() para registrar una devolución de llamada de inicialización. Para usar estos métodos, crea una instancia de la clase EmojiCompat.InitCallback. Llama a estos métodos y pasa la instancia de la clase EmojiCompat.InitCallback. Cuando la inicialización de la biblioteca de compatibilidad EmojiCompat es correcta, la clase EmojiCompat llama al método onInitialized(). Si la biblioteca no se inicializa, la clase EmojiCompat llama al método onFailed().

Para comprobar el estado de inicialización en cualquier momento, llama al método getLoadState(). Muestra uno de los siguientes valores: LOAD_STATE_LOADING, LOAD_STATE_SUCCEEDED o LOAD_STATE_FAILED.

Cómo usar EmojiCompat con widgets de AppCompat

Si estás usando AppCompat widgets, puedes usar widgets EmojiCompat que se extienden desde .

  1. Agrega la biblioteca de compatibilidad a la sección de dependencias.
  2.     dependencies {
              implementation "com.android.support:support-emoji-appcompat:$version"
        }
        
  3. Usa widgets EmojiCompatAppCompat Widget en los XML de diseño.
  4.     <android.support.text.emoji.widget.EmojiAppCompatTextView
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"/>
    
        <android.support.text.emoji.widget.EmojiAppCompatEditText
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"/>
    
        <android.support.text.emoji.widget.EmojiAppCompatButton
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"/>
        

Cómo configurar fuentes empaquetadas

La biblioteca de compatibilidad EmojiCompat también está disponible en una versión de fuentes empaquetadas. Este paquete incluye la fuente con los metadatos incorporados. El paquete también incluye un BundledEmojiCompatConfig que usa AssetManager para cargar metadatos y fuentes.

Nota: El tamaño de la fuente está en varios megabytes.

Cómo agregar dependencias a la biblioteca de compatibilidad

Para usar la biblioteca de compatibilidad EmojiCompat con la configuración de fuentes empaquetadas, debes modificar las dependencias de ruta de clase del proyecto de tu app en tu entorno de desarrollo.

Para agregar una biblioteca de compatibilidad al proyecto de tu aplicación:

  1. Abre el archivo build.gradle de tu aplicación.
  2. Agrega la biblioteca de compatibilidad a la sección dependencies.
    dependencies {
        ...
        implementation "com.android.support:support-emoji-bundled:$version"
    }
    

Cómo usar fuentes empaquetadas para configurar EmojiCompat

Para usar fuentes empaquetadas a fin de configurar EmojiCompat, realiza los siguientes pasos:

  1. Usa BundledEmojiCompatConfig para crear una instancia de EmojiCompat y proporciona una instancia de Context.
  2. Llama al método init() para inicializar EmojiCompat y pasa la instancia de BundledEmojiCompatConfig.

Kotlin

    class MyApplication : Application() {

        override fun onCreate() {
            super.onCreate()
            val config = BundledEmojiCompatConfig(this)
            EmojiCompat.init(config)
        }
    }
    

Java

    public class MyApplication extends Application {
        @Override
        public void onCreate() {
            super.onCreate();
            EmojiCompat.Config config = new BundledEmojiCompatConfig(this);
            EmojiCompat.init(config);
            ...
        }
    }
    

Cómo usar EmojiCompat sin widgets

EmojiCompat usa EmojiSpan para renderizar las imágenes correctas. Por lo tanto, tiene que convertir cualquier CharSequence dado en instancias Spanned con EmojiSpans. La clase EmojiCompat proporciona un método para convertir CharSequences en instancias Spanned con EmojiSpans. Con este método, puedes procesar y almacenar en caché las instancias procesadas en vez de la string sin procesar, lo que mejora el rendimiento de tu aplicación.

Kotlin

    val processed = EmojiCompat.get().process("neutral face \uD83D\uDE10")
    

Java

    CharSequence processed = EmojiCompat.get().process("neutral face \uD83D\uDE10");
    

Cómo usar EmojiCompat para los IME

Con la biblioteca de compatibilidad EmojiCompat, los teclados pueden renderizar los emoji compatibles con la aplicación con la que están interactuando. Los IME pueden usar el método hasEmojiGlyph() para verificar si EmojiCompat es capaz de renderizar un emoji. Este método toma un CharSequence de un emoji y muestra true si EmojiCompat puede detectarlo y renderizarlo.

El teclado también puede verificar la versión de la biblioteca de compatibilidad EmojiCompat que admite la app para determinar qué emojis debe renderizar en la paleta. Para verificar la versión, si está disponible, el teclado debe comprobar si las siguientes claves existen en el paquete EditorInfo.extras:

Después de recibir las claves del paquete EditorInfo.extras, el teclado puede usar el método hasEmojiGlyph(), donde metadataVersion es el valor de EDITOR_INFO_METAVERSION_KEY para verificar si la app puede renderizar un emoji específico.

Cómo usar EmojiCompat con widgets personalizados

Siempre puedes usar el método process() para preprocesar el CharSequence en tu app y agregarlo a cualquier widget que pueda renderizar instancias Spanned, por ejemplo, TextView. Además, EmojiCompat proporciona las siguientes clases de asistente de widgets para que puedas enriquecer tus widgets personalizados con asistencia de emojis con un mínimo esfuerzo.

Ejemplo de TextView

Kotlin

    class MyTextView(context: Context) : AppCompatTextView(context) {

        private val emojiTextViewHelper: EmojiTextViewHelper by lazy(LazyThreadSafetyMode.NONE) {
            EmojiTextViewHelper(this).apply {
                updateTransformationMethod()
            }
        }

        override fun setFilters(filters: Array<InputFilter>) {
            super.setFilters(emojiTextViewHelper.getFilters(filters))
        }

        override fun setAllCaps(allCaps: Boolean) {
            super.setAllCaps(allCaps)
            emojiTextViewHelper.setAllCaps(allCaps)
        }
    }
    

Java

    public class MyTextView extends AppCompatTextView {
       ...
       public MyTextView(Context context) {
           super(context);
           init();
       }
       ...
       private void init() {
           getEmojiTextViewHelper().updateTransformationMethod();
       }

       @Override
       public void setFilters(InputFilter[] filters) {
           super.setFilters(getEmojiTextViewHelper().getFilters(filters));
       }

       @Override
       public void setAllCaps(boolean allCaps) {
           super.setAllCaps(allCaps);
           getEmojiTextViewHelper().setAllCaps(allCaps);
       }

       private EmojiTextViewHelper getEmojiTextViewHelper() {
           ...
       }
    }
    
Ejemplo de EditText

Kotlin

    class MyEditText(context: Context) : AppCompatEditText(context) {

        private val emojiEditTextHelper: EmojiEditTextHelper by lazy(LazyThreadSafetyMode.NONE) {
            EmojiEditTextHelper(this).also {
                super.setKeyListener(it.getKeyListener(keyListener))
            }
        }

        override fun setKeyListener(input: KeyListener?) {
            input?.also {
                super.setKeyListener(emojiEditTextHelper.getKeyListener(it))
            }
        }

        override fun onCreateInputConnection(outAttrs: EditorInfo): InputConnection {
            val inputConnection: InputConnection = super.onCreateInputConnection(outAttrs)
            return emojiEditTextHelper.onCreateInputConnection(
                    inputConnection,
                    outAttrs
            ) as InputConnection
        }
    }
    

Java

    public class MyEditText extends AppCompatEditText {
       ...
       public MyEditText(Context context) {
           super(context);
           init();
       }
       ...
       private void init() {
           super.setKeyListener(getEmojiEditTextHelper().getKeyListener(getKeyListener()));
       }

       @Override
       public void setKeyListener(android.text.method.KeyListener keyListener) {
           super.setKeyListener(getEmojiEditTextHelper().getKeyListener(keyListener));
       }

       @Override
       public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
           InputConnection inputConnection = super.onCreateInputConnection(outAttrs);
           return getEmojiEditTextHelper().onCreateInputConnection(inputConnection, outAttrs);
       }

       private EmojiEditTextHelper getEmojiEditTextHelper() {
           ...
       }
    }
    

Preguntas frecuentes

  • ¿Cómo inicio la descarga de fuentes?
  • Las fuentes de emojis se descargan en la primera solicitud si no existen en el dispositivo. La programación de descarga es transparente para la app.

  • ¿Cuánto tiempo se necesita para inicializar?
  • Después de descargar la fuente, la inicialización de EmojiCompat tarda aproximadamente 150 milisegundos.

  • ¿Cuánta memoria usa la biblioteca de compatibilidad EmojiCompat?
  • Actualmente, la estructura de datos para encontrar los emojis se carga en la memoria de la app y usa alrededor de 200 KB.

  • ¿Puedo usar EmojiCompat para un TextView personalizado?
  • Sí EmojiCompat proporciona clases de asistentes para widgets personalizados. También es posible preprocesar una string determinada y convertirla en Spanned. Para obtener más información sobre las clases de asistentes de widget, consulta la sección Cómo usar EmojiCompat con widgets personalizados.

  • ¿Qué sucede si agrego widgets en los XML de diseño en dispositivos con Android 4.4 (API nivel 19) o versiones anteriores?
  • Puedes incluir la biblioteca de compatibilidad EmojiCompat o sus widgets en tus aplicaciones que admiten dispositivos con Android 4.4 (API nivel 19) o versiones anteriores. Sin embargo, si un dispositivo se ejecuta en una versión de Android anterior a la API nivel 19, EmojiCompat y sus widgets están en un estado "sin operación". Esto significa que EmojiTextView se comporta exactamente como un TextView normal. La instancia EmojiCompat entra inmediatamente en un estado LOAD_STATE_SUCCEEDED cuando llamas al método init().

Recursos adicionales

Para obtener más información sobre el uso de la biblioteca EmojiCompat, mira el video EmojiCompat.