Hỗ trợ biểu tượng cảm xúc hiện đại

Bộ biểu tượng cảm xúc (emoji) tiêu chuẩn được Unicode cập nhật hằng năm, cùng với việc người dùng sử dụng biểu tượng cảm xúc tăng nhanh chóng trên mọi loại ứng dụng.

Nếu ứng dụng của bạn hiển thị nội dung Internet hoặc cung cấp tính năng nhập văn bản, bạn nên hỗ trợ các phông chữ biểu tượng cảm xúc mới nhất. Nếu không, biểu tượng cảm xúc mới hơn có thể hiển thị dưới dạng một ô vuông nhỏ gọi là đậu phụ (tofu) (☐) hoặc các trình tự biểu tượng cảm xúc hiển thị không chính xác.

Phiên bản Android 11 (API cấp 30) trở xuống không có khả năng cập nhật phông chữ biểu tượng cảm xúc. Vì vậy, bạn phải cập nhật thủ công mọi ứng dụng hiển thị các biểu tượng cảm xúc này trên những phiên bản Android thấp hơn.

Sau đây là một vài ví dụ về biểu tượng cảm xúc hiện đại.

Ví dụ Phiên bản
😶‍🌫️ 🧔🏻‍♀️ 🧑🏿‍❤️‍🧑🏾 13.1 (Tháng 9 năm 2020)
🥲 🥷🏿 🐻‍❄️ 13.0 (Tháng 3 năm 2020)
🧑🏻‍🦰 🧑🏿‍🦯 👩🏻‍🤝‍👩🏼 12.1 (Tháng 10 năm 2019)
🦩 🦻🏿 👩🏼‍🤝‍👩🏻 12.0 (Tháng 2 năm 2019)

Thư viện androidx.emoji2:emoji2 cung cấp khả năng tương thích ngược đơn giản hơn với các phiên bản Android thấp hơn. Thư viện emoji2 là phần phụ thuộc của thư viện AppCompat và không cần thêm cấu hình nào để hoạt động.

Điều kiện tiên quyết

Để xác nhận rằng ứng dụng của bạn hiển thị đúng biểu tượng cảm xúc mới, hãy chạy ứng dụng trên một thiết bị sử dụng phiên bản từ Android 4.4 (API cấp 19) tới Android 10 (API cấp 29) dành cho tất cả mọi người. Trang này bao gồm các biểu tượng cảm xúc hiện đại mà bạn có thể hiển thị để thử nghiệm.

Sử dụng AppCompat để hỗ trợ biểu tượng cảm xúc mới nhất

AppCompat 1.4 có hỗ trợ cho biểu tượng cảm xúc từ phiên bản Android 4.4 trở lên.

Cách dùng AppCompat để hỗ trợ biểu tượng cảm xúc mới nhất:

  1. Kiểm tra để đảm bảo mô-đun của bạn chạy phiên bản thư viện appcompat 1.4.0-alpha01 trở lên.

    build.gradle
    
    // Ensure version is 1.4.0-alpha01 or higher.
    implementation "androidx.appcompat:appcompat.$appcompatVersion"
    
  2. Hãy đảm bảo rằng tất cả hoạt động hiển thị văn bản đều mở rộng lớp AppCompatActivity.

    Kotlin

    MyActivity.kt
    
    class MyActivity: AppCompatActivity {
       …
    }
    

    Java

    MyActivity.java
    
    class MyActivity extends AppCompatActivity {
       …
    }
    
  3. Để kiểm tra hoạt động tích hợp của bạn, hãy chạy ứng dụng trên một thiết bị chạy Android 10 trở xuống và hiển thị chuỗi thử nghiệm sau. Hãy đảm bảo rằng tất cả các ký tự hiển thị chính xác.

    • 13.1: 😶‍🌫️, 🧔🏻‍♀️, 🧑🏿‍❤️‍🧑🏾
    • 13.0: 🥲, 🥷🏿, 🐻‍❄️
    • 12.1: 🧑🏻‍🦰, 🧑🏿‍🦯, 👩🏻‍🤝‍👩🏼
    • 12.0: 🦩, 🦻🏿, 👩🏼‍🤝‍👩🏻

