社交和消息应用中的文本

文本是社交应用的核心,用户在这里分享想法、表达情感和讲述故事。本文档探讨了如何有效地处理文本,重点关注 Emoji、样式和富媒体内容集成。

使用 Emoji

Emoji 已成为现代沟通不可或缺的一部分,尤其是在社交和消息应用中。它们超越了语言障碍,使用户能够快速有效地表达情感和想法。

Compose 中的 Emoji 支持

Jetpack Compose,Android 现代的声明式 UI 工具包,简化了 Emoji 处理

  • 输入TextField 组件原生支持 Emoji 输入。
  • 显示:Compose 的 Text 组件能够正确渲染 Emoji,确保其在提供 Emoji2 兼容可下载字体提供程序的设备和平台(例如由 Google Play 服务 提供支持的设备)上保持一致的外观。

显示 Emoji 涵盖了在 Jetpack Compose 中显示 Emoji,包括如何确保您的应用显示最新的 Emoji 字体,以及如果您的应用 在同一个 Activity 中同时使用 Views 和 Compose 时如何确保 Emoji 正确工作,以及当 Emoji 未按预期显示时如何进行故障排除。

Views 中的 Emoji 支持

如果您使用的是 Android Views,则 AppCompat 库 1.4 或更高版本为 TextView 的平台子类提供 Emoji 支持。

如果您正在 创建自定义视图,并且它是 TextView 的直接或间接子类,请扩展 AppCompat 实现(而不是平台实现)以获得内置的 Emoji 支持。支持现代 Emoji 展示了如何测试和排查 Emoji 集成,如何在没有 AppCompat 的情况下支持 Emoji,如何在自定义视图中支持 Emoji,以及如何支持备用字体或字体提供程序等等。

使用 Emoji 选择器

Jetpack Emoji 选择器 是一个 Android View,它提供了一个分类的 Emoji 列表、粘性变体以及对最近使用 Emoji 的支持——兼容多个 Android 版本和设备。这是一种提升应用 Emoji 集成体验的简单方法。

首先在 build.gradle 中导入库。

dependencies {
   implementation("androidx.emoji2:emojipicker:$version")
}

在 Compose 中使用 Emoji 选择器

您可以在 Compose 中使用 AndroidView 可组合项构建 Emoji 选择器。此代码片段包含一个侦听器,可让您知道何时选择了 Emoji。

AndroidView(
    modifier = Modifier.fillMaxSize(),
    factory = { context ->
        val emojiPickerView = EmojiPickerView(context)
        emojiPickerView.setOnEmojiPickedListener(this::updateTextField)
        emojiPickerView
    },
)

Compose 1.7 为 BasicTextField 添加了许多新功能,包括对 TextFieldState 的支持,它可以位于您的 ViewModel 中。

private val emojiTextFieldState = TextFieldState()

@Composable fun EmojiTextField() {
    BasicTextField(
        state = emojiTextFieldState,
    )
}

您可以使用 TextFieldState 在光标位置插入文本或替换选定的文本,就像您在 IME 中输入一样。

private fun insertStringAsIfTyping(textFieldState: TextFieldState, string: String) {
    textFieldState.edit {
        replace(selection.start, selection.end, string)
        // clear selection on replace if necessary
        if (hasSelection) selection = TextRange(selection.end)
    }
}

回调可以使用辅助函数更新 BasicTextField

private fun updateTextField(emojiViewItem: EmojiViewItem) {
    insertStringAsIfTyping(emojiTextFieldState, emojiViewItem.emoji)
}

在 Views 中使用 Emoji 选择器

Emoji 选择器也适用于 Views。

加载 EmojiPickerView。您可以根据每个 Emoji 单元格所需的尺寸选择设置 emojiGridColumns 和 emojiGridRows。

<androidx.emoji2.emojipicker.EmojiPickerView
        app:emojiGridColumns="9" />

在光标位置插入字符或替换选定的文本。

