Jetpack Soạn và tạo kiểu strings.xml

Nov 26 2022
Vấn đề Vì vậy, bạn có một mục nhập trong chuỗi.xml với nội dung HTML: Tất cả kiểu dáng đã biến mất! Chuyện gì đã xảy ra thế? Giải pháp Jetpack Compose chưa hỗ trợ văn bản theo kiểu.
Biểu tượng Soạn thảo Jetpack. Nó trông đẹp, nhưng không có văn bản theo kiểu. Tại sao vậy?

Vấn đề

Vì vậy, bạn có một mục nhập trong strings.xml với nội dung HTML:

<string name="neatly_styled">Nice <u>underlined</u> and <b>bold</b> text.</string>

@Preview
@Compose
fun PreviewStyledText() {
  Text(text = stringResource(R.string.neatly_styled))
}

Xem trước văn bản. Kiểu dáng bị thiếu!

Tất cả các kiểu dáng đã biến mất! Chuyện gì đã xảy ra thế?

Dung dịch

Jetpack Compose chưa hỗ trợ văn bản theo kiểu. Nhưng nó đơn giản để sửa chữa.

Sau vấn đề 139320238 , chúng tôi tạo trình tải tài nguyên chuỗi của riêng mình:

@Composable
fun annotatedStringResource(@StringRes id: Int): AnnotatedString {
    val resources = LocalContext.current.resources
    return remember(id) {
        val text = resources.getText(id)
        if (text is Spanned) {
            val spanStyles = mutableListOf<AnnotatedString.Range<SpanStyle>>()
            spanStyles.addAll(text.getSpans(0, text.length, UnderlineSpan::class.java).map {
                AnnotatedString.Range(
                    SpanStyle(textDecoration = TextDecoration.Underline),
                    text.getSpanStart(it),
                    text.getSpanEnd(it)
                )
            })
            spanStyles.addAll(text.getSpans(0, text.length, StyleSpan::class.java).map {
                AnnotatedString.Range(
                    SpanStyle(fontWeight = FontWeight.Bold),
                    text.getSpanStart(it),
                    text.getSpanEnd(it)
                )
            })
            AnnotatedString(text.toString(), spanStyles = spanStyles)
        } else {
            AnnotatedString(text.toString())
        }
    }
}

@Preview
@Composable
fun PreviewStyledTextFix() {
    Text(text = annotatedStringResource(R.string.styled_text))
}

Xem trước văn bản. Vẫn không có kiểu dáng vì nó không được hỗ trợ trong Bản xem trước

Ơ cái gì...Vẫn KHÔNG CÓ KIỂU DÁNG? Vấn đề là, chế độ Xem trước cũng không hỗ trợ văn bản theo kiểu.

Tuy nhiên, một thiết bị thực sự:

Xem trước văn bản trên thiết bị. Phong cách là có!

Và bởi vì người dùng của chúng tôi chỉ sử dụng các thiết bị thực, tất cả chúng tôi đều ổn.

Dưới mui xe

Thành phần Jetpack Compose Text hỗ trợ văn bản được tạo kiểu. Hỗ trợ được gọi là AnnotatedString. Vì vậy, nếu chúng tôi chỉ có thể cung cấp Văn bản với AnnotatedStrings, tất cả chúng tôi đều ổn.

Về phía Android, nó cung cấp hai cách để lấy chuỗi được bản địa hóa:

  • Chuỗi getString(id), trả về một Chuỗi. Điều đó không thể chứa bất kỳ kiểu dáng nào và các thẻ HTML chỉ bị loại bỏ và bỏ qua.
  • CharSequence getText(id), trả về một CharSequence. Điều đáng chú ý là trình tự này cũng chứa các khoảng kiểu được xác định trong HTML.