Zgodność emotikonów

Biblioteka pomocy EmojiCompat ma na celu zapewnienie aktualności emotikonów na urządzeniach z Androidem. Zapobiega to wyświetlaniu w aplikacji brakujących znaków emotikonów w postaci skonfiguruj, co oznacza, że Twoje urządzenie nie ma czcionki umożliwiającej wyświetlanie tekstu. Dzięki bibliotece pomocy EmojiCompat użytkownicy Twojej aplikacji nie muszą czekać na aktualizacje systemu operacyjnego Android, aby uzyskać najnowsze emotikony.

Urządzenia wyświetlające emotikony
Rysunek 1. Porównanie emotikonów

Zapoznaj się z tymi powiązanymi materiałami:

  • Przykładowa aplikacja dot. zgodności emotikonów Java | Kotlin

Jak działa EmojiCompat?

Biblioteka pomocy EmojiCompat zawiera klasy do implementacji zgodnej wstecznie obsługi emotikonów na urządzeniach z Androidem 4.4 (poziom interfejsu API 19) lub nowszym. Możesz skonfigurować EmojiCompat z czcionkami w pakiecie lub dostępnymi do pobrania. Więcej informacji o konfiguracji znajdziesz w tych sekcjach:

EmojiCompat identyfikuje emotikony dla danego elementu CharSequence, zastępuje je elementem EmojiSpans, jeśli jest to wymagane, a na koniec renderuje glify emotikonów. Proces ten przedstawiono na Rysunku 2.

Proces emotikonów
Rysunek 2. Proces Emotikony

Konfiguracja czcionek do pobrania

Konfiguracja czcionek do pobrania korzysta z funkcji biblioteki obsługi czcionek z możliwością pobierania w celu pobrania czcionki emotikonów. Aktualizuje również niezbędne metadane emotikonów, które biblioteka obsługująca EmojiCompat musi zapewnić zgodność z najnowszymi wersjami specyfikacji Unicode.

Dodaję zależność biblioteki pomocy

Aby korzystać z biblioteki pomocy EmojiCompat, musisz zmodyfikować zależności ścieżki klasy projektu w środowisku programistycznym.

Aby dodać bibliotekę pomocy do projektu aplikacji:

  1. Otwórz plik build.gradle swojej aplikacji.
  2. Dodaj bibliotekę pomocy do sekcji dependencies.

Odlotowy

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

Kotlin

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

Inicjuję konfigurację czcionki do pobrania

Aby wczytać metadane i krój czcionki, musisz zainicjować EmojiCompat. Ponieważ inicjowanie może trochę potrwać, proces inicjowania działa w wątku w tle.

Aby zainicjować EmojiCompat za pomocą konfiguracji czcionki, którą możesz pobrać, wykonaj te czynności:

  1. Utwórz instancję klasy FontRequest i podaj nazwę urzędu dostawcy czcionki, pakiet dostawcy czcionek, zapytanie dotyczące czcionek oraz listę zestawów haszów certyfikatu. Więcej informacji o FontRequest znajdziesz w sekcji Automatyczne używanie czcionek do pobrania w dokumentacji czcionek do pobrania.
  2. Utwórz instancję FontRequestEmojiCompatConfig i podaj instancje Context oraz FontRequest.
  3. Zainicjuj EmojiCompat, wywołując metodę init() i przekazując instancję 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. Używaj widżetów EmojiCompat w plikach XML układu. Jeśli używasz funkcji AppCompat, zapoznaj się z sekcją Korzystanie z widżetów EmojiCompat w 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"/>
    

Więcej informacji o tym, jak skonfigurować EmojiCompat przy użyciu konfiguracji czcionki, którą można pobrać, znajdziesz w artykule na temat przykładowej aplikacji zgodności emotikonów Java | Kotlin.

Komponenty biblioteki

