Jetpack?Compose基礎(chǔ)組件之文字組件
概述
文本是UI界面中最常見(jiàn)的元素之一,在Compose中,文字組件扮演著重要的角色,文字組件是遵循Material Design規(guī)范設(shè)計(jì)的上層組件,如果我們不想使用Material Design,我們也可以直接使用更底層的文本組件,如Text組件對(duì)應(yīng)的更底層的文本組件是BasicText,文本組件不得不提輸入框的使用,本文會(huì)主要介紹Text和輸入框,并且實(shí)現(xiàn)一個(gè)現(xiàn)在App中都在用的好看的輸入框
文字組件
1.Text 文本
因?yàn)镃omposable組件都是函數(shù),所有的配置都來(lái)自于參數(shù)的傳遞,所以我們通過(guò)參數(shù)列表就可以了解組件的所有功能,Text組件的參數(shù)列表如下:
@Composable
fun Text(
text: String, // 需要顯示的文本
modifier: Modifier = Modifier,// 修飾符
color: Color = Color.Unspecified, // 文字顏色
fontSize: TextUnit = TextUnit.Unspecified,// 文字大小
fontStyle: FontStyle? = null, // 繪制文本時(shí)使用的字體變換,如斜體
fontWeight: FontWeight? = null, // 文字的粗細(xì)
fontFamily: FontFamily? = null,// 文字的字體
letterSpacing: TextUnit = TextUnit.Unspecified, // 文本間距
textDecoration: TextDecoration? = null, // 文字裝飾,如下劃線,刪除線等
textAlign: TextAlign? = null, // 文本的對(duì)齊方式
lineHeight: TextUnit = TextUnit.Unspecified, // 文本行間距
overflow: TextOverflow = TextOverflow.Clip,// 文本溢出時(shí)的視覺(jué)效果,比如超出的文字用三個(gè)點(diǎn)表示
softWrap: Boolean = true,// 控制文本是否能夠換行,如果為false,則會(huì)定位
maxLines: Int = Int.MAX_VALUE,// 文本最多的展示行數(shù)
onTextLayout: (TextLayoutResult) -> Unit = {},// 在文本發(fā)生變化之后,會(huì)回調(diào)一個(gè)TextLayoutResult,包含此文本的各種信息
style: TextStyle = LocalTextStyle.current // 文本的風(fēng)格配置,如顏色,字體,行高等
)
Text組件的參數(shù)會(huì)按照其使用的頻度排序,比如text和modifier排在靠前的位置,并盡量添加默認(rèn)實(shí)現(xiàn)。
Text組件的基本功能是顯示一段文字,可以為text參數(shù)傳入要顯示的文字內(nèi)容,Compose也提供了stringResource方法,通過(guò)R 資源文件獲取字符串,方便做多語(yǔ)言適配
// 指定字符串
Text(text = "Hello World")
// 指定文字資源
Text(text = stringResource(id = R.string.app_name))
2.Text的style文字樣式
style參數(shù)接受一個(gè)TextStyle類型,TextStyle中包含了一系列設(shè)置文字樣式的字段,例如行高,間距,字體大小,字體粗細(xì)等,演示代碼如下所示:
@Composable
fun TextStyleDemo() {
Column {
Text(
text = "Zhongxj",
style = TextStyle(
fontSize = 25.sp,
fontWeight = FontWeight.Bold,
background = Color.Cyan,
lineHeight = 35.sp
)
)
Text(
text = stringResource(id = R.string.app_name), style = TextStyle(
color = Color.Cyan,
letterSpacing = 4.sp
)
)
Text(
text = "Hello world", style = TextStyle(
textDecoration = TextDecoration.LineThrough
)
)
Text(
text = "Walt-zhong",
style = MaterialTheme.typography.h6.copy(fontStyle = FontStyle.Italic)
)
}
}
運(yùn)行結(jié)果如下所示:

