ความเข้ากันได้ของอีโมจิ

ไลบรารีการสนับสนุนของ EmojiCompat มีเป้าหมายเพื่อ ทำให้อุปกรณ์ Android ทันสมัยอยู่เสมอด้วยอีโมจิล่าสุด วิธีนี้จะช่วยให้แอปของคุณ ไม่แสดงอักขระอีโมจิในรูปแบบ ☐ ซึ่ง ระบุว่าอุปกรณ์ของคุณไม่มีแบบอักษรที่จะแสดงข้อความ โดย โดยใช้ไลบรารีการสนับสนุน EmojiCompat ผู้ใช้แอปไม่จำเป็นต้องรอการอัปเดตระบบปฏิบัติการ Android เพื่อรับเวอร์ชันล่าสุด อีโมจิ

วันที่ อุปกรณ์ที่แสดงอีโมจิ
รูปที่ 1 การเปรียบเทียบอีโมจิ

โปรดดูแหล่งข้อมูลที่เกี่ยวข้องต่อไปนี้

  • แอปตัวอย่างความเข้ากันได้กับอีโมจิ Java | Kotlin

EmojiCompat ทำงานอย่างไร

ไลบรารีการสนับสนุนของ EmojiCompat มี ชั้นเรียนเพื่อใช้การรองรับอีโมจิที่เข้ากันได้แบบย้อนหลังในอุปกรณ์ที่ใช้ Android 4.4 (API ระดับ 19) ขึ้นไป คุณสามารถกำหนดค่า EmojiCompat ที่รวมมาด้วยหรือ แบบอักษรที่ดาวน์โหลดได้ สําหรับข้อมูลเพิ่มเติมเกี่ยวกับการกําหนดค่า โปรดดู ส่วนต่อไปนี้

EmojiCompat ระบุอีโมจิสำหรับ CharSequence แทนที่ด้วย EmojiSpans หากจำเป็น และ จะแสดงรูปอักขระอีโมจิ รูปที่ 2 แสดงกระบวนการ

วันที่ กระบวนการ EmojiCompat
รูปที่ 2 กระบวนการ EmojiCompat

การกำหนดค่าแบบอักษรที่ดาวน์โหลดได้

การกำหนดค่าแบบอักษรที่ดาวน์โหลดได้จะใช้การสนับสนุนแบบอักษรที่ดาวน์โหลดได้ ไลบรารีสำหรับดาวน์โหลดแบบอักษรอีโมจิ และยังอัปเดตข้อมูล ข้อมูลเมตาของอีโมจิที่ EmojiCompat ไลบรารีการสนับสนุนจะต้อง อัปเดต Unicode เวอร์ชันล่าสุดอยู่เสมอ

การเพิ่มทรัพยากร Dependency ของไลบรารีการสนับสนุน

หากต้องการใช้ไลบรารีการสนับสนุน EmojiCompat คุณต้องแก้ไขทรัพยากร Dependency ของคลาสพาธของโปรเจ็กต์แอปภายใน สภาพแวดล้อมในการพัฒนาซอฟต์แวร์

วิธีเพิ่มไลบรารีการสนับสนุนลงในโปรเจ็กต์แอปพลิเคชัน

  1. เปิดไฟล์ build.gradle ของแอปพลิเคชัน
  2. เพิ่มไลบรารีการสนับสนุนลงในส่วน dependencies

ดึงดูด

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

Kotlin

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

กำลังเริ่มต้นแบบอักษรที่สามารถดาวน์โหลดได้ การกำหนดค่า

คุณต้องเริ่มต้น EmojiCompat เพื่อ โหลดข้อมูลเมตาและลักษณะแบบอักษร การเริ่มต้นอาจใช้เวลาสักครู่ กระบวนการเริ่มต้นจะทำงานบนเทรดเบื้องหลัง

