Совместимость эмодзи

Попробуйте способ создания композиций.
Jetpack Compose — рекомендуемый набор инструментов для создания пользовательского интерфейса для Android. Узнайте, как поддерживать эмодзи в Compose.

Библиотека поддержки EmojiCompat призвана поддерживать актуальность эмодзи на устройствах Android. Она предотвращает отображение отсутствующих символов эмодзи в виде ☐, что указывает на отсутствие подходящего шрифта для отображения текста на вашем устройстве. Используя библиотеку поддержки EmojiCompat , пользователям вашего приложения не нужно ждать обновления ОС Android, чтобы получить последние эмодзи.

Устройства, отображающие эмодзи
Рисунок 1. Сравнение эмодзи.

Обратитесь к следующим соответствующим ресурсам:

  • Пример приложения для проверки совместимости с эмодзи на Java | Kotlin

Как работает EmojiCompat?

Библиотека поддержки EmojiCompat предоставляет классы для реализации обратной совместимости поддержки эмодзи на устройствах под управлением Android 4.4 (уровень API 19) и выше. Вы можете настроить EmojiCompat как с помощью встроенных, так и загружаемых шрифтов. Для получения дополнительной информации о настройке см. следующие разделы:

EmojiCompat идентифицирует эмодзи для заданной CharSequence , заменяет их на EmojiSpans , если это необходимо, и, наконец, отображает глифы эмодзи. На рисунке 2 показан этот процесс.

Процесс EmojiCompat
Рисунок 2. Процесс EmojiCompat.

Настройка загружаемых шрифтов

В настройках загружаемых шрифтов используется функция библиотеки поддержки загружаемых шрифтов для загрузки шрифта эмодзи. Также обновляются необходимые метаданные эмодзи, которые требуются библиотеке поддержки EmojiCompat для соответствия последним версиям спецификации Unicode.

Добавление зависимости от библиотеки поддержки.

Для использования библиотеки поддержки EmojiCompat необходимо изменить зависимости classpath вашего проекта приложения в среде разработки.

Чтобы добавить библиотеку поддержки в проект вашего приложения:

  1. Откройте файл build.gradle вашего приложения.
  2. Добавьте библиотеку поддержки в раздел dependencies .

Классный

dependencies {
    ...
    implementation "androidx.emoji:emoji:28.0.0"
}

Котлин

dependencies {
    ...
    implementation("androidx.emoji:emoji:28.0.0")
}

Инициализация конфигурации загружаемого шрифта.

Для загрузки метаданных и шрифта необходимо инициализировать EmojiCompat . Поскольку инициализация может занять некоторое время, процесс инициализации выполняется в фоновом потоке.

Для инициализации EmojiCompat с использованием загруженных настроек шрифтов выполните следующие действия:

  1. Создайте экземпляр класса FontRequest и укажите центр сертификации поставщика шрифтов, пакет поставщика шрифтов, запрос шрифта и список наборов хешей для сертификата. Для получения дополнительной информации о FontRequest см. раздел «Программное использование загружаемых шрифтов» в документации по загружаемым шрифтам .
  2. Создайте экземпляр класса FontRequestEmojiCompatConfig и предоставьте экземпляры классов Context и FontRequest .
  3. Инициализируйте EmojiCompat , вызвав метод init() и передав ему экземпляр FontRequestEmojiCompatConfig .
  4. Котлин

    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. Используйте виджеты EmojiCompat в XML-файлах разметки. Если вы используете AppCompat , обратитесь к разделу «Использование виджетов EmojiCompat с 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"/>

Для получения дополнительной информации о настройке EmojiCompat с использованием загружаемых настроек шрифтов перейдите к примеру приложения Emoji Compatibility Java | Kotlin .

Компоненты библиотеки