代碼中的TextDecoration可以為文字增加刪除線或下劃線,F(xiàn)ontStyle可以用來(lái)設(shè)置文字是否是斜體
3.maxLines參數(shù)
maxLines參數(shù)可以幫助我們將文本限制在指定行數(shù)之間,當(dāng)文本超過(guò)了參數(shù)設(shè)置的閾值時(shí),文本會(huì)被截?cái)?,而overflow可以處理文字過(guò)多的場(chǎng)景,文字過(guò)多的時(shí)候會(huì)以“...”結(jié)尾,這個(gè)參數(shù)可以用來(lái)實(shí)現(xiàn)一個(gè)閱讀文字時(shí)的展開(kāi)和收起功能,當(dāng)我們顯示很多條數(shù)據(jù)時(shí),每一條數(shù)據(jù)都有很多的文字,這時(shí)我們可以使用這個(gè)參數(shù),默認(rèn)只展示指定的行數(shù),提供一個(gè)展開(kāi)按鈕,當(dāng)用戶點(diǎn)擊展開(kāi)的時(shí)候,就顯示所有的文本。展示收起按鈕,點(diǎn)擊收起按鈕又可以顯示指定的行數(shù)。這個(gè)功能后面有時(shí)間我們會(huì)演示,這里我們先看下基本的演示代碼:
@Composable
fun MaxLinesDemo() {
Column {
Text(
text = "在Compose中,每一個(gè)組件都是帶有@Compose注解的函數(shù),被稱為Composable。" +
"Compose已經(jīng)預(yù)置了很多的Compose UI組件,這些組件都是基于Material Design規(guī)范設(shè)計(jì)的",
style = MaterialTheme.typography.body1,
color = Color.Red
)
Spacer(modifier = Modifier.size(10.dp))
Text(
text = "在Compose中,每一個(gè)組件都是帶有@Compose注解的函數(shù),被稱為Composable。" +
"Compose已經(jīng)預(yù)置了很多的Compose UI組件,這些組件都是基于Material Design規(guī)范設(shè)計(jì)的",
style = MaterialTheme.typography.body1,
maxLines = 1,
color = Color.Green
)
Spacer(modifier = Modifier.size(10.dp))
Text(
text = "在Compose中,每一個(gè)組件都是帶有@Compose注解的函數(shù),被稱為Composable。" +
"Compose已經(jīng)預(yù)置了很多的Compose UI組件,這些組件都是基于Material Design規(guī)范設(shè)計(jì)的",
style = MaterialTheme.typography.body1,
maxLines = 1,
color = Color.Blue,
overflow = TextOverflow.Ellipsis
)
}
}
運(yùn)行結(jié)果:

4.fontFamily字體風(fēng)格
fontFamily參數(shù)用來(lái)設(shè)置文字字體,演示代碼如下:
@Composable
fun FontFamilyDemo() {
Column {
Text(text = "Hello World", color = Color.Red)
Spacer(modifier = Modifier.size(10.dp))
Text(text = "Hello World", color = Color.Green, fontFamily = FontFamily.Monospace)
Spacer(modifier = Modifier.size(10.dp))
Text(text = "Hello World", color = Color.Blue, fontFamily = FontFamily.Cursive)
}
}
運(yùn)行結(jié)果

當(dāng)使用系統(tǒng)中沒(méi)有的字體時(shí),可以右擊res文件夾,選擇New->Android Resource Directory->Resource type ->font創(chuàng)建font文件夾,然后將自己的字體拖入文件夾即可
5.AnnotatedString多樣式文字
AnnotatedString 其實(shí)很像傳統(tǒng)View中的SpannableString,在很多的場(chǎng)景中,我們需要在一段文字中突出某些內(nèi)容,比如超鏈接和電話號(hào)碼,我們點(diǎn)擊超鏈接和電話號(hào)碼能跳到鏈接指向的頁(yè)面和撥打電話。在Compose中就需要使用AnnotatedString多樣式文字,AnnotatedString是一個(gè)數(shù)據(jù)類,除了文本值,它還包含了一個(gè)SpanStyle和ParagraphStyle的Range列表,SpanStyle用于描述在文本中字串的文字樣式,ParagraphStyle則用于描述文本字串中的段落樣式,Range確定字串的范圍,示例代碼如下:
@Composable
fun AnnotatedStringDemo() {
Text(text = buildAnnotatedString {
withStyle(style = SpanStyle(fontSize = 24.sp)) {
append("I am Iron man,我是鋼鐵俠")
}
withStyle(style = SpanStyle(fontWeight = FontWeight.W900, fontSize = 24.sp)) {
append("zhongxj")
}
append("\n")
withStyle(style = ParagraphStyle(lineHeight = 25.sp)) {
append(
"在Compose中,每一個(gè)組件都是帶有@Compose注解的函數(shù),被稱為Composable。" +
"Compose已經(jīng)預(yù)置了很多的Compose UI組件,這些組件都是基于Material Design規(guī)范設(shè)計(jì)的"
)
}
append("\n")
append("Now,We are working hard")
append(annotatedText)
})
}
運(yùn)行結(jié)果如下:

SpanStyle繼承了TextStyle中關(guān)于文字樣式相關(guān)的字段,而ParagraphyStyle繼承了TextStyle中控制鍛煉的樣式,例如textAlign,lineHeight等。SpanStyle和ParagraphyStyle中的設(shè)置優(yōu)先于整個(gè)TextStyle中同名屬性的設(shè)置
看到上圖中的綠色文字,是不是有一種想點(diǎn)擊的沖動(dòng),可惜現(xiàn)在是無(wú)法點(diǎn)擊的,若要實(shí)現(xiàn)點(diǎn)擊,我們需要借助于ClickedText.演示代碼如下:
@Composable
fun ClickTextDemo() {
ClickableText(text = annotatedText, onClick = { offset ->
annotatedText.getStringAnnotations(
tag = "URL",
start = offset,
end = offset
).firstOrNull()?.let {
Log.d("zhongxj", "click me, content: $it")
}
})
}
val annotatedText = buildAnnotatedString {
withStyle(style = ParagraphStyle(lineHeight = 25.sp)) {
append(
"在Compose中,每一個(gè)組件都是帶有@Compose注解的函數(shù),被稱為Composable。" +
"Compose已經(jīng)預(yù)置了很多的Compose UI組件,這些組件都是基于Material Design規(guī)范設(shè)計(jì)的"
)
}
append("\n")
pushStringAnnotation(tag = "URL", annotation = "http://xxxxx")
withStyle(
style = SpanStyle(
fontWeight = FontWeight.W900,
textDecoration = TextDecoration.Underline,
color = Color(0xFF59A869)
)
) {
append("點(diǎn)擊我,了解更多")
}
}
運(yùn)行結(jié)果如下:

這樣才可以點(diǎn)擊,點(diǎn)擊的時(shí)候我們打了一個(gè)Log,證明點(diǎn)擊生效了

6.SelectionContainer可選中文字
Text自身默認(rèn)是不能被長(zhǎng)按選擇的,否則在Button使用的時(shí)候,就會(huì)出現(xiàn)傳統(tǒng)View的Button是可粘貼的Button的按鈕,Compose提供了專門(mén)的SelectionContainer組件對(duì)包裹的Text進(jìn)行選中,演示代碼如下:
@Composable
fun SelectionContainerDemo() {
SelectionContainer {
Text(text = "我是可以被復(fù)制的文字")
}
}
運(yùn)行結(jié)果:

7.TextField輸入框
TextField組件是我們最常用的文本輸入框,遵循Material Design設(shè)計(jì)準(zhǔn)則,它有一個(gè)低級(jí)別的底層組件,BasicTextField.TextField有兩種風(fēng)格,默認(rèn)的(filled)和OutlinedTextField我們可以先看下輸入框的參數(shù)
@Composable
fun TextField(
value: String, // 輸入框顯示的文本
onValueChange: (String) -> Unit, // 當(dāng)輸入框內(nèi)的文字發(fā)生改變時(shí)的回調(diào),其中帶有最新的文本參數(shù)
modifier: Modifier = Modifier,// 修飾符
enabled: Boolean = true,// 是否啟用
readOnly: Boolean = false, // 控制輸入框的可編輯狀態(tài)
textStyle: TextStyle = LocalTextStyle.current, // 輸入框內(nèi)文字樣式
label: @Composable (() -> Unit)? = null, // 可選的標(biāo)簽,將顯示在輸入框內(nèi)
placeholder: @Composable (() -> Unit)? = null, // 占位符,當(dāng)輸入框處于焦點(diǎn)位置且輸入框文本為空時(shí)顯示
leadingIcon: @Composable (() -> Unit)? = null, // 輸入框開(kāi)頭的前置圖標(biāo)
trailingIcon: @Composable (() -> Unit)? = null,// 輸入框末尾的后置圖標(biāo)
isError: Boolean = false, // 指示輸入框當(dāng)前值是否有錯(cuò),當(dāng)值為true時(shí),標(biāo)簽底部指示器和尾部圖標(biāo)將以錯(cuò)誤的顏色顯示
visualTransformation: VisualTransformation = VisualTransformation.None,// 輸入框內(nèi)的文字視覺(jué)
keyboardOptions: KeyboardOptions = KeyboardOptions.Default, // 軟鍵盤(pán)選項(xiàng),包含鍵盤(pán)類型和ImeAction等配置
keyboardActions: KeyboardActions = KeyboardActions(), // 當(dāng)輸入服務(wù)發(fā)出一個(gè)IME動(dòng)作時(shí),相應(yīng)的回調(diào)被調(diào)用
singleLine: Boolean = false,// 輸入框是否只能輸入一行
maxLines: Int = Int.MAX_VALUE, // 輸入框能輸入的最大行數(shù)
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, // 監(jiān)聽(tīng)組件的狀態(tài)便于自定義
// 組件不同狀態(tài)下的樣式
shape: Shape =
MaterialTheme.shapes.small.copy(bottomEnd = ZeroCornerSize, bottomStart = ZeroCornerSize),// 輸入框的外觀形狀
colors: TextFieldColors = TextFieldDefaults.textFieldColors() // 輸入框的顏色組
)
演示示例如下所示:
@Composable
fun TextFieldDemo() {
var text by remember {
mutableStateOf("")
}
TextField(value = text, onValueChange = {
text = it
},
label = { Text(text = "用戶名") })
}
運(yùn)行結(jié)果