ในการเริ่มต้น EmojiCompat ด้วย การกำหนดค่าแบบอักษรที่สามารถดาวน์โหลดได้ ให้ทำตามขั้นตอนต่อไปนี้

  1. สร้างอินสแตนซ์ของ FontRequest และระบุหน่วยงานของผู้ให้บริการแบบอักษร แพ็กเกจผู้ให้บริการแบบอักษร การค้นหาแบบอักษร และรายการชุดแฮชสำหรับใบรับรอง สำหรับข้อมูลเพิ่มเติม ข้อมูลเกี่ยวกับ FontRequest โปรดดู ไปยัง การใช้แบบอักษรที่ดาวน์โหลดได้แบบเป็นโปรแกรม ในส่วนแบบอักษรที่ดาวน์โหลดได้ เอกสารประกอบ
  2. สร้างอินสแตนซ์ของ FontRequestEmojiCompatConfig และระบุอินสแตนซ์ของ Context และ FontRequest
  3. เริ่มต้น EmojiCompat โดยเรียกใช้ วันที่ init() และส่งอินสแตนซ์ของ 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. ใช้วิดเจ็ต 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 ด้วยแบบอักษรที่ดาวน์โหลดได้ การกำหนดค่า ให้ไปที่แอปตัวอย่างความเข้ากันได้กับอีโมจิ Java | Kotlin

คอมโพเนนต์ไลบรารี

วันที่ องค์ประกอบของไลบรารีในกระบวนการ EmojiCompat
รูปที่ 3 องค์ประกอบของไลบรารีในขั้นตอน EmojiCompat
วิดเจ็ต: EmojiEditText, EmojiTextView, EmojiButton
การติดตั้งใช้งานวิดเจ็ตเริ่มต้นที่จะใช้ EmojiCompatด้วย TextView, EditText และ Button
EmojiCompat
พื้นที่สาธารณะหลักสำหรับไลบรารีการสนับสนุน โดยจะดำเนินการทั้งหมด การโทรภายนอกและการประสานงานกับส่วนอื่นๆ ของระบบ
EmojiCompat.Config
กำหนดค่าอินสแตนซ์เดี่ยวที่จะสร้างอินสแตนซ์
EmojiSpan
คลาสย่อย ReplacementSpan ที่แทนที่ (ลำดับ) แล้วแสดงผลรูปอักขระ
แบบอักษร EmojiCompat
EmojiCompat ใช้แบบอักษรในการแสดงผล อีโมจิ แบบอักษรนี้เป็นเวอร์ชันที่แก้ไขแล้วของ แบบอักษรอีโมจิของ Android แบบอักษรจะถูกแก้ไขดังนี้
  • เพื่อให้สามารถแสดงอีโมจิเพื่อความเข้ากันได้แบบย้อนหลัง อีโมจิทั้งหมด แสดงด้วยจุดรหัส Unicode จุดเดียวใน Supplemental Private Use Area-A ของ Unicode ขึ้นต้นด้วย U+F0001
  • ข้อมูลเมตาอีโมจิเพิ่มเติมจะแทรกลงในรูปแบบไบนารีในแบบอักษรและ ถูกแยกวิเคราะห์ขณะรันไทม์โดย EmojiCompat ข้อมูลฝังอยู่ ในตาราง meta ของแบบอักษรที่มีแท็กส่วนตัว Emji

ตัวเลือกการกำหนดค่า

คุณใช้อินสแตนซ์ EmojiCompat เพื่อ แก้ไขลักษณะการทำงานของ EmojiCompat คุณสามารถใช้ เมธอดต่อไปนี้จากคลาสพื้นฐานมากำหนดค่า

  • setReplaceAll(): กำหนดว่า EmojiCompat ควร แทนที่อีโมจิทั้งหมดที่พบ EmojiSpans โดยค่าเริ่มต้น EmojiCompat พยายามอย่างเต็มที่เพื่อ เข้าใจว่าระบบจะแสดงผลอีโมจิได้หรือไม่และไม่แทนที่อีโมจิเหล่านั้น อีโมจิ เมื่อตั้งค่าเป็น true EmojiCompat จะแทนที่อีโมจิทั้งหมดที่พบ ด้วย EmojiSpans
  • setEmojiSpanIndicatorEnabled(): ระบุว่า EmojiCompat ได้แทนที่อีโมจิด้วยอีโมจิแล้ว CANNOT TRANSLATE EmojiSpan เมื่อตั้งค่าเป็น true EmojiCompat วาดพื้นหลังสำหรับ EmojiSpan วิธีนี้ใช้กันเป็นหลัก เพื่อจุดประสงค์ในการแก้ไขข้อบกพร่อง
  • setEmojiSpanIndicatorColor(): ตั้งค่าสีเพื่อระบุ EmojiSpan ค่าเริ่มต้นคือ GREEN
  • registerInitCallback: แจ้งแอปเกี่ยวกับสถานะ การเริ่มต้น 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() {...})

