1. 程式人生 > 其它 >【原創】Jetpack Compose學習筆記(二)

【原創】Jetpack Compose學習筆記(二)

Jetpack Compose學習筆記(二)

今天不幹飯,幹下Compose裡面Text控制元件,類似TextView,不過在Compose裡Text是一個函式,繪製文字。

基本屬性

text: String // 設定文字
modifier: Modifier // 這個很複雜後面單說
color: Color = Color.Unspecified // 字型顏色
fontSize: TextUnit // 字號
fontStyle: FontStyle // 斜體
fontWeight: FontWeight? // 粗細
fontFamily: FontFamily // 字型
letterSpacing: TextUnit // 字間距 sp
textDecoration: TextDecoration // 刪除線、下劃線
textAlign: TextAlign // 對齊方式
lineHeight: TextUnit // 行高 sp
overflow: TextOverflow // 文字溢位,預設擷取
softWrap: Boolean // 預設true,如果false,overflow為預設時候溢位文字不會擷取,而且文字不換行
maxLines: Int // 最大行數
style: TextStyle // 上面的屬性最後都會覆蓋該物件的屬性,所以也可以完全通過該屬性來自定義Text

下面我們通過TextView常用的一些操作來介紹Text函式,例如文字的顏色,大小,加粗,斜體,刪除線,字型等,這些Text函式都支援。

簡單文字

一個簡單使用Text函式

Text(text = "簡單示例")

多樣式文字

Text函式有一個過載函式,text屬性的型別是AnnotatedString。這是一個多樣式多文字型別的資料物件。簡單說,我們一個文字可以不同部分展示不同樣式。如下示例

val multiStyleText = buildAnnotatedString {
    append("紅色 加粗 斜體 正常")
    addStyle(style = SpanStyle(color = Color.Red), start = 0, end = 2)
    addStyle(style = SpanStyle(fontWeight = FontWeight.Bold), start = 3, end = 5)
    addStyle(style = SpanStyle(fontStyle = FontStyle.Italic), start = 6, end = 8)
}
Text(text = multiStyleText)

文字顏色

文字顏色可以通過color屬性配置,在新建工程時候有個theme包,我們一般顏色資源都是放在該包Color檔案中,我們就引用這裡的顏色資源即可。

Text(
    text = "Hello $name!"
    color = Purple200
)

當然除了使用在Color檔案中定義的顏色外,還可以直接呼叫Color()函式來設定顏色,這種就類似xml配置中我們直接使用#FFFFFF來設定顏色。我們已可以引用系統的顏色,例如Color.RED

字號

字型大小可以通過fontSize屬性配置。這裡fontSize為型別為TextUnit,而Compose框架中擴充套件了Int函式dp、sp,所以我們直接呼叫即可。

Text(
    text = "Hello $name!",
    fontSize = 11.sp
)

這裡需要特別說明下,在TextUnit中有一個新的單位em,轉換公式1em = 16px

粗體

粗體可通過fontWeight屬性配置,該屬性型別為FontWeight,該類支援多種字寬度100-900,我們給字型加粗使用600700800900即可。

Text(
    text = "Hello $name!",
    fontWeight = FontWeight.BOLD
)

斜體

斜體可通過fontStyle來配置,該屬性型別為FontStyle,而該類為列舉型別,支援正常和斜體。

Text(
    text = "Hello $name!",
    fontStyle = FontStyle.Italic
)

字間距

字間距通過letterSpacing屬性配置,這裡需要注意的是這裡必須使用sp的擴充套件,不能使用dp

Text(
    text = "5sp的字元間距",
    letterSpacing = 5.sp
)

刪除線、下劃線

刪除線、下劃線通過textDecoration屬性來配置,該屬性型別為TextDecoration,內部支援LineThroughUnderline設定。

Text(
    text = "刪除線", 
    textDecoration = TextDecoration.LineThrough
)
Text(
    text = "下劃線", 
    textDecoration = TextDecoration.Underline
)

字型

字型設定和xml配置一樣都是需要配置fontFamily屬性。JetpackCompose中也內建了Android系統字型,但是我想一般我們不會使用,畢竟中國都是漢字。下面示例載入本地字型

Text(
    text = "Baiyu is NB",
    fontFamily = FontFamily(Font(R.font.abeezee))
)

行高

行高通過lineHeight屬性配置,這裡單位同字間距一樣也是sp,該屬性必須多行文字才會有效果。

Text(
    text = "行高文字", 
    lineHeight = 30.sp,
    modifier = Modifier.width(40.dp) // 這裡文字太短所以設定寬度為40以達到換行目的,關於Modifier後面單獨講解
)