Vậy là xong! Ứng dụng của bạn sẽ tự động hiển thị biểu tượng cảm xúc có thể tương thích ngược trên mọi thiết bị sử dụng trình cung cấp phông chữ có thể tải xuống tương thích với emoji2, chẳng hạn như các thiết bị sử dụng dịch vụ Google Play.

Nếu ứng dụng của bạn đang sử dụng AppCompat nhưng hiển thị ký hiệu đậu phụ (☐)

Trong một số trường hợp, ứng dụng của bạn có thể hiển thị đậu phụ (☐) thay vì biểu tượng cảm xúc phù hợp, mặc dù bạn đã thêm thư viện AppCompat. Sau đây là một số nguyên nhân có thể xảy ra và giải pháp.

Bạn đang chạy ứng dụng này trên một thiết bị gần đây đã cài đặt ROM hoặc trên một trình mô phỏng hoàn toàn mới

Xoá dữ liệu ứng dụng cho dịch vụ Google Play để xoá mọi hoạt động lưu phông chữ vào bộ nhớ đệm có thể đã xảy ra trong quá trình khởi động. Khi bạn làm như vậy, trường hợp này thường tự giải quyết sau vài giờ.

Để xoá dữ liệu ứng dụng, hãy làm như sau:

  1. Trên thiết bị Android của bạn, hãy mở phần Cài đặt.

  2. Trong phần Cài đặt, hãy nhấn vào Ứng dụng và thông báo.

  3. Nhấn vào Xem tất cả ứng dụng hoặc Thông tin ứng dụng.

  4. Di chuyển qua các ứng dụng rồi nhấn vào Dịch vụ Google Play.

  5. Nhấn vào Bộ nhớ và bộ nhớ đệm.

  6. Nhấn vào Xoá bộ nhớ đệm.

Ứng dụng của bạn hiện không sử dụng lớp AppCompat liên quan đến văn bản

Điều này có thể xảy ra nếu bạn không mở rộng AppCompatActivity, hoặc nếu bạn bắt đầu tạo phiên bản của một thành phần hiển thị trong mã chẳng hạn như TextView. Đảm bảo rằng bạn làm theo các bước như sau:

  • Hoạt động mở rộng AppCompatActivity.
  • Nếu bạn tạo chế độ xem trong mã, hãy sử dụng appcompat subclass chính xác.

AppCompatActivity tự động tăng cường AppCompatTextView thay cho TextView khi tăng cường XML, vì vậy bạn không cần phải cập nhật XML.

Điện thoại thử nghiệm không hỗ trợ phông chữ có thể tải xuống

Xác minh rằng DefaultEmojiCompatConfig.create trả về cấu hình có giá trị.

Trình mô phỏng ở cấp độ API cũ hơn chưa nâng cấp dịch vụ Google Play

Khi sử dụng một trình mô phỏng ở cấp API cũ hơn, có thể cần phải nâng cấp dịch vụ Google Play đi kèm cho emoji2 để tìm trình cung cấp phông chữ. Để làm điều này, hãy đăng nhập vào Cửa hàng Google Play trên trình mô phỏng.

Để xác minh rằng bạn đã cài đặt phiên bản gần đây nhất, hãy làm như sau:

  1. Chạy lệnh sau:

    adb shell dumpsys package com.google.android.gms | grep version
    
  2. Kiểm tra để đảm bảo rằng versionCode cao hơn 211200000.

Hỗ trợ biểu tượng cảm xúc không có AppCompat

Nếu ứng dụng của bạn không có appcompat thì có thể sử dụng trực tiếp emoji2. Phương thức này cần xử lý thêm nên chỉ sử dụng khi ứng dụng của bạn không thể dùng appcompat.

