Jetpack Compose學習(2)——文本(Text)的使用


原文: Jetpack Compose學習(2)——文本(Text)的使用 | Stars-One的雜貨小窩

對於開發來說,文字最為基礎的組件,我們先從這兩個使用開始吧

本篇涉及到Kotlin和DSL特性的使用 若不了解的話可能會造成代碼閱讀困難,閱讀前確保你有上述基礎知識!!!

本系列以往文章請查看此分類鏈接jetpackcompose學習

基礎使用

@Preview(showBackground = true)
@Composable
fun textDemo() {
    ComposeDemoTheme {
        Column() {
			//基礎使用
            Text(text = "Hello world")
			//文字顏色
            Text(text = "Hello world", color = Color.Blue)
			//文字大小,sp關鍵字需要導入
			Text("Hello World", fontSize = 30.sp)
			//斜體
            Text("Hello World", fontStyle = FontStyle.Italic)
			//字體加粗
            Text("Hello World", fontWeight = FontWeight.Bold)
			//文字溢出(顯示省略號) repeat是重復的意思,文本內容是20個Hello world組成的字符串
            Text(text = "Hello world".repeat(20),overflow = TextOverflow.Ellipsis,maxLines = 2)

        }
    }
}

上述代碼的效果如下圖所示:

屬性 說明
text 文字
color 文字顏色
fontSize 字體大小
fontStyle 字體樣式, 可設置為斜體Italic
fontWeight 字體權重,可設置字體加粗
overflow 文字溢出效果,與maxLines結合使用可實現文字溢出顯示省略號效果
maxLines 最大行數 ,與overflow結合使用實現文字溢出顯示省略號效果

PS:這里提下,還有個重要的屬性modifier,這個准備在和布局使用一起講解,其作用很強大,可以設置控件寬高,背景,點擊效果,間距,滾動等效果,所有的組件都是存在有這個屬性,方便我們對組件進行調整

上述列出的屬性並不是全部,還有些不是太常用的就沒列出來了

補充: 一般我們是將常用的文本放在string.xml文件中,如果想要獲取這里的數值,compose也是提供有相應的方法,當然,除了文本之外,顏色等資源也有對應的方法

文本 -> stringResource(R.string.app_name)

顏色 -> colorResource(R.color.black)

尺寸 -> dimensionResource(R.dimen.padding_small)

圖片 -> painterResource(R.drawable.ic_logo)

單行文本多樣式

我們可能遇到這樣的情況,在一行文本中,其中某個地址可以點擊,或者某個詞語需要加粗,按照以往的操作,我們就得用多個TextView來實現或借助他人封裝的View來實現

但在Compose中,我們可以很方便的實現上述這樣的效果,text屬性除了接收字符串,還可以接收一個參數AnnotatedString,如下圖所示

提示:如果你快捷鍵是默認的話,在方法括號里按下ctrl+p可以看到參數提示 :good:

官方文檔的解釋:

The basic data structure of text with multiple styles.

翻譯過來就是說AnnotatedString是一種具有多種樣式的文本的基本數據結構

文檔上也是說明了,推薦可以使用構建器來生成對象,其實也就是一個方法buildAnnotatedString()

此方法里面我們可以使用Kotlin的語言特性DSL,更方便的創建一個AnnotatedString

來段簡單的代碼:

@Composable
fun ParagraphStyle() {
    Text(
        buildAnnotatedString {
            withStyle(style = ParagraphStyle(lineHeight = 30.sp)) {
				//設置Hello為藍色字體
                withStyle(style = SpanStyle(color = Color.Blue)) {
                    append("Hello")
                }       
            }
        }
    )
}

buildAnnotatedString方法里存在有withStyleappend方法,這兩個方法其實是AnnotatedString.Builder類里的方法

這里是采用了lambda寫法,buildAnnotatedString花括號里的對象即為AnnotatedString.Builder

withStyle可以接收ParagraphStyleSpanStyle

從字面上很容易理解,ParagraphStyle是段落樣式,SpanStyle是單行樣式

從構造方法來看,SpanStyle其實和Text的構造方法差不多,而且比Text類中的屬性都要豐富,如設置背景色,陰影等(而Text類中這些功能都被封裝在Modified類里)

前面列出的屬性表格它都有,但除了text屬性(當然,也能理解,這只是個Style,要text屬性做什么 ) 😅