// Consider unregistering/reregistering anyTextWatcher that you might have as part of this
private fun insertStringAsIfTyping(editText: EditText, string: String) {
    val stringBuffer = StringBuffer(editText.text.toString())
    val index = editText.selectionStart
    if ( !editText.hasSelection() ) {
        stringBuffer.insert(index, string)
    } else {
        stringBuffer.replace(index, editText.selectionEnd, string)
    }
    editText.setText(stringBuffer.toString())
    editText.setSelection(index + string.length)
}

为选定的 Emoji 提供一个侦听器,并使用它将字符追加到 EditText 中。

// a listener example
emojiPickerView.setOnEmojiPickedListener {
   val editText = findViewById<EditText>(R.id.edit_text)
   insertStringAsIfTyping(editText, it.emoji)
}

设置文本样式

通过对文本应用视觉区分,例如字体样式、大小、粗细和颜色,您可以增强社交或消息应用的用户界面的可读性、层次结构和整体美观性。文本样式可帮助用户快速解析信息,区分不同类型的消息并识别重要元素。

在 Compose 中设置文本样式

Text 可组合项提供了丰富的样式选项,包括

  • 文本颜色:设置 Color 以使文本脱颖而出。
  • 字体大小:控制 FontSize 以获得合适的比例。
  • 字体样式:使用 FontStyle 使文本斜体。
  • 字体粗细:调整 FontWeight 以获得粗体、细体等文本变化。
  • 字体系列:使用 FontFamily 选择合适的字体。
Text(
    text = "Hello 👋",
    color = Color.Blue
    fontSize = 18.sp,
    fontWeight = FontWeight.Bold,
    fontFamily = FontFamily.SansSerif
)

您可以使用主题在整个应用程序中一致地设置这些样式选项。

MaterialTheme(
    // This theme would include Color.Blue (as appropriate for dark and light themes)
    colorScheme = colorScheme,
    content = content,
    typography = Typography(
        titleLarge = TextStyle(
            fontSize = 18.sp,
            fontFamily = titleFont,
            fontWeight = FontWeight.Bold
        ),
    ),
)

在文本中添加多个样式

您可以使用 AnnotatedString 在同一个 Text 可组合项中设置不同的样式。

AnnotatedString 具有一个 类型安全构建器buildAnnotatedString,使创建更容易。

@Composable
fun MultipleStylesInText() {
    Text(
        buildAnnotatedString {
            withStyle(style = SpanStyle(color = Color.Blue)) {
                append("M")
            }
            append("y ")

            withStyle(style = SpanStyle(fontWeight = FontWeight.Bold, color = Color.Red)) {
                append("S")
            }
            append("tyle")
        }
    )
}

请参阅 设置文本样式,以获取有关 Compose 中文本样式的更多信息,包括 添加阴影使用 Brush 进行高级样式设置 以及 不透明度

在 Views 中设置文本样式

在 Views 中,依靠样式和主题来实现一致的排版。请参阅 样式和主题,以获取有关如何为应用中的视图应用自定义主题的更多信息。如果您想在一个文本视图中设置不同的样式,请参阅 Spans,以获取有关如何以各种方式更改文本的更多信息,包括添加 颜色、使文本 可点击、缩放 文本大小 以及以 自定义方式 绘制文本。

支持图片键盘和其他富媒体内容

用户通常希望使用贴纸、动画和其他类型的富媒体内容进行交流。为了简化应用接收富媒体内容的操作,Android 12(API 级别 31)引入了一个统一的 API,允许您的应用接受来自任何来源的内容:剪贴板、键盘或拖放。为了与之前的 Android 版本(目前回溯到 API 级别 14)保持向后兼容性,我们建议您使用此 API 的 Android Jetpack(AndroidX)版本。

您可以将 OnReceiveContentListener 附加到 UI 组件,并在通过任何机制插入内容时获得回调。回调成为您的代码处理接收所有内容的唯一位置,从纯文本和格式化文本到标记、图像、视频、音频文件等。

请参阅 接收富媒体内容,以了解有关如何在您的应用中实现支持的更多信息。Jetpack Compose 现在具有 dragAndDropSourcedragAndDropTarget 修饰符,以简化在您的应用内和与其他应用之间实现拖放操作。