輸入框附帶一個(gè)label,label會(huì)更具輸入框獲得焦點(diǎn)而呈現(xiàn)出不同的效果,底部會(huì)有一個(gè)高亮的圖標(biāo),代碼中有關(guān)于State的使用,此處不做講解,這里用于展示使用
我們還可以給輸入框添加裝飾,代碼如下:
@Composable
fun TextFieldWithDec() {
var username by remember {
mutableStateOf("")
}
var password by remember {
mutableStateOf("")
}
Column {
TextField(value = username, onValueChange = {
username = it
}, label = { Text(text = "用戶名") }, leadingIcon = {
Icon(imageVector = Icons.Filled.AccountBox, contentDescription = "用戶名")
})
TextField(value = password, onValueChange = {
password = it
}, label = { Text(text = "密碼") }, trailingIcon = {
IconButton(onClick = { /*TODO*/ }) {
Icon(
painter = painterResource(id = R.drawable.password),
modifier = Modifier.size(16.dp),
contentDescription = "password"
)
}
})
}
}
運(yùn)行結(jié)果

8.OutlinedTextField邊框樣式輸入框
OutlinedTextField是按照Material Design規(guī)范設(shè)計(jì)的另一種風(fēng)格的輸入框,除了外觀上帶有一個(gè)邊框,其他用法和TextField基本一致,演示代碼如下:
@Composable
fun OutlineTextFieldDemo()
{
var text by remember {
mutableStateOf("")
}
OutlinedTextField(value = text, onValueChange = {text = it},
label = { Text(text = "用戶名")})
}
運(yùn)行結(jié)果:

9.BasicTextField
BasicTextField是一個(gè)更低級(jí)別的Compose組件,與TextField,OutlinedTextField不同的是,BasicTextField擁有更多的自定義效果,我們可以看下BasicTextField為我們提供的可選參數(shù)列表:
@Composable
fun BasicTextField(
value: String,
onValueChange: (String) -> Unit,
modifier: Modifier = Modifier,
enabled: Boolean = true,
readOnly: Boolean = false,
textStyle: TextStyle = TextStyle.Default,
keyboardOptions: KeyboardOptions = KeyboardOptions.Default,
keyboardActions: KeyboardActions = KeyboardActions.Default,
singleLine: Boolean = false,
maxLines: Int = Int.MAX_VALUE,
visualTransformation: VisualTransformation = VisualTransformation.None,
onTextLayout: (TextLayoutResult) -> Unit = {}, // 當(dāng)輸入框文本更新時(shí)的回調(diào)包括當(dāng)前文本的各種信息
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
cursorBrush: Brush = SolidColor(Color.Black), // 輸入框光標(biāo)的顏色
decorationBox: @Composable (innerTextField: @Composable () -> Unit) -> Unit =
@Composable { innerTextField -> innerTextField() } // 允許在TextField周圍添加修飾的Composable lambda,需要在布局中
// 中調(diào)用innerTextField()才能完成TextField的創(chuàng)建
)
我們可以看到,BasicTextField的參數(shù)和TextField的參數(shù)有很多共同的地方,我們自定義的關(guān)鍵在于最后一個(gè)參數(shù)decorationBox,decorationBox是一個(gè)Composable,它回調(diào)了一個(gè)innerTextField函數(shù)給我們,innerTextField是框架定義好給我們使用的,它就是文字輸入的入口,所以需要?jiǎng)?chuàng)建一個(gè)完整的輸入框界面,并且在合適的地方調(diào)用這個(gè)函數(shù),我們實(shí)現(xiàn)一個(gè)仿當(dāng)前大多是app都會(huì)使用的輸入框結(jié)束今天的內(nèi)容:代碼如下
@Composable
fun SearchBar() {
var text by remember {
mutableStateOf("")
}
Box(
modifier = Modifier
.fillMaxSize()
.background(Color(0xFFD3D3D3)),
contentAlignment = Alignment.Center
)
{
BasicTextField(value = text, onValueChange = {
text = it
}, decorationBox = { innerTextField ->
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.padding(vertical = 2.dp, horizontal = 8.dp)
) {
Icon(imageVector = Icons.Filled.Search, contentDescription = null)
Box(
modifier = Modifier.padding(horizontal = 10.dp),
contentAlignment = Alignment.CenterStart
) {
if (text.isEmpty()) {
Text(
text = "請(qǐng)輸入", style = TextStyle(
color = Color(0, 0, 0, 128)
)
)
}
innerTextField()
}
Box(
modifier = Modifier.fillMaxWidth(),
contentAlignment = Alignment.CenterEnd
) {
if (text.isNotEmpty()) {
IconButton(onClick = { text = "" }, modifier = Modifier.size(16.dp)) {
Icon(
imageVector = Icons.Filled.Close, contentDescription = null
)
}
}
}
}
}, modifier = Modifier
.padding(horizontal = 10.dp)
.background(Color.White, CircleShape)
.height(30.dp)
.fillMaxWidth()
)
}
}
運(yùn)行結(jié)果