Komponenty biblioteki w procesie EmojiCompat
Rysunek 3. Komponenty biblioteki w procesie EmojiCompat
Widżety: EmojiEditText, EmojiTextView, EmojiButton
Domyślne implementacje widżetów używające EmojiCompat z tagami TextView, EditText i Button.
EmojiCompat
Główna przestrzeń publiczna dla biblioteki pomocy. Wykonuje wszystkie połączenia zewnętrzne i koordynuje działania z innymi częściami systemu.
EmojiCompat.Config
Konfiguruje instancję typu singleton do utworzenia.
EmojiSpan
Podklasa ReplacementSpan, która zastępuje znak (sekwencje) i renderuje glif.
Czcionka: EmojiCompat
EmojiCompat używa czcionki do wyświetlania emotikonów. Ta czcionka jest zmodyfikowaną wersją czcionki emotikonów Androida. Czcionka jest modyfikowana w ten sposób:
  • Aby zapewnić zgodność wsteczną do renderowania emotikonów, wszystkie znaki emotikonów są reprezentowane przez jeden punkt kodowy Unicode w dodatkowym obszarze do prywatnego użytku Unicode zaczynający się od U+F0001.
  • Dodatkowe metadane emotikonów są wstawiane do czcionki w formacie binarnym i są analizowane w czasie działania przez funkcję EmojiCompat. Dane są umieszczone w tabeli meta czcionki z tagiem prywatnym Emji.

Opcje konfiguracji

Możesz użyć instancji EmojiCompat, aby zmodyfikować działanie EmojiCompat. Aby ustawić konfigurację, możesz użyć tych metod z klasy podstawowej:

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

Dodawanie detektorów inicjowania

Klasy EmojiCompat i EmojiCompat udostępniają metody registerInitCallback() i unregisterInitCallback() służące do rejestrowania wywołania zwrotnego inicjowania. Aby korzystać z tych metod, utwórz instancję klasy EmojiCompat.InitCallback. Wywołaj te metody i przekaż instancję klasy EmojiCompat.InitCallback. Po zainicjowaniu biblioteki pomocy EmojiCompat klasa EmojiCompat wywołuje metodę onInitialized(). Jeśli biblioteki nie uda się zainicjować, klasa EmojiCompat wywoła metodę onFailed().

Aby w dowolnym momencie sprawdzić stan inicjowania, wywołaj metodę getLoadState(). Zwraca jedną z tych wartości: LOAD_STATE_LOADING, LOAD_STATE_SUCCEEDED lub LOAD_STATE_FAILED.

Używanie funkcji EmojiCompat z widżetami AppCompat

Jeśli używasz AppCompat widgets, możesz używać widżetów (EmojiCompat), które wykraczają poza zakres AppCompat widgets.

  1. Dodaj bibliotekę pomocy do sekcji zależności.

    Odlotowy

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

    Kotlin

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

    Odlotowy

          dependencies {
              implementation "androidx.emoji:emoji-appcompat:$version"
          }
          
  2. Użyj widżetów EmojiCompat AppCompat Widget w plikach XML układu.
  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"/>
    

Konfiguracja pakietów czcionek

Biblioteka pomocy EmojiCompat jest też dostępna w pakiecie czcionek. Ten pakiet zawiera czcionkę i osadzone metadane. Pakiet zawiera też właściwość BundledEmojiCompatConfig, która używa AssetManager do wczytywania metadanych i czcionek.

Uwaga: rozmiar czcionki jest podany w wielu megabajtach.

Dodaję zależność biblioteki pomocy

Aby korzystać z biblioteki pomocy EmojiCompat ze łączoną konfiguracją czcionek, musisz zmodyfikować zależności ścieżki klasy projektu w środowisku programistycznym.

Aby dodać bibliotekę pomocy do projektu aplikacji:

  1. Otwórz plik build.gradle swojej aplikacji.
  2. Dodaj bibliotekę pomocy do sekcji dependencies.

Odlotowy

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

Kotlin

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

Korzystanie z pakietów czcionek do konfigurowania EmojiCompat

Aby użyć czcionek w pakiecie do skonfigurowania EmojiCompat, wykonaj te czynności:

  1. Użyj BundledEmojiCompatConfig, aby utworzyć instancję EmojiCompat i udostępnić instancję Context.
  2. Wywołaj metodę init(), aby zainicjować EmojiCompat i przekazać instancję 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);
        ...
    }
}

Korzystanie z kompleksu emotikonów bez widżetów