Để hỗ trợ biểu tượng cảm xúc mà không cần thư viện AppCompat, hãy làm như sau:

  1. Trong tệp build.gradle của ứng dụng, hãy thêm emoji2emoji2-views.

    build.gradle
    
    def emojiVersion = "1.0.0-alpha03"
    implementation "androidx.emoji2:emoji2:$emojiVersion"
    implementation "androidx.emoji2:emoji2-views:$emojiVersion"
    

    Mô-đun emoji2-views cung cấplớp con của TextView, ButtonEditText triển khai EmojiCompat. Đồng thời, không nên sử dụng mô-đun này trong ứng dụng chứa appcompat vì mô-đun này đã triển khai EmojiCompat.

  2. Trong XML hoặc mã (bất kể bạn sẽ sử dụng TextView, EditText hay Button), hãy sử dụng EmojiTextView, EmojiEditText hoặc EmojiButton.

    activity_main.xml
    
    <androidx.emoji2.widget.EmojiTextView … />
    <androidx.emoji2.widget.EmojiEditText … />
    <androidx.emoji2.widget.EmojiButton … />
    

    Bằng cách thêm mô-đun emoji2, hệ thống sử dụng trình cung cấp mặc định phông chữ có thể tải xuống để tự động tải phông chữ biểu tượng cảm xúc ngay sau khi khởi động ứng dụng mà không cần thêm cấu hình.

  3. Để kiểm tra hoạt động tích hợp của bạn, hãy chạy ứng dụng trên một thiết bị chạy Android 10 trở xuống và hiển thị các chuỗi thử nghiệm sau đây. Hãy đảm bảo rằng tất cả các ký tự hiển thị chính xác.

    • 13.1: 😶‍🌫️, 🧔🏻‍♀️, 🧑🏿‍❤️‍🧑🏾
    • 13.0: 🥲, 🥷🏿, 🐻‍❄️
    • 12.1: 🧑🏻‍🦰, 🧑🏿‍🦯, 👩🏻‍🤝‍👩🏼
    • 12.0: 🦩, 🦻🏿, 👩🏼‍🤝‍👩🏻

Sử dụng EmojiCompat mà không cần tiện ích

EmojiCompat sử dụng EmojiSpan để hiển thị hình ảnh chính xác. Do đó, đối tượng này phải chuyển đổi bất kỳ đối tượng [CharSequence] nào thành đối tượng Spanned có đối tượng EmojiSpan. Lớp EmojiCompat cung cấp phương thức process() để chuyển đổi CharSequences thành các phiên bản Spanned. Khi sử dụng phương thức này, bạn có thể gọi process() trong nền và kết quả của bộ nhớ đệm để cải thiện hiệu suất của ứng dụng.

Kotlin

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

Java

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

Sử dụng EmojiCompat để chỉnh sửa phương thức nhập

Lớp EmojiCompat cho phép bàn phím hiển thị biểu tượng cảm xúc được ứng dụng mà họ đang tương tác hỗ trợ. Trình chỉnh sửa phương thức nhập (IME) có thể sử dụng phương thức hasEmojiGlyph() để kiểm tra xem phiên bản của EmojiCompat có thể hiển thị biểu tượng cảm xúc hay không. Phương thức này sẽ nhận một CharSequence biểu tượng cảm xúc và trả về true nếu EmojiCompat có thể phát hiện và hiển thị biểu tượng cảm xúc đó.

Bàn phím cũng có thể kiểm tra phiên bản EmojiCompat mà ứng dụng hỗ trợ để xác định biểu tượng cảm xúc nào sẽ hiển thị trong bảng chế độ xem. Để kiểm tra phiên bản này, nếu có, bàn phím có thể tìm các mã khoá sau trong gói EditorInfo.extras:

  • EDITOR_INFO_METAVERSION_KEY: Thể hiện phiên bản siêu dữ liệu của biểu tượng cảm xúc mà ứng dụng sử dụng. Nếu mã khoá này không tồn tại thì ứng dụng không sử dụng EmojiCompat.
  • EDITOR_INFO_REPLACE_ALL_KEY: Nếu mã khoá này tồn tại và được đặt thành true, thì ứng dụng đã định cấu hình EmojiCompat để thay thế tất cả biểu tượng cảm xúc, ngay cả khi các biểu tượng cảm xúc đó có trong hệ thống.

