【问题标题】:Android Emoji App Compat Text View not rendering some emojis such as ????Android Emoji Appcompat Textview 不呈现一些表情符号,例如????
【发布时间】:2021-03-30 00:29:13
【问题描述】:

我正在尝试使用Emoji App Compat Text View,但我不明白我在实施时做错了什么。

我正在尝试渲染这三个表情符号????????????,它在 Android Q 上运行良好,但在 Android Lollipop 上无法运行,请看截图:

Screenshot on Android Q Screenshot on Android Lollipop

据我了解,使用 Emoji App Compat Text View 的想法是让 emoji 集在 android API 21 及更高版本中正常工作,所以请看看我的实现,是否有任何遗漏、错误或可能Emoji App Compat Text View 不像我想的那样工作?

您可以获取complete code here at github 或阅读以下主要部分:

Application的onCreate,设置EmojiCompat,我没有使用捆绑版:

EmojiCompat.init(
    FontRequestEmojiCompatConfig(
        this,
        FontRequest(
            "com.google.android.gms.fonts",
            "com.google.android.gms",
            "Noto Color Emoji Compat",
            R.array.com_google_android_gms_fonts_certs
        )
    ).setReplaceAll(true)
    // I did remove the callback for brevity, but I got the `onInitialized` called.
)

Activity,只需设置布局,获取View并设置文本:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 
…
    <androidx.emoji.widget.EmojiAppCompatTextView
        android:id="@+id/text_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textSize="60sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
…
</androidx.constraintlayout.widget.ConstraintLayout>
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        findViewById<EmojiAppCompatTextView>(R.id.text_view).text = getString(R.string.three_emojis)
    }
}

字符串

<string name="three_emojis">????????????</string>

分级

plugins {
    id "com.android.application"
    id "kotlin-android"
}

android {
    compileSdkVersion 29
    buildToolsVersion "30.0.2"
…
    defaultConfig {
        minSdkVersion 21
        targetSdkVersion 29
…
    }
…
}

dependencies {
    implementation "androidx.emoji:emoji-appcompat:1.1.0"
    implementation "androidx.emoji:emoji:1.1.0"
    implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
    implementation "androidx.appcompat:appcompat:1.2.0"
    implementation "androidx.constraintlayout:constraintlayout:2.0.4"
    implementation "androidx.core:core-ktx:1.3.2"
    implementation "com.google.android.material:material:1.2.1"
}

【问题讨论】:

  • 这是非常奇怪的行为。我已经尝试过来自emojipedia.org/eye 的相同表情符号并且它有效。即使您的表情符号看起来也一样。还与r12a.github.io/app-conversion 进行了比较,两个“眼睛”表情符号具有相同的数据。 imgur.com/a/I9B7pSA
  • @HarisDautović 我无话可说,也不知道发生了什么,但我确实重现了您的示例,并且得到了相同的结果。我确实跑了kotlinc-jvm"????"=="????",左边是原始的,右边来自emojipedia,结果是res1: kotlin.Boolean = true
  • 这里是一些额外的调试数据:imgur.com/a/fbFqvsa 数据值只包含眼睛表情符号。案例 1:不起作用 -> 解码的表情符号有 2 个字符。案例 2:有效 -> 解码的表情符号有 3 个字符。第三个字符为空。
  • @HarisDautović 我想你一针见血,读到这个65039 字符,它是Variation selector-16,根据维基百科 VS15 和 VS16 被保留以请求一个字符应分别显示为文本或表情符号。 所以为了测试它,我确实运行了.text = String(charArrayOf('\uD83D', '\uDC41')),但我没有得到表情符号。运行.text = String(charArrayOf('\uD83D', '\uDC41', 65039.toChar())) 我得到了表情符号。并运行 VS15 .text = String(charArrayOf('\uD83D', '\uDC41', 65038.toChar())) 我没有得到预期的表情符号。

标签: android android-appcompat emoji


【解决方案1】:

结论:默认情况下,将使用文本样式,除非这些后跟 U+FE0F 变体选择器。

这可以使用以下方法进行验证:

案例 1:在所有 Android 版本上返回 false。

EmojiCompat.get().hasEmojiGlyph(String(charArrayOf('\uD83D', '\uDC41')))

案例 2:在 Android API 版本 >=18 上返回 true

EmojiCompat.get().hasEmojiGlyph(String(charArrayOf('\uD83D', '\uDC41', 65039.toChar())))

解决方案.setUseEmojiAsDefaultStyle(true)

class App : Application() {
    override fun onCreate() {
        super.onCreate()
        AppCompatDelegate.setCompatVectorFromResourcesEnabled(true)
        EmojiCompat.init(
            FontRequestEmojiCompatConfig(
                this,
                FontRequest(
                    "com.google.android.gms.fonts",
                    "com.google.android.gms",
                    "Noto Color Emoji Compat",
                    R.array.com_google_android_gms_fonts_certs
                )
            ).setReplaceAll(true)
                .setUseEmojiAsDefaultStyle(true)
                .registerInitCallback(object : EmojiCompat.InitCallback() {
                    override fun onInitialized() {
                        super.onInitialized()
                        Toast.makeText(this@App, "EmojiCompat was initialized", LENGTH_SHORT).show()
                    }

                    override fun onFailed(throwable: Throwable?) {
                        super.onFailed(throwable)
                        throw RuntimeException(throwable)
                    }
                })
        )
    }
}

在 Android API 19 上测试:

【讨论】:

  • 你摇滚,简单而有效的解决方案!
  • 谢谢!我很欣赏你提出问题的方式。演示 Github 项目非常有帮助。
  • setUseEmojiAsDefaultStyle 文档中说“确定 EmojiCompat 是否应该对具有默认文本样式的表情符号使用表情符号呈现样式。”这意味着偶数和一些特殊字符不会表示为文本,而是表示为表情符号,如果这是想要的行为,这很好,但如果不是,这个解决方案可能非常难看,因为你必须定义一个完整的异常表情符号列表
猜你喜欢
  • 2016-06-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-02
相关资源
最近更新 更多