表情符號相容性

EmojiCompat 支援資料庫可協助您讓 Android 裝置在最新狀態,擁有新推出的表情符號。這樣一來,您的應用程式就不會以 ☐ 的形式顯示缺少的表情符號字元,表示裝置沒有可以顯示文字的字型。只要使用 EmojiCompat 支援資料庫,應用程式使用者不必等待 Android OS 更新就能使用最新的表情符號。

顯示表情符號的裝置
圖 1. 表情符號比較

請參閱下列相關資源:

EmojiCompat 如何運作?

EmojiCompat 支援資料庫提供類別,可在搭載 Android 4.4 (API 級別 19) 以上版本的裝置上實作具回溯相容性的表情符號。您可使用套裝字型或可下載的字型設定 EmojiCompat。如要進一步瞭解設定,請參閱以下各節:

EmojiCompat 可辨識特定 CharSequence 的表情符號;如果需要的話,請將其替換成 EmojiSpans,最後再轉譯成表情符號字符。圖 2 說明了此流程。

EmojiCompat 流程
圖 2. EmojiCompat 流程

可下載的字型設定

可下載的字型設定使用「可下載的字型」支援資料庫功能下載表情符號字型,也會更新 EmojiCompat 支援資料庫所需的表情符號中繼資料,以跟上最新版的萬國碼 (Unicode) 規格。

新增支援資料庫依附元件

如要使用 EmojiCompat 支援資料庫,您必須在開發環境中修改應用程式專案的 classpath 依附元件。

如何在應用程式專案中新增支援資料庫:

  1. 開啟應用程式的 build.gradle 檔案。
  2. 將支援資料庫新增至 dependencies 區段。

Groovy

dependencies {
    ...
    implementation "com.android.support:support-emoji:28.0.0"
}

Kotlin

dependencies {
    ...
    implementation("com.android.support:support-emoji:28.0.0")
}

初始化可下載的字型設定

您必須初始化 EmojiCompat 才能載入中繼資料和字體。由於初始化可能需要一些時間,所以初始化流程會在背景執行緒執行。

如要利用可下載的字型設定初始化 EmojiCompat,請執行下列步驟:

  1. 建立 FontRequest 類別的例項,並提供字型提供者授權、字型提供者套件、字型查詢,以及憑證的雜湊組合清單。如要進一步瞭解 FontRequest,請參閱「可下載的字型」文件中的透過程式輔助方式使用可下載字型一節。
  2. 建立 FontRequestEmojiCompatConfig 的例項,並提供 ContextFontRequest 的例項。
  3. 呼叫 init() 方法並傳遞 FontRequestEmojiCompatConfig 的例項以初始化 EmojiCompat
  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. 在版面配置 XML 中使用 EmojiCompat 小工具。如果您使用的是 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 相容性應用程式範例 Java | Kotlin

資料庫元件

EmojiCompat 流程中的資料庫元件
圖 3. EmojiCompat 流程中的資料庫元件
小工具:EmojiEditTextEmojiTextViewEmojiButton
預設小工具實作,搭配 TextViewEditTextButton 使用 EmojiCompat
EmojiCompat
支援資料庫的主要公開途徑,執行所有外部呼叫並協調系統其他部分。
EmojiCompat.Config
設定要建立的單例模式例項。
EmojiSpan
ReplacementSpan 子類別,會取代字元 (序列),並轉譯字符。
EmojiCompat 字型
EmojiCompat 使用字型顯示表情符號。這個字型是 Android 表情符號字型的修改版本。字型的修改方式如下:
  • 為了提供回溯相容以轉譯表情符號,所有表情符號字元都以「補充私人使用區域 A」(Supplemental Private Use Area-A) 中從 U+F0001 開始的一種萬國碼 (Unicode) 碼點表示。
  • 額外的表情符號中繼資料會以二進位格式插入字型中,並由 EmojiCompat在執行階段剖析。資料會嵌入字型的 meta 表格中,私人標記為「Emji」

設定選項

您可以使用 EmojiCompat 例項來修改 EmojiCompat 的行為。基本類別的下列方法可用來設定:

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

新增初始化事件監聽器

EmojiCompatEmojiCompat 類別提供 registerInitCallback()unregisterInitCallback() 方法來註冊初始化回呼。如要使用這些方法,請建立 EmojiCompat.InitCallback 類別的例項。呼叫這些方法,並傳遞 EmojiCompat.InitCallback 類別的例項。當 EmojiCompat 支援資料庫的初始化成功時,EmojiCompat 類別會呼叫 onInitialized() 方法。如果資料庫無法初始化,EmojiCompat 類別會呼叫 onFailed() 方法。

如要在任何時間點查看初始化狀態,請呼叫 getLoadState() 方法。此方法會傳回下列其中一個值:LOAD_STATE_LOADINGLOAD_STATE_SUCCEEDEDLOAD_STATE_FAILED

搭配使用 EmojiCompat 與 AppCompat 小工具