Tìm hiểu thêm về cách định cấu hình một phiên bản của EmojiCompat.

Sử dụng biểu tượng cảm xúc trong thành phần hiển thị tuỳ chỉnh

Nếu ứng dụng của bạn có thành phần hiển thị tuỳ chỉnh là các lớp con trực tiếp hoặc gián tiếp của TextView (ví dụ: Button, Switch hoặc EditText) và có thể hiển thị nội dung do người dùng tạo, mỗi thành phần hiển thị nên triển khai EmojiCompat.

Quá trình này sẽ khác nhau tuỳ thuộc vào việc ứng dụng của bạn có sử dụng thư viện appcompat hay không.

Thêm thành phần hiển thị tuỳ chỉnh cho các ứng dụng bằng AppCompat

Nếu ứng dụng của bạn sử dụng AppCompat, hãy mở rộng việc triển khai AppCompat thay vì triển khai nền tảng. Sử dụng bảng sau đây làm hướng dẫn về cách mở rộng thành phần hiển thị trong AppCompat:

Thay vì mở rộng... Mở rộng
TextView AppCompatTextView
EditText AppCompatEditText
ToggleButton AppCompatToggleButton
Switch SwitchCompat
Button AppCompatButton
CheckedTextView AppCompatCheckedTextView
RadioButton AppCompatRadioButton
CheckBox AppCompatCheckBox
AutoCompleteTextView AppCompatAutoCompleteTextView
MultiAutoCompleteTextView AppCompatMultiAutoCompleteTextView

Thêm thành phần hiển thị tuỳ chỉnh cho các ứng dụng không có AppCompat

Nếu ứng dụng của bạn không sử dụng appcompat, hãy sử dụng trình trợ giúp tích hợp thành phần hiển thị trong mô-đun emoji2-views-helper với thiết kế có thể sử dụng trong thành phần hiển thị tuỳ chỉnh. Đây là những trình trợ giúp mà thư viện appcompat sử dụng để triển khai việc hỗ trợ biểu tượng cảm xúc.

Hãy hoàn tất các bước sau để hỗ trợ thành phần hiển thị tuỳ chỉnh cho các ứng dụng không sử dụng appcompat.

  1. Thêm thư viện emoji2-views-helper.

    implementation "androidx.emoji2:emoji2-views-helper:$emojiVersion"
    
  2. Làm theo hướng dẫn để thêm EmojiTextViewHelper hoặc EmojiEditTextHelper vào thành phần hiển thị tuỳ chỉnh của ứng dụng.

  3. Để kiểm tra hoạt động tích hợp của bạn, hãy chạy ứng dụng trên một thiết bị chạy Android 10 trở xuống và hiển thị chuỗi thử nghiệm sau. Hãy đảm bảo rằng tất cả các ký tự hiển thị chính xác.

    • 13.1: 😶‍🌫️, 🧔🏻‍♀️, 🧑🏿‍❤️‍🧑🏾
    • 13.0: 🥲, 🥷🏿, 🐻‍❄️
    • 12.1: 🧑🏻‍🦰, 🧑🏿‍🦯, 👩🏻‍🤝‍👩🏼
    • 12.0: 🦩, 🦻🏿, 👩🏼‍🤝‍👩🏻

Các tính năng không bắt buộc để xử lý emoji2

Sau khi đưa thư viện emoji2 vào ứng dụng, bạn có thể chọn thêm các tính năng không bắt buộc như mô tả trong phần này.

Định cấu hình emoji2 để sử dụng phông chữ hoặc trình cung cấp phông chữ có thể tải xuống khác

