Jetpack?Compose基礎(chǔ)組件之文字組件
概述
文本是UI界面中最常見的元素之一,在Compose中,文字組件扮演著重要的角色,文字組件是遵循Material Design規(guī)范設(shè)計的上層組件,如果我們不想使用Material Design,我們也可以直接使用更底層的文本組件,如Text組件對應(yīng)的更底層的文本組件是BasicText,文本組件不得不提輸入框的使用,本文會主要介紹Text和輸入框,并且實現(xiàn)一個現(xiàn)在App中都在用的好看的輸入框
文字組件
1.Text 文本
因為Composable組件都是函數(shù),所有的配置都來自于參數(shù)的傳遞,所以我們通過參數(shù)列表就可以了解組件的所有功能,Text組件的參數(shù)列表如下:
@Composable fun Text( text: String, // 需要顯示的文本 modifier: Modifier = Modifier,// 修飾符 color: Color = Color.Unspecified, // 文字顏色 fontSize: TextUnit = TextUnit.Unspecified,// 文字大小 fontStyle: FontStyle? = null, // 繪制文本時使用的字體變換,如斜體 fontWeight: FontWeight? = null, // 文字的粗細(xì) fontFamily: FontFamily? = null,// 文字的字體 letterSpacing: TextUnit = TextUnit.Unspecified, // 文本間距 textDecoration: TextDecoration? = null, // 文字裝飾,如下劃線,刪除線等 textAlign: TextAlign? = null, // 文本的對齊方式 lineHeight: TextUnit = TextUnit.Unspecified, // 文本行間距 overflow: TextOverflow = TextOverflow.Clip,// 文本溢出時的視覺效果,比如超出的文字用三個點表示 softWrap: Boolean = true,// 控制文本是否能夠換行,如果為false,則會定位 maxLines: Int = Int.MAX_VALUE,// 文本最多的展示行數(shù) onTextLayout: (TextLayoutResult) -> Unit = {},// 在文本發(fā)生變化之后,會回調(diào)一個TextLayoutResult,包含此文本的各種信息 style: TextStyle = LocalTextStyle.current // 文本的風(fēng)格配置,如顏色,字體,行高等 )
Text組件的參數(shù)會按照其使用的頻度排序,比如text和modifier排在靠前的位置,并盡量添加默認(rèn)實現(xiàn)。
Text組件的基本功能是顯示一段文字,可以為text參數(shù)傳入要顯示的文字內(nèi)容,Compose也提供了stringResource方法,通過R 資源文件獲取字符串,方便做多語言適配
// 指定字符串 Text(text = "Hello World") // 指定文字資源 Text(text = stringResource(id = R.string.app_name))
2.Text的style文字樣式
style參數(shù)接受一個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) ) } }
運行結(jié)果如下所示:
代碼中的TextDecoration可以為文字增加刪除線或下劃線,F(xiàn)ontStyle可以用來設(shè)置文字是否是斜體
3.maxLines參數(shù)
maxLines參數(shù)可以幫助我們將文本限制在指定行數(shù)之間,當(dāng)文本超過了參數(shù)設(shè)置的閾值時,文本會被截斷,而overflow可以處理文字過多的場景,文字過多的時候會以“...”結(jié)尾,這個參數(shù)可以用來實現(xiàn)一個閱讀文字時的展開和收起功能,當(dāng)我們顯示很多條數(shù)據(jù)時,每一條數(shù)據(jù)都有很多的文字,這時我們可以使用這個參數(shù),默認(rèn)只展示指定的行數(shù),提供一個展開按鈕,當(dāng)用戶點擊展開的時候,就顯示所有的文本。展示收起按鈕,點擊收起按鈕又可以顯示指定的行數(shù)。這個功能后面有時間我們會演示,這里我們先看下基本的演示代碼:
@Composable fun MaxLinesDemo() { Column { Text( text = "在Compose中,每一個組件都是帶有@Compose注解的函數(shù),被稱為Composable。" + "Compose已經(jīng)預(yù)置了很多的Compose UI組件,這些組件都是基于Material Design規(guī)范設(shè)計的", style = MaterialTheme.typography.body1, color = Color.Red ) Spacer(modifier = Modifier.size(10.dp)) Text( text = "在Compose中,每一個組件都是帶有@Compose注解的函數(shù),被稱為Composable。" + "Compose已經(jīng)預(yù)置了很多的Compose UI組件,這些組件都是基于Material Design規(guī)范設(shè)計的", style = MaterialTheme.typography.body1, maxLines = 1, color = Color.Green ) Spacer(modifier = Modifier.size(10.dp)) Text( text = "在Compose中,每一個組件都是帶有@Compose注解的函數(shù),被稱為Composable。" + "Compose已經(jīng)預(yù)置了很多的Compose UI組件,這些組件都是基于Material Design規(guī)范設(shè)計的", style = MaterialTheme.typography.body1, maxLines = 1, color = Color.Blue, overflow = TextOverflow.Ellipsis ) } }
運行結(jié)果:
4.fontFamily字體風(fēng)格
fontFamily參數(shù)用來設(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) } }
運行結(jié)果
當(dāng)使用系統(tǒng)中沒有的字體時,可以右擊res文件夾,選擇New->Android Resource Directory->Resource type ->font創(chuàng)建font文件夾,然后將自己的字體拖入文件夾即可
5.AnnotatedString多樣式文字
AnnotatedString 其實很像傳統(tǒng)View中的SpannableString,在很多的場景中,我們需要在一段文字中突出某些內(nèi)容,比如超鏈接和電話號碼,我們點擊超鏈接和電話號碼能跳到鏈接指向的頁面和撥打電話。在Compose中就需要使用AnnotatedString多樣式文字,AnnotatedString是一個數(shù)據(jù)類,除了文本值,它還包含了一個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中,每一個組件都是帶有@Compose注解的函數(shù),被稱為Composable。" + "Compose已經(jīng)預(yù)置了很多的Compose UI組件,這些組件都是基于Material Design規(guī)范設(shè)計的" ) } append("\n") append("Now,We are working hard") append(annotatedText) }) }
運行結(jié)果如下:
SpanStyle繼承了TextStyle中關(guān)于文字樣式相關(guān)的字段,而ParagraphyStyle繼承了TextStyle中控制鍛煉的樣式,例如textAlign,lineHeight等。SpanStyle和ParagraphyStyle中的設(shè)置優(yōu)先于整個TextStyle中同名屬性的設(shè)置
看到上圖中的綠色文字,是不是有一種想點擊的沖動,可惜現(xiàn)在是無法點擊的,若要實現(xià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中,每一個組件都是帶有@Compose注解的函數(shù),被稱為Composable。" + "Compose已經(jīng)預(yù)置了很多的Compose UI組件,這些組件都是基于Material Design規(guī)范設(shè)計的" ) } append("\n") pushStringAnnotation(tag = "URL", annotation = "http://xxxxx") withStyle( style = SpanStyle( fontWeight = FontWeight.W900, textDecoration = TextDecoration.Underline, color = Color(0xFF59A869) ) ) { append("點擊我,了解更多") } }
運行結(jié)果如下:
這樣才可以點擊,點擊的時候我們打了一個Log,證明點擊生效了
6.SelectionContainer可選中文字
Text自身默認(rèn)是不能被長按選擇的,否則在Button使用的時候,就會出現(xiàn)傳統(tǒng)View的Button是可粘貼的Button的按鈕,Compose提供了專門的SelectionContainer組件對包裹的Text進行選中,演示代碼如下:
@Composable fun SelectionContainerDemo() { SelectionContainer { Text(text = "我是可以被復(fù)制的文字") } }
運行結(jié)果:
7.TextField輸入框
TextField組件是我們最常用的文本輸入框,遵循Material Design設(shè)計準(zhǔn)則,它有一個低級別的底層組件,BasicTextField.TextField有兩種風(fēng)格,默認(rèn)的(filled)和OutlinedTextField我們可以先看下輸入框的參數(shù)
@Composable fun TextField( value: String, // 輸入框顯示的文本 onValueChange: (String) -> Unit, // 當(dāng)輸入框內(nèi)的文字發(fā)生改變時的回調(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)輸入框處于焦點位置且輸入框文本為空時顯示 leadingIcon: @Composable (() -> Unit)? = null, // 輸入框開頭的前置圖標(biāo) trailingIcon: @Composable (() -> Unit)? = null,// 輸入框末尾的后置圖標(biāo) isError: Boolean = false, // 指示輸入框當(dāng)前值是否有錯,當(dāng)值為true時,標(biāo)簽底部指示器和尾部圖標(biāo)將以錯誤的顏色顯示 visualTransformation: VisualTransformation = VisualTransformation.None,// 輸入框內(nèi)的文字視覺 keyboardOptions: KeyboardOptions = KeyboardOptions.Default, // 軟鍵盤選項,包含鍵盤類型和ImeAction等配置 keyboardActions: KeyboardActions = KeyboardActions(), // 當(dāng)輸入服務(wù)發(fā)出一個IME動作時,相應(yīng)的回調(diào)被調(diào)用 singleLine: Boolean = false,// 輸入框是否只能輸入一行 maxLines: Int = Int.MAX_VALUE, // 輸入框能輸入的最大行數(shù) interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, // 監(jiān)聽組件的狀態(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 = "用戶名") }) }
運行結(jié)果
輸入框附帶一個label,label會更具輸入框獲得焦點而呈現(xiàn)出不同的效果,底部會有一個高亮的圖標(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" ) } }) } }
運行結(jié)果
8.OutlinedTextField邊框樣式輸入框
OutlinedTextField是按照Material Design規(guī)范設(shè)計的另一種風(fēng)格的輸入框,除了外觀上帶有一個邊框,其他用法和TextField基本一致,演示代碼如下:
@Composable fun OutlineTextFieldDemo() { var text by remember { mutableStateOf("") } OutlinedTextField(value = text, onValueChange = {text = it}, label = { Text(text = "用戶名")}) }
運行結(jié)果:
9.BasicTextField
BasicTextField是一個更低級別的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)輸入框文本更新時的回調(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)鍵在于最后一個參數(shù)decorationBox,decorationBox是一個Composable,它回調(diào)了一個innerTextField函數(shù)給我們,innerTextField是框架定義好給我們使用的,它就是文字輸入的入口,所以需要創(chuàng)建一個完整的輸入框界面,并且在合適的地方調(diào)用這個函數(shù),我們實現(xiàn)一個仿當(dāng)前大多是app都會使用的輸入框結(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 = "請輸入", 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() ) } }
運行結(jié)果
總結(jié)
至此,我們的文字組件就介紹完了,本文只是簡單的介紹了文字組件的入門功能,如果讀者想要實現(xiàn)更加復(fù)雜絢麗的功能,請查看官方文檔和腳本之家其它相關(guān)文章!
相關(guān)文章
Android編程程序?qū)崿F(xiàn)一鍵鎖屏的方法講解
今天小編就為大家分享一篇關(guān)于Android編程程序?qū)崿F(xiàn)一鍵鎖屏的方法講解,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧2019-03-03mac開發(fā)android環(huán)境搭建步驟圖解
這里比較詳細(xì)的來總結(jié)下mac開發(fā)android的環(huán)境搭建步驟安裝過程,希望對一些正準(zhǔn)備配置Android開發(fā)環(huán)境的小伙伴們有一定幫助2014-01-01Android使用ViewFlipper實現(xiàn)圖片切換功能
這篇文章主要為大家詳細(xì)介紹了Android使用ViewFlipper實現(xiàn)圖片切換功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-07-07Android懸浮按鈕點擊返回頂部FloatingActionButton
這篇文章主要為大家詳細(xì)介紹了Android懸浮按鈕FloatingActionButton點擊回到頂部的實現(xiàn)代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-02-02