如果您使用的是 AppCompat widgets,可以使用從 AppCompat widgets 延伸而來的 EmojiCompat小工具。

  1. 將支援資料庫新增至依附元件區段。

    Groovy

    dependencies {
        ...
        implementation "com.android.support:support-emoji-bundled:$version"
    }
    

    Kotlin

          dependencies {
              implementation("com.android.support:support-emoji-appcompat:$version")
          }
          

    Groovy

          dependencies {
              implementation "com.android.support:support-emoji-appcompat:$version"
          }
          
  2. 在版面配置 XML 中使用 EmojiCompat AppCompat Widget 小工具。
  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 支援資料庫也提供套裝字型版本。這個套件包含內嵌中繼資料的字型,也包含使用 AssetManager 載入中繼資料和字型的 BundledEmojiCompatConfig

注意:字型大小以 MB 為單位。

新增支援資料庫依附元件

如要使用搭配套裝字型設定的 EmojiCompat 支援資料庫,您「必須」在開發環境中修改應用程式專案的 classpath 依附元件。

如何在應用程式專案中新增支援資料庫:

  1. 開啟應用程式的 build.gradle 檔案。
  2. 將支援資料庫新增至 dependencies 區段。

Groovy

dependencies {
    ...
    implementation "com.android.support:support-emoji:28.0.0"
}

Kotlin

dependencies {
    ...
    implementation("com.android.support:support-emoji:28.0.0")
}

使用套裝字型設定 EmojiCompat

如要使用套裝字型設定 EmojiCompat,請執行下列步驟:

  1. 使用 BundledEmojiCompatConfig 建立 EmojiCompat 的例項,並提供 Context 的例項。
  2. 呼叫 init() 方法以初始化 EmojiCompat,並傳遞 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);
        ...
    }
}

不搭配小工具使用 EmojiCompat

EmojiCompat 使用 EmojiSpan 來轉譯正確的圖片,因此必須使用 EmojiSpans 將提供的任一 CharSequence 轉換為 Spanned 例項。EmojiCompat 類別提供一種方法,以使用 EmojiSpansCharSequences 轉換為 Spanned 例項。您可以使用此方法處理及快取例項 (而非原始字串),進而提升應用程式的效能。

Kotlin

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

Java

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

將 EmojiCompat 用於輸入法編輯器

使用 EmojiCompat 支援資料庫時,鍵盤可轉譯其互動的應用程式所支援的表情符號。輸入法編輯器可以使用 hasEmojiGlyph() 方法檢查 EmojiCompat 是否能轉譯表情符號。這個方法會擷取表情符號的 CharSequence,且如果 EmojiCompat 能偵測到及顯示表情符號,則會傳回 true

鍵盤也可以檢查應用程式支援的 EmojiCompat 支援資料庫版本,以判斷要在區塊面板轉譯哪個表情符號。為了確認版本 (如果有的話),鍵盤必須檢查 EditorInfo.extras 套件中是否有下列索引鍵:

收到 EditorInfo.extras 套件中的索引鍵後,鍵盤可以使用 hasEmojiGlyph() 方法 (其中 metadataVersionEDITOR_INFO_METAVERSION_KEY 的值) 檢查應用程式是否能轉譯特定表情符號。

搭配使用 EmojiCompat 與自訂小工具

您隨時可以使用 process() 方法,在應用程式中預先處理 CharSequence,並將其加入任何可轉譯 Spanned 例項的小工具;例如 TextView。此外,EmojiCompat 提供下列小工具輔助類別,讓您以最輕鬆的方式支援表情符號,使自訂小工具更豐富。

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

常見問題

  • 如何開始下載字型?
  • 如果裝置中沒有表情符號字型,裝置會在初次收到要求時加以下載。應用程式會知道下載時間。

  • 初始化需要多久?
  • 字型下載完畢後,初始化 EmojiCompat 約需 150 毫秒。

  • EmojiCompat 支援資料庫會使用多少記憶體?
  • 目前,用於尋找表情符號的資料結構已載入應用程式的記憶體中,約使用 200KB。

  • 可以使用 EmojiCompat 建立自訂 TextView 嗎?
  • 可以。EmojiCompat 提供自訂小工具適用的輔助類別 您也可以預先處理特定字串,並將其轉換為 Spanned。如要進一步瞭解小工具輔助類別,請參閱搭配使用 EmojiCompat 與自訂小工具一節。

  • 如果在搭載 Android 4.4 (API 級別 19) 以下版本的裝置上,於版面配置 XML 中新增小工具,會發生什麼事?
  • 您可以在支援 Android 4.4 (API 級別 19) 以下版本裝置的應用程式中,加入 EmojiCompat 支援資料庫或其小工具。不過,如果裝置執行的 Android 版本早於 API 級別 19,EmojiCompat 及其小工具就會處於「無法運作」狀態。這表示 EmojiTextView 的行為就像一般的 TextView.EmojiCompat 例項;在您呼叫 init() 方法後,會立即進入 LOAD_STATE_SUCCEEDED 狀態。

其他資源

如要進一步瞭解如何使用 EmojiCompat 資料庫,請觀看 EmojiCompat 影片。