Jetpack เขียนและจัดสไตล์ strings.xml

Nov 26 2022
ปัญหา คุณมีรายการใน strings.xml ที่มีเนื้อหา HTML: สไตล์ทั้งหมดหายไป! เกิดอะไรขึ้น โซลูชัน Jetpack Compose ยังไม่รองรับข้อความที่มีสไตล์
โลโก้ Jetpack เขียน ดูดี แต่ไม่มีข้อความที่จัดรูปแบบ ทำไมถึงเป็นเช่นนั้น?

ปัญหา

ดังนั้นคุณจึงมีรายการใน strings.xml ที่มีเนื้อหา 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))
}

ดูตัวอย่างข้อความ ขาดสไตล์!

หมดทุกสไตล์! เกิดอะไรขึ้น

สารละลาย

Jetpack Compose ยังไม่รองรับข้อความที่มีสไตล์ แต่มันง่ายที่จะแก้ไข

ต่อจากปัญหา139320238เราสร้างตัวโหลดทรัพยากรสตริงของเราเอง:

@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))
}

ดูตัวอย่างข้อความ ยังไม่มีสไตล์เพราะไม่รองรับการแสดงตัวอย่าง

เอ๊ะ อะไรนะ… ยังไม่ได้สไตล์เหรอ? สิ่งนี้คือโหมดแสดงตัวอย่างไม่รองรับข้อความที่มีสไตล์เช่นกัน

แต่อุปกรณ์จริงทำ:

ดูตัวอย่างข้อความบนอุปกรณ์ สไตล์อยู่ที่นั่น!

และเนื่องจากผู้ใช้ของเราใช้อุปกรณ์จริงเท่านั้น เราจึงไม่เป็นไร

ภายใต้ประทุน

คอมโพเนนต์ Jetpack Compose Text รองรับข้อความที่มีสไตล์ การสนับสนุนนี้เรียกว่า AnnotatedString ดังนั้นหากเราสามารถใส่ข้อความด้วย AnnotatedStrings ได้ เราก็ไม่เป็นไร

จากฝั่ง Android จะมีสองวิธีในการรับสตริงที่แปลเป็นภาษาท้องถิ่น:

  • สตริง getString(id) ซึ่งส่งคืนสตริง ที่ไม่สามารถมีสไตล์ใด ๆ และแท็ก HTML จะถูกละทิ้งและละเว้น
  • CharSequence getText(id) ซึ่งส่งคืน CharSequence จับได้ว่าลำดับนี้มีช่วงสไตล์ที่กำหนดไว้ใน HTML