ParagraphStyle稍微比較少一點,主要以排版的屬性為主,如對齊,行高,文本方向等,從下圖可以看得出來

append方法也容易理解,就是你想要把樣式賦值給哪個文本

然后我們就可以無限套娃,組合出我們想要的樣式 😀

Text(buildAnnotatedString {
	withStyle(ParagraphStyle()) {
		append("stars-one")
		withStyle(SpanStyle(color = Color.Black)) {
			append("的網站:")
		}
		withStyle(SpanStyle(color = Color.Red)) {
			append("stars-one.site")
		}
	}
	//新起段落
	withStyle(ParagraphStyle()) {
		append("newLine")
	}
})

效果如下圖:

PS:換行的話也可以輸入\n轉義符號

文本長按可選擇

默認情況下,Text是無法選擇的,compose中提供了一個容器SelectionContainer,方便我們實現Text的選擇效果

@Composable
fun SelectableText() {
    SelectionContainer {
        Text("This text is selectable")
    }
}

可點擊文本

設置文本的點擊事件我們可以使用Modifier提供的方法,點擊會有有水波漣漪的效果

Text(
	text = "Hello world",
	modifier = Modifier.clickable {	
		//點擊事件
	}
)

如果你有存在是判斷點擊的位置需求,官方則是推薦使用ClickableText這個控件,此控件只接受AnnotatedString文本,不接受常規字符串文本參數

ClickableText(
	text = AnnotatedString("Click Me"),
	onClick = { offset ->
		//offset是你點擊的時候是點了哪個文字
        //如你點了C,那么offset為0
	}
)

點擊文本跳轉鏈接

我們常見的文本,會在一段文字中間有個鏈接文本,點擊會跳轉瀏覽器從而打開到具體的頁面H5

輸入使用上面的效果也是能完成效果,但是每次還得算下下標的范圍才符合條件,這樣過於繁瑣

對此情況,官方也是有對應的解決方法,在AnnotatedString構造的時候,使用pushStringAnnotation()pop()方法即可達到效果,如下面給出的代碼

val annotatedText = buildAnnotatedString {
    append("Click ")

    //設置存放的數據和標簽
    pushStringAnnotation(tag = "URL",annotation = "https://developer.android.com")
    withStyle(style = SpanStyle(color = Color.Blue,fontWeight = FontWeight.Bold)) {
        append("here")
    }
    //代表結束
    pop()
}

在構造的時候,使用pushStringAnnotation()存下相應的數據,之后在點擊事件中通過AnnotatedStringgetStringAnnotations()方法重新獲取內容,之后進行相應的邏輯操作(如跳轉地址)

可以看到,pushStringAnnotation()方法中存在有兩個參數,tag代表標簽,數據可以隨意定義,但要與之后調用getStringAnnotations()傳參需要對應上,annotation則是存放的數據(只支持String)

記得在后面需要調用pop()方法,這兩個方法是需要結合使用的,上述代碼就是把here這個詞設置了一個額外數據內容

我們還是使用ClickableText這個類,在點擊事件中獲取參數即可

@Composable
fun AnnotatedClickableText() {
    val annotatedText = buildAnnotatedString {
        append("Click ")

        
        pushStringAnnotation(tag = "URL",annotation = "https://developer.android.com")
        withStyle(style = SpanStyle(color = Color.Blue,
                                    fontWeight = FontWeight.Bold)) {
            append("here")
        }
        pop()
    }

    ClickableText(
        text = annotatedText,
        onClick = { offset ->
            val annotationList = annotatedText.getStringAnnotations(tag = "URL", start = offset,nd = offset)
            //firstOrNull是找List中的第一個對象,找不到則則返回null
            annotationList.firstOrNull()?.let { annotation ->
                val url = annotation.item
                //后面即邏輯操作...
                
            }
        }
    )
}

需要注意的是,getStringAnnotations()傳了之前設置的tags參數的內容及開始和結束的下標,返回的是一個List對象

這里返回List也不難理解,getStringAnnotations()方法作用就是搜索文本的指定下標范圍內,存在有tags的內容數據,指定下標范圍內,若tags相同,應該也是會被收集到

但是我覺得應該不會用這種情況的發生,但是為了確保使用,tags參數的數值我們最好設置一個唯一的數值

參考


免責聲明!

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



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