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

Попробуйте способ Compose
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)
        }
    }

    Ява

    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
Настраивает создаваемый экземпляр singleton.
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() {
            ...
        })

Ява

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

Ява

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

Ява

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

Ява

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() {
       ...
   }
}
Образец EditText

Котлин

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

Ява

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 ведет себя точно так же, как обычный TextView . EmojiCompat ; он немедленно переходит в состояние LOAD_STATE_SUCCEEDED при вызове метода init() .

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

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