Để định cấu hình emoji2 cho phép sử dụng phông chữ hoặc trình cung cấp phông chữ có thể tải xuống khác, hãy làm như sau:

  1. Tắt EmojiCompatInitializer bằng cách thêm đoạn mã sau vào tệp kê khai.

    <provider
        android:name="androidx.startup.InitializationProvider"
        android:authorities="${applicationId}.androidx-startup"
        android:exported="false"
        tools:node="merge">
    <meta-data android:name="androidx.emoji2.text.EmojiCompatInitializer"
               tools:node="remove" />
    </provider>
  2. Thực hiện một trong các hành động sau:

Sửa đổi hành vi của EmojiCompat

Bạn có thể sử dụng một phiên bản của EmojiCompat.Config để sửa đổi hành vi của EmojiCompat.

Tuỳ chọn cấu hình quan trọng nhất là setMetadataLoadStrategy(). Tuỳ chọn này kiểm soát thời điểm EmojiCompat tải phông chữ. Việc tải phông chữ sẽ bắt đầu ngay khi bạn gọi EmojiCompat.load() và hoạt động này sẽ kích hoạt mọi lượt tải xuống cần thiết. Hệ thống sẽ tạo một chuỗi để tải phông chữ xuống trừ phi ứng dụng của bạn cung cấp chuỗi đó.

LOAD_STRATEGY_MANUAL cho phép bạn kiểm soát thời điểm gọi EmojiCompat.load()LOAD_STRATEGY_DEFAULT giúp việc tải bắt đầu đồng bộ trong lệnh gọi EmojiCompat.init().

Hầu hết các ứng dụng đều sử dụng LOAD_STRATEGY_MANUAL để cho phép kiểm soát chuỗi và thời gian tải phông chữ. Cụ thể, ứng dụng của bạn phải trì hoãn cho đến khi màn hình đầu tiên hiển thị để tránh gây ra độ trễ khi khởi động. EmojiCompatInitializer làm theo phương pháp này và trì hoãn việc tải phông chữ biểu tượng cảm xúc cho đến khi màn hình đầu tiên tiếp tục.

Bạn có thể sử dụng các phương thức sau trong lớp cơ sở để đặt các chương trình thành phần khác của cấu hình:

  • setReplaceAll(): Xác định xem EmojiCompat có nên thay thế tất cả các biểu tượng cảm xúc mà công cụ này tìm thấy bằng các phiên bản của EmojiSpan hay không. Theo mặc định, khi EmojiCompat suy luận rằng hệ thống có thể hiển thị biểu tượng cảm xúc, thì công cụ này sẽ không thay thế biểu tượng cảm xúc đó. Khi bạn đặt thành true, EmojiCompat sẽ thay thế tất cả biểu tượng cảm xúc bằng các đối tượng EmojiSpan.
  • setEmojiSpanIndicatorEnabled(): Cho biết liệu EmojiCompat có thay thế biểu tượng cảm xúc bằng đối tượng EmojiSpan hay không. Khi bạn đặt thành true, EmojiCompat sẽ vẽ một nền cho EmojiSpan. Phương thức này chủ yếu dùng để gỡ lỗi.
  • setEmojiSpanIndicatorColor: Đặt màu để chỉ báo EmojiSpan. Giá trị mặc định là GREEN.
  • registerInitCallback(): Thông báo cho ứng dụng về trạng thái của quá trình khởi động EmojiCompat.

Thêm trình nghe quá trình khởi động

Các lớp EmojiCompatEmojiCompat.Config cung cấp cho registerInitCallback()unregisterInitCallback() các phương thức để đăng ký và hủy đăng ký lệnh gọi lại quá trình khởi động. Ứng dụng của bạn sử dụng các lệnh gọi lại này để chờ cho đến khi EmojiCompat được khởi động trước khi bạn xử lý biểu tượng cảm xúc trên chuỗi nền hoặc trong một thành phần hiển thị tuỳ chỉnh.

Để sử dụng các phương thức này, hãy tạo một phiên bản của lớp EmojiCompat.InitCallback. Hãy gọi các phương thức này và chuyển vào phiên bản của lớp EmojiCompat.InitCallback. Khi quá trình khởi động thành công, lớp EmojiCompat sẽ gọi phương thức onInitialized(). Nếu thư viện không khởi động được, lớp EmojiCompat sẽ gọi phương thức onFailed(). Để kiểm tra trạng thái khởi động vào bất cứ lúc nào, hãy gọi phương thức getLoadState(). Phương thức này trả về một trong các giá trị sau: LOAD_STATE_LOADING, LOAD_STATE_SUCCEEDED hoặc LOAD_STATE_FAILED.