總結(jié)
至此,我們的文字組件就介紹完了,本文只是簡(jiǎn)單的介紹了文字組件的入門(mén)功能,如果讀者想要實(shí)現(xiàn)更加復(fù)雜絢麗的功能,請(qǐng)查看官方文檔和腳本之家其它相關(guān)文章!
- Jetpack Compose按鈕組件使用實(shí)例詳細(xì)講解
- Jetpack Compose圖片組件使用實(shí)例詳細(xì)講解
- Jetpack Compose之選擇器使用實(shí)例講解
- Jetpack Compose實(shí)現(xiàn)對(duì)話框和進(jìn)度條實(shí)例解析
- Android使用Jetpack Compose開(kāi)發(fā)零基礎(chǔ)起步教程
- Jetpack?Compose實(shí)現(xiàn)對(duì)角線滾動(dòng)效果
- 融會(huì)貫通Android?Jetpack?Compose中的Snackbar
- 使用Jetpack Compose實(shí)現(xiàn)翻轉(zhuǎn)卡片效果流程詳解
相關(guān)文章
Android獲取屏幕方向及鍵盤(pán)狀態(tài)的小例子
很多開(kāi)發(fā)Android的網(wǎng)友可能需要判斷當(dāng)前的屏幕方向或鍵盤(pán)狀態(tài),下面的代碼可以判斷出橫屏landscape和常規(guī)的portrait縱握方式,如果使用的是G1這樣有QWERTY鍵盤(pán)硬件的,還可以判斷屏幕方向以及鍵盤(pán)的拉出狀態(tài)。2013-05-05
Android仿美團(tuán)分類下拉菜單實(shí)例代碼
這篇文章主要為大家詳細(xì)介紹了Android仿美團(tuán)分類下拉菜單實(shí)例代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-05-05
Android編程程序?qū)崿F(xiàn)一鍵鎖屏的方法講解
今天小編就為大家分享一篇關(guān)于Android編程程序?qū)崿F(xiàn)一鍵鎖屏的方法講解,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2019-03-03
mac開(kāi)發(fā)android環(huán)境搭建步驟圖解
這里比較詳細(xì)的來(lái)總結(jié)下mac開(kāi)發(fā)android的環(huán)境搭建步驟安裝過(guò)程,希望對(duì)一些正準(zhǔn)備配置Android開(kāi)發(fā)環(huán)境的小伙伴們有一定幫助2014-01-01
Android使用ViewFlipper實(shí)現(xiàn)圖片切換功能
這篇文章主要為大家詳細(xì)介紹了Android使用ViewFlipper實(shí)現(xiàn)圖片切換功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-07-07
Android懸浮按鈕點(diǎn)擊返回頂部FloatingActionButton
這篇文章主要為大家詳細(xì)介紹了Android懸浮按鈕FloatingActionButton點(diǎn)擊回到頂部的實(shí)現(xiàn)代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-02-02