EmojiCompat używa EmojiSpan do renderowania poprawnych obrazów. Dlatego musi przekonwertować każdą instancję CharSequence na Spanned instancję za pomocą EmojiSpans. Klasa EmojiCompat udostępnia metodę konwertowania instancji CharSequences na instancje (Spanned) za pomocą EmojiSpans. Korzystając z tej metody, zamiast nieprzetworzonego ciągu znaków możesz przetwarzać i buforować przetworzone instancje, co zwiększa wydajność aplikacji.

Kotlin

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

Java

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

Korzystanie z emotikonu na potrzeby IME

Dzięki bibliotece obsługi EmojiCompat klawiatury mogą renderować emotikony obsługiwane przez aplikację, z której korzystają. IME mogą używać metody hasEmojiGlyph(), aby sprawdzić, czy EmojiCompat potrafi renderować emotikon. Ta metoda pobiera CharSequence emotikona i zwraca true, jeśli EmojiCompat może go wykryć i wyrenderować.

Aby określić, które emotikony mają być renderowane w palecie, klawiatura może też sprawdzić wersję biblioteki obsługi EmojiCompat, którą obsługuje aplikacja. Aby sprawdzić wersję, klawiatura musi sprawdzić, czy w pakiecie EditorInfo.extras są wymienione te klawisze:

Po otrzymaniu klawiszy w pakiecie EditorInfo.extras klawiatura może użyć metody hasEmojiGlyph(), gdzie metadataVersion to wartość parametru EDITOR_INFO_METAVERSION_KEY, aby sprawdzić, czy aplikacja może wyrenderować konkretny emotikon.

Używanie funkcji EmojiCompat z niestandardowymi widżetami

W dowolnej chwili możesz użyć metody process(), aby wstępnie przetworzyć CharSequence w aplikacji i dodać ją do dowolnego widżetu, który może renderować wystąpienia Spanned, np. TextView. Dodatkowo EmojiCompat udostępnia opisane poniżej klasy pomocnicze widżetów, które pozwalają bez trudu wzbogacać niestandardowe widżety o obsługę emotikonów.

Przykładowy widok tekstu

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() {
       ...
   }
}
Przykładowy tekst 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() {
       ...
   }
}

Najczęstsze pytania

  • Jak rozpocząć pobieranie czcionki?
  • Czcionki emotikonów są pobierane przy pierwszym żądaniu, jeśli nie ma ich na urządzeniu. Harmonogram pobierania jest widoczny dla aplikacji.

  • Ile czasu zajmuje inicjowanie?
  • Po pobraniu czcionki zainicjowanie EmojiCompat trwa około 150 milisekund.

  • Ile pamięci używa biblioteka emotikonów?
  • Obecnie struktura danych służąca do znajdowania emotikonów jest wczytywana w pamięci aplikacji i zajmuje około 200 KB.

  • Czy mogę użyć funkcji EmojiCompat, aby utworzyć niestandardowy widok TextView?
  • Tak. EmojiCompat zapewnia klasy pomocnicze dla niestandardowych widżetów. Możesz też wstępnie przetworzyć dany ciąg znaków i przekonwertować go na parametr Spanned. Więcej informacji o klasach pomocniczych widżetów znajdziesz w sekcji o używaniu emotikonów niestandardowych z widżetami niestandardowymi.

  • Co się stanie, jeśli dodam widżety w plikach XML układu na urządzeniach z Androidem 4.4 (poziom interfejsu API 19) lub starszym?
  • Możesz dołączyć bibliotekę pomocy EmojiCompat lub jej widżety do swoich aplikacji obsługujących urządzenia z Androidem 4.4 (poziom interfejsu API 19) lub niższym. Jeśli jednak urządzenie działa na urządzeniu z Androidem w wersji starszej niż 19 interfejsu API, EmojiCompat i jego widżety będą w stanie „brak operacji”. Oznacza to, że EmojiTextView działa dokładnie tak samo jak standardowy element TextView. EmojiCompat; natychmiast przechodzi w stan LOAD_STATE_SUCCEEDED po wywołaniu metody init().

Dodatkowe materiały

Więcej informacji o korzystaniu z biblioteki EmojiCompat znajdziesz w filmie EmojiCompat.