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

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

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

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

  • Пример Java- приложения для совместимости с Emoji | Котлин

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

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

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

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

Загружаемая конфигурация шрифтов

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

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

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

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

  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 | Котлин .

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

Компоненты библиотеки в процессе 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 со встроенной конфигурацией шрифтов, вам необходимо изменить зависимости пути к классам вашего проекта приложения в вашей среде разработки.

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

  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 .