【原創】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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM