Upgrade to Pro — share decks privately, control downloads, hide ads and more …

No more □ (tofu): Taming Emoji on Android

No more □ (tofu): Taming Emoji on Android

Google announced EmojiCompat at I/O as a solution for undisplayable Emoji (tofu). But does it solve all issues developers have with Emoji? In our talk you’ll learn from our experience with Emoji in a social network app and if EmojiCompat is the best solution for you.

Miguel Beltran

July 26, 2017
Tweet

More Decks by Miguel Beltran

Other Decks in Programming

Transcript

  1. How Emoji works val emoji = "\uD83D\uDE02" val emoji2 =

    "\uD83D\uDC69\uD83C\uDFFE\u200D\uD83D\uDCBB" U+1F469 U+1F3FE U+200D U+1F4BB
  2. How long is an Emoji? Problem: Users must write at

    least two characters. val it = BreakIterator.getCharacterInstance()
 it.setText(emoji2)
 var count = 0
 while (it.next() != BreakIterator.DONE) {
 count++
 } emoji2.length Character.codePointCount(emoji2, 0, emoji2.length) = 7 = 4 = 3 on API 23 = 1 on API 25 val emoji2 = "\uD83D\uDC69\uD83C\uDFFE\u200D\uD83D\uDCBB"
  3. Problems so far: • Missing Emoji (tofu) • Different Emoji

    per platform • Length of strings with Emoji • Shortname <—> Unicode
  4. EmojiOne custom font val typeface = Typeface.createFromAsset(assets, "fonts/emojione.ttf")
 textView4.typeface =

    typeface 
 textView4.text = "Joy: $emoji\nDeveloper: $emoji2” Download: https://github.com/emojione/emojione/tree/master/extras/fonts Place in assets/fonts
  5. Hold on… API < 23 Not supported! Link: https://github.com/emojione/emojione/issues/252 Problem:

    Fonts with color bitmap, FreeType >2.5 Fatal Exception: java.lang.RuntimeException: native typeface cannot be made
 at android.graphics.Typeface.<init>(Typeface.java:321)
 at android.graphics.Typeface.createFromAsset(Typeface.java:295)
  6. EmojiCompat in Action Disclaimer: 26.0.0-Beta2 is broken! Slides use Beta1

    compile "com.android.support:support-emoji:26.0.0-beta1"
 compile "com.android.support:support-emoji-bundled:26.0.0-beta1" Adds: 7.4 MB
  7. Init EmojiCompat class MyApplication : Application() {
 override fun onCreate()

    {
 super.onCreate()
 val config = BundledEmojiCompatConfig(this)
 EmojiCompat.init(config)
 }
 } Takes 150 ms to init (but happens asynchronously)
  8. Using EmojiCompat val string = "Joy: $emoji\nDeveloper: $emoji2” val processed

    = EmojiCompat.get().process(string)
 textView3.text = processed
  9. Replace all or not? class MyApplication : Application() {
 override

    fun onCreate() {
 super.onCreate()
 val config = BundledEmojiCompatConfig(this)
 config.setReplaceAll(true)
 EmojiCompat.init(config)
 }
 }
  10. Wait for it EmojiCompat.get().registerInitCallback ( object : EmojiCompat.InitCallback() {
 override

    fun onInitialized() {
 val processed = EmojiCompat.get().process(string)
 textView3.text = processed
 }
 
 override fun onFailed(throwable: Throwable?) {
 
 }
 })