Компоненты библиотеки в процессе EmojiCompat
Рисунок 3. Компоненты библиотеки в процессе EmojiCompat.
Виджеты: EmojiEditText , EmojiTextView , EmojiButton
Реализации виджетов по умолчанию для использования EmojiCompat с TextView , EditText и Button .
EmojiCompat
Основной общедоступный интерфейс для библиотеки поддержки. Он выполняет все внешние запросы и координирует действия с другими частями системы.
EmojiCompat.Config
Настраивает создаваемый экземпляр синглтона.
EmojiSpan
Подкласс ReplacementSpan , который заменяет символы (последовательности) и отображает глиф.
Шрифт EmojiCompat
EmojiCompat использует шрифт для отображения эмодзи. Этот шрифт является модифицированной версией шрифта Android Emoji . Модификация шрифта выглядит следующим образом:
  • Для обеспечения обратной совместимости при отображении эмодзи все символы эмодзи представлены одной кодовой точкой Unicode в дополнительной области частного использования Unicode-A, начинающейся с U+F0001.
  • Дополнительные метаданные эмодзи вставляются в шрифт в бинарном формате и анализируются во время выполнения функцией EmojiCompat . Данные внедряются в meta шрифта с помощью приватного тега Emji .

Параметры конфигурации

Вы можете использовать экземпляр EmojiCompat для изменения поведения EmojiCompat . Для настройки конфигурации можно использовать следующие методы базового класса:

  • setReplaceAll() : Определяет, следует ли EmojiCompat заменять все найденные эмодзи на EmojiSpans . По умолчанию EmojiCompat пытается определить, может ли система отобразить эмодзи, и не заменяет их. Если установлено значение true , EmojiCompat заменяет все найденные эмодзи на EmojiSpans .
  • setEmojiSpanIndicatorEnabled() : Указывает, заменил ли EmojiCompat эмодзи на EmojiSpan . Если установлено значение true , EmojiCompat отображает фон для EmojiSpan . Этот метод в основном используется для отладки.
  • setEmojiSpanIndicatorColor() : Задает цвет для обозначения элемента EmojiSpan . Значение по умолчанию — GREEN .
  • registerInitCallback : Информирует приложение о состоянии инициализации EmojiCompat .

Котлин

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() {...})

Добавление слушателей инициализации

Классы EmojiCompat и EmojiCompat предоставляют методы registerInitCallback() и unregisterInitCallback() для регистрации функции обратного вызова инициализации. Чтобы использовать эти методы, создайте экземпляр класса EmojiCompat.InitCallback . Вызовите эти методы, передав в качестве аргумента экземпляр класса EmojiCompat.InitCallback . Если инициализация библиотеки поддержки EmojiCompat прошла успешно, класс EmojiCompat вызывает метод onInitialized() . Если инициализация библиотеки не удалась, класс EmojiCompat вызывает метод onFailed() .

Чтобы проверить состояние инициализации в любой момент, вызовите метод getLoadState() . Он возвращает одно из следующих значений: LOAD_STATE_LOADING , LOAD_STATE_SUCCEEDED или LOAD_STATE_FAILED .

Использование EmojiCompat с виджетами AppCompat

Если вы используете AppCompat widgets , вы можете использовать виджеты EmojiCompat , которые наследуются от AppCompat widgets .

  1. Добавьте библиотеку поддержки в раздел зависимостей.

    Классный

    dependencies {
        ...
        implementation "androidx.emoji:emoji-bundled:$version"
    }

    Котлин

          dependencies {
              implementation("androidx.emoji:emoji-appcompat:$version")
          }
          

    Классный

          dependencies {
              implementation "androidx.emoji:emoji-appcompat:$version"
          }
          
  2. Используйте виджеты EmojiCompat AppCompat Widget в XML-файлах разметки.
  3. <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"/>

Настройка комплекта шрифтов

Библиотека поддержки EmojiCompat также доступна в виде встроенного шрифта. Этот пакет включает шрифт со встроенными метаданными. Пакет также включает BundledEmojiCompatConfig , который использует AssetManager для загрузки метаданных и шрифтов.

Примечание: Размер шрифта указан в нескольких мегабайтах.

Добавление зависимости от библиотеки поддержки.

Для использования библиотеки поддержки EmojiCompat с встроенной конфигурацией шрифтов необходимо изменить зависимости classpath в вашем проекте приложения в среде разработки.

Чтобы добавить библиотеку поддержки в проект вашего приложения:

  1. Откройте файл build.gradle вашего приложения.
  2. Добавьте библиотеку поддержки в раздел dependencies .

Классный

dependencies {
    ...
    implementation "androidx.emoji:emoji:28.0.0"
}

Котлин

dependencies {
    ...
    implementation("androidx.emoji:emoji:28.0.0")
}

Использование встроенных шрифтов для настройки EmojiCompat