對齊方式

文字對齊可使用textAlign屬性實現,當然你的文字內容要小於Text的寬度,不然沒有效果哦

// 右對齊效果
Text(
    text = "右對齊文字", 
    textAlign = TextAlign.End, 
    modifier = Modifier.width(200.dp)
)

文字溢位

TextView我們可以設定android:ellipsize="end"android:lines="1"來實現溢位後省略號表示,在Compose中我們可以通過maxLinesoverflow屬性來實現。預設是擷取效果。

Text(
    text = "溢位文字", 
    maxLines = 1, 
    overflow = TextOverflow.Ellipsis, 
    modifier = Modifier.width(50.dp)
)

文字縮排

文字縮排一般用於段落,該屬性Text函式沒有配置,需要通過textStyle屬性來實現

Text(
    text = "這是一個段落文字展示了首行縮排效果",
    modifier = Modifier.width(100.dp),
    style = TextStyle(textIndent = TextIndent(24.sp))
)

花樣文字

額,我覺得這樣稱呼這個屬性inlineContent的功能比較貼切,哈哈。該屬性型別為Map<String, InlineTextContent>,使用inlineContext需要配合上面多樣式文字結合使用。下面展示一個圖文內容

val inlineContentText = buildAnnotatedString {
    append("inlineContext展示圖文")
   appendInlineContent("image")
   appendInlineContent("text")
}
val inlineContent = mapOf(
    "image" to InlineTextContent (
        placeholder = Placeholder(
            width = 2.em,
            height = 2.em,
            placeholderVerticalAlign = PlaceholderVerticalAlign.AboveBaseline
        ),
        children = {
           Image(
	       // 這裡資源是DrawableRes
               bitmap = ImageBitmap.imageResource(id = R.drawable.acto),
               contentDescription = null
           )
        }
    ),
    "text" to InlineTextContent (
        placeholder = Placeholder(
            width = 2.em,
            height = 2.em,
            placeholderVerticalAlign = PlaceholderVerticalAlign.AboveBaseline
        ),
        children = {
            Text(text = "InlineText")
        }
    )
)
Text(
    text = inlineContentText, 
    inlineContent = inlineContent
)

話外
學習ComposeUI,看到一個部落格Jetpack Compose - Text文中提到如何單獨給上文中的紅色字型設定點選事件的API,我想有這個屬性就不在是難事了。另外官方也給出了ClickableText函式可以更簡單的實現

補充:
這裡補充一個官方看到的ClickableText函式,還是蠻實用的。例如文字中含有電話,或者URL連線,使用者點選後可以接收事件,然後呼叫打電話或者開啟網址。


@Composable
fun DialText(context:Context) {

    val annotatedText = buildAnnotatedString {
        append("撥打電話")
        pushStringAnnotation(
            tag = "tel",
            annotation = "15888888888"
        )
        withStyle(
            style = SpanStyle(
                color = Color.Blue,
                fontWeight = FontWeight.Bold
            )
        ) {
            append("15888888888")
        }
        pop()
    }

    ClickableText(
        text = annotatedText,
        onClick = { offset ->
            annotatedText.getStringAnnotations(tag = "tel", start = offset,
                end = offset)
                .firstOrNull()?.let { annotation ->
                    context.startActivity(Intent().apply {
                        action = Intent.ACTION_DIAL
                        data = Uri.parse("tel:${annotation.item}")
                    })
                }
        }
    )
}

跑馬燈

這個在Compose UI中還沒有發現,Google也沒有大神來實現這個效果,以後看到在補上吧。

字元長度限制

目前還沒有找到設定方法,不過感覺實際不需要了,因為你可以設定文字的寬度,如果超過寬度就按著溢位擷取掉就好了。

補充:文字選擇

這個是在官網看到的,主要就是使用者是否可以選擇文字做複製貼上操作,預設Text函式設定的文字使用者無法通過長按進行選擇的,如果要啟動,需要外層增加SelectionContainer,詳細可參看使用者互動

SelectionContainer {
    Column {
        Text("可選擇文字")
        DisableSelection {
            Text("不可選擇")
        }
    }
}




以上屬性都可以通過style直接自定義實現。通過原始碼我們可以看到最終Text函式會呼叫BasicText函式並將Text函式中設定的一些屬性引數都通過呼叫textStyle.merge覆蓋TextStyle預設的屬性了。




感謝:
Vinay Gaba

推薦:
Google Fonts