Hỗ trợ phông chữ đi kèm với emoji2

Bạn có thể sử dụng cấu phần mềm emoji2-bundled để gói một phông chữ biểu tượng cảm xúc vào ứng dụng của mình. Tuy nhiên, vì phông chữ NotoColorEmoji hiện tại có hơn 10 MB, ứng dụng của bạn nên sử dụng phông chữ có thể tải xuống khi cần. Cấu phần mềm emoji2- bundled dành cho ứng dụng trên các thiết bị không hỗ trợ phông chữ có thể tải xuống.

Để sử dụng cấu phần mềm emoji2-bundled, hãy làm như sau:

  1. Thêm các cấu phần mềm emoji2-bundledemoji2.

    implementation "androidx.emoji2:emoji2:$emojiVersion"
    implementation "androidx.emoji2:emoji2-bundled:$emojiVersion"
    
  2. Định cấu hình emoji2 để sử dụng cấu hình đi kèm.

    Kotlin

    EmojiCompat.init(BundledEmojiCompatConfig(context))
    

    Java

    EmojiCompat.init(new BundledEmojiCompatConfig(context));
    
  3. Hãy kiểm tra hoạt động tích hợp bằng cách làm theo các bước ở trên để thêm emojicompat có hoặc không có appcompat, sau đó đảm bảo chuỗi thử nghiệm hiển thị chính xác.

    • 13.1: 😶‍🌫️, 🧔🏻‍♀️, 🧑🏿‍❤️‍🧑🏾
    • 13.0: 🥲, 🥷🏿, 🐻‍❄️
    • 12.1: 🧑🏻‍🦰, 🧑🏿‍🦯, 👩🏻‍🤝‍👩🏼
    • 12.0: 🦩, 🦻🏿, 👩🏼‍🤝‍👩🏻

Tác động của cấu hình EmojiCompat tự động

Hệ thống áp dụng cấu hình mặc định bằng cách sử dụng thư viện khởi động, EmojiCompatInitializerDefaultEmojiCompatConfig.

Ngay sau khi hoạt động đầu tiên tiếp tục trong ứng dụng của bạn, trình khởi động sẽ lên lịch tải phông chữ biểu tượng cảm xúc. Độ trễ ngắn này cho phép ứng dụng của bạn hiển thị nội dung ban đầu mà không có bất kỳ độ trễ tiềm ẩn nào do việc tải phông chữ trong chuỗi nền.

DefaultEmojiCompatConfig tìm kiếm trình cung cấp phông chữ có thể tải xuống do hệ thống cài đặt để triển khai giao diện EmojiCompat, chẳng hạn như dịch vụ Google Play. Trên các thiết bị do dịch vụ Google Play cung cấp, tính năng này sẽ tải phông chữ thông qua việc sử dụng dịch vụ Google Play.

Trình khởi động tạo một chuỗi nền để tải phông chữ biểu tượng cảm xúc và quá trình tải phông chữ xuống có thể mất tối đa 10 giây trước khi hết thời gian chờ. Sau khi tải phông chữ xuống, bạn sẽ mất khoảng 150 mili giây để khởi động một chuỗi trong nền EmojiCompat.

Hoãn việc khởi động EmojiCompat, ngay cả khi bạn tắt EmojiCompatInitializer. Nếu bạn định cấu hình EmojiCompat theo cách thủ công, hãy gọi EmojiCompat.load() sau màn hình đầu tiên của ứng dụng xuất hiện để tránh hiển thị nội dung trong nền khi tải màn hình lần đầu.

Sau khi tải, EmojiCompat sử dụng khoảng 300KB RAM để lưu giữ siêu dữ liệu biểu tượng cảm xúc.