Чтобы использовать встроенные шрифты для настройки EmojiCompat , выполните следующие действия:

  1. Используйте BundledEmojiCompatConfig для создания экземпляра EmojiCompat и предоставления экземпляра Context .
  2. Вызовите метод init() для инициализации EmojiCompat и передайте ему экземпляр класса BundledEmojiCompatConfig .

Котлин

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

Использование EmojiCompat без виджетов

EmojiCompat использует EmojiSpan для корректного отображения изображений. Поэтому он должен преобразовывать любой заданный CharSequence в экземпляры Spanned с помощью EmojiSpans . Класс EmojiCompat предоставляет метод для преобразования CharSequences в экземпляры Spanned с помощью EmojiSpans . Используя этот метод, вы можете обрабатывать и кэшировать обработанные экземпляры вместо исходной строки, что повышает производительность вашего приложения.

Котлин

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

Java

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

Использование EmojiCompat для IME

Используя библиотеку поддержки EmojiCompat , клавиатуры могут отображать эмодзи, поддерживаемые приложением, с которым они взаимодействуют. Интерфейсы ввода-вывода (IME) могут использовать метод hasEmojiGlyph() для проверки того, способен ли EmojiCompat отображать эмодзи. Этот метод принимает CharSequence содержащий эмодзи, и возвращает true если EmojiCompat может обнаружить и отобразить эмодзи.

Клавиатура также может проверить версию библиотеки поддержки EmojiCompat , которую поддерживает приложение, чтобы определить, какие эмодзи следует отображать в палитре. Для проверки версии, если она доступна, клавиатуре необходимо проверить, существуют ли следующие ключи в пакете EditorInfo.extras :

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

  • EDITOR_INFO_REPLACE_ALL_KEY
  • Если ключ существует и имеет значение true , это означает, что приложение вызвало метод SetReplaceAll() . Для получения дополнительной информации о настройке EmojiCompat см. раздел «Параметры конфигурации» .

После получения ключей из пакета EditorInfo.extras клавиатура может использовать метод hasEmojiGlyph() , где metadataVersion — это значение параметра EDITOR_INFO_METAVERSION_KEY , чтобы проверить, может ли приложение отобразить определенный эмодзи.

Использование EmojiCompat с пользовательскими виджетами

Вы всегда можете использовать метод process() для предварительной обработки CharSequence в вашем приложении и добавления его в любой виджет, который может отображать экземпляры Spanned ; например, TextView . Кроме того, EmojiCompat предоставляет следующие вспомогательные классы для виджетов, позволяющие с минимальными усилиями обогатить ваши пользовательские виджеты поддержкой эмодзи.

Пример текстового поля

Котлин

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() {
       ...
   }
}
Пример текста-запроса

Котлин

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() {
       ...
   }
}

Часто задаваемые вопросы

  • Как мне начать загрузку шрифта?
  • Шрифты с эмодзи загружаются при первом запросе, если они отсутствуют на устройстве. Планирование загрузки происходит незаметно для приложения.

  • Сколько времени занимает инициализация?
  • После загрузки шрифта инициализация EmojiCompat занимает приблизительно 150 миллисекунд.

  • Сколько памяти использует библиотека поддержки EmojiCompat?
  • В настоящее время структура данных для поиска эмодзи загружается в память приложения и занимает около 200 КБ.

  • Можно ли использовать EmojiCompat для пользовательского TextView?
  • Да. EmojiCompat предоставляет вспомогательные классы для пользовательских виджетов. Также можно предварительно обработать заданную строку и преобразовать её в Spanned . Для получения дополнительной информации о вспомогательных классах виджетов см. раздел «Использование EmojiCompat с пользовательскими виджетами» .

  • Что произойдет, если я добавлю виджеты в XML-файлы разметки на устройствах под управлением Android 4.4 (уровень API 19) или ниже?
  • Вы можете включить библиотеку поддержки EmojiCompat или её виджеты в свои приложения, поддерживающие устройства под управлением Android 4.4 (уровень API 19) или ниже. Однако, если устройство работает на версии Android ниже уровня API 19, EmojiCompat и её виджеты находятся в состоянии «бездействия». Это означает, что EmojiTextView ведёт себя точно так же LOAD_STATE_SUCCEEDED как обычный TextView ; он немедленно переходит в состояние EmojiCompat при вызове метода init() .

Дополнительные ресурсы

Для получения дополнительной информации об использовании библиотеки EmojiCompat посмотрите видеоролик EmojiCompat .