การเพิ่ม Listener การเริ่มต้น

EmojiCompat และ EmojiCompat ชั้นเรียน ระบุ registerInitCallback() และ unregisterInitCallback() เมธอดในการลงทะเบียน Callback ของการเริ่มต้น หากต้องการใช้วิธีการเหล่านี้ ให้สร้าง ตัวอย่างของ 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. เพิ่มไลบรารีการสนับสนุนลงในส่วนทรัพยากร Dependency

    ดึงดูด

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

    Kotlin

          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 เพื่อโหลดข้อมูลเมตา และแบบอักษร

หมายเหตุ: ขนาดของแบบอักษรมีหน่วยเป็น เมกะไบต์

การเพิ่มทรัพยากร Dependency ของไลบรารีการสนับสนุน

วิธีใช้ไลบรารีการสนับสนุน EmojiCompat เมื่อใช้การกำหนดค่าแบบอักษรเป็นกลุ่ม คุณจะต้องแก้ไขโปรเจ็กต์แอป ทรัพยากร Dependency ของคลาสพาธภายในสภาพแวดล้อมการพัฒนาซอฟต์แวร์

วิธีเพิ่มไลบรารีการสนับสนุนลงในโปรเจ็กต์แอปพลิเคชัน

  1. เปิดไฟล์ build.gradle ของแอปพลิเคชัน
  2. เพิ่มไลบรารีการสนับสนุนลงในส่วน dependencies

ดึงดูด

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

Kotlin

dependencies {
    ...
    implementation("androidx.emoji: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 เพื่อแสดงรูปภาพที่ถูกต้อง ดังนั้นจึงต้องแปลง CharSequence ที่ระบุเป็น Spanned อินสแตนซ์ที่มี EmojiSpans คลาส EmojiCompat มีวิธีให้ แปลง CharSequences เป็น Spanned อินสแตนซ์ที่มี EmojiSpans หากใช้วิธีนี้ คุณสามารถประมวลผลและแคชอินสแตนซ์ที่ประมวลผลแล้วแทนสตริงดิบ ซึ่งช่วยปรับปรุงประสิทธิภาพของแอปพลิเคชัน

Kotlin

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

Java

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 มีวิดเจ็ตต่อไปนี้ ชั้นเรียนตัวช่วยที่คุณสามารถปรับแต่งวิดเจ็ตที่กำหนดเองด้วยการรองรับอีโมจิ ขั้นต่ำที่สุด

ตัวอย่าง 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() {
       ...
   }
}

คำถามที่พบบ่อย

  • ฉันจะเริ่มดาวน์โหลดแบบอักษรได้อย่างไร
  • แบบอักษรอีโมจิจะดาวน์โหลดตามคำขอครั้งแรก หากยังไม่มี ในอุปกรณ์ การตั้งเวลาดาวน์โหลดมีความโปร่งใสสำหรับแอป

  • การเริ่มต้นใช้เวลานานเท่าใด
  • หลังจากดาวน์โหลดแบบอักษรแล้ว จะใช้เวลาประมาณ 150 มิลลิวินาที เพื่อเริ่มต้น EmojiCompat

  • EmojiCompat รองรับไลบรารีได้เท่าไร
  • ในปัจจุบัน โครงสร้างข้อมูลในการค้นหาอีโมจินั้นโหลดอยู่ใน และใช้หน่วยความจำประมาณ 200 KB

  • ฉันจะใช้ 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