一文講完Jetpack常用修飾符
「這是我參與2022首次更文挑戰的第15天,活動詳情檢視:2022首次更文挑戰」。
Jetpack Compose系列(4) - 修飾符
修飾符
Modifier,即JetpackCompose中的修飾符,可以用來修飾以下內容:
· 更改可組合項的大小、佈局、行為和外觀
· 新增資訊,如無障礙標籤
· 處理使用者輸入
· 新增高階互動,如使元素可點選、可滾動、可拖動或可縮放
修飾符是標準的Kotlin物件,可以通過呼叫某個Modifier類函式來建立修飾符,例如:
@Preview(showBackground = true)
@Composable
fun DefaultPreview() {
Column(modifier = Modifier.padding(35.dp)){
Text(text = "Hello")
Text(text = "Modifier")
}
}
對應生成的padding值為15dp的兩個Text列表效果為:
相信到這裡你已經開始明白,Modifier可以像原先View體系中的XML檔案裡設定padding等擴充套件函式來調節佈局效果,當然也可以調節width和height一系列屬性,下面就讓我們來熟悉這些你以後經常使用到的擴充套件函式:
背景(background)和透明度(alpha)
· background(color: Color, shape: Shape?):設定背景及背景形狀,shape可以指定形狀,例如可以使用RoundedCornerShape來指定圓角大小。
· alpha(alpha: Float):設定透明度,範圍值從0到1。
如果是漸變背景,可以使用background(brush: Brush, shape: Shape?, alpha: Float?)。其中Brush引數就是我們指定的漸變,例如使用verticalGradient建立的豎直方向漸變:
@Composable
fun CustomView() {
Column(modifier = Modifier.background(
Brush.verticalGradient(listOf(Color.Blue,Color.Red))
)
.alpha(0.3f)){
Text(text = "Hello")
Text(text = "Modifier")
}
}
對應生成的效果為:
需要注意的是,這裡設定的alpha透明度指的是{}裡的物件的透明度,而如果要修改背景透明度則要把alpha設定進background()內,例如:
在設定Brush的時候,你會發現可以設定很多函式:
這些函式可以做到橫向漸變、線性漸變、掃描漸變,外加指定開始結束位置等等,這裡就不多做介紹了。
大小 ( size ) 和寬高
· width(width: dp): 設定寬度,單位dp。
· height(height: dp): 設定高度,單位dp。
· size(width: dp,height: dp) :同時設定寬高,單位dp。
下面兩段程式碼是等價的:
Column(modifier = Modifier
.background(Color.Red)
.width(60.dp)
.height(120.dp)){
Text(text = "Hello")
Text(text = "Modifier")
}
Column(modifier = Modifier
.background(Color.Red)
.size(60.dp,120.dp)){
Text(text = "Hello")
Text(text = "Modifier")
}
實現效果也是一致的:
邊框 (border) 和點選
· border(width: Dp, color: Color, shape: Shape?):新增邊框,color引數指定顏色,shape引數指定粗細和形狀。
· clickable():讓任意控制元件變的可點選,且會附加水波紋效果。
@Composable
fun CustomView() {
Column(modifier = Modifier
.background(Color.Red)
.width(60.dp)
.height(120.dp)
.clickable (onClick = {
Log.i("clickEvent"," get clicked ! ")
})){
Text(text = "Hello")
Text(text = "Modifier")
}
}
點選列表,對應的控制檯輸出日誌為:
當然,clickable()也有其他引數可以設定不可點選等:
Modifier.clickable(
enabled: Boolean = true, // 是否可點選狀態,預設可點選,false則不可點選
onClickLabel: String? = null, // 語義/可訪問性標籤
role: Role? = null, // 點選元素的型別,例如Button、Checkbox、Image等。用於可訪問性服務。
onClick: () -> Unit // 響應點選事件
)
· combinedClickable:可設定長按,多次點選,普通點選監聽等。注意:這是實驗性的API隨時可能刪除(使用時會要求方法和方法被呼叫處帶上@ExperimentalFoundationApi)。示例如下:
@ExperimentalFoundationApi
@Composable
fun CustomView() {
Column(modifier = Modifier
.background(Color.Red)
.width(60.dp)
.height(120.dp)
.combinedClickable (
onLongClick = {
Log.i("clickEvent"," onLongClick event happened ! ")
},
onDoubleClick = {
Log.i("clickEvent"," onDoubleClick event happened ! ")
},
onClick = {
Log.i("clickEvent"," onClick event happened ! ")
}
)){
Text(text = "Hello")
Text(text = "Modifier")
}
}
對應日誌也能在控制檯正確輸出:
· onFocusChanged():監聽焦點變化事件。
· focusable():設定焦點。
· requiredWidth(width: Dp):強制設定寬度,可以忽略父元素的寬高限制。
· requiredHeight(height: Dp):強制設定高度,可以忽略父元素的寬高限制。
· heightIn(min: Dp, max: Dp ),設定高度的最大最小值。widthIn同理。
· padding(all: Dp): 在元素周圍留出空間,即內邊距。
· rotate(degrees: Float):設定旋轉度數。
· scale(scaleX: Float, scaleY: Float):設定縮放,如果是負數可以實現映象效果。
· horizontalScroll(),允許子元素在寬度大於最大限制時橫向滾動。(指超出螢幕寬度後,我們還可以水平方向滾動)
· verticalScroll(),允許子元素在寬度大於最大限制時垂直滾動。
例如:
Row(Modifier.horizontalScroll(rememberScrollState())) {
Box(
Modifier
.size(700.dp, 50.dp)
.background(Color.Red)
){
Text("123")
}
}
對應輸出效果為:
這時這個紅色的條目是可以左右拖動的。
· fillMaxHeight(fraction: Float = 1f):子佈局填充父項允許的所有可用高度,效果類似於XML中的match_parent,預設值1f。fillMaxSize 和 fillMaxWidth同理。
例如如下程式碼:
Box(Modifier.requiredSize(100.dp).background(Color.Red)) {
Box(
Modifier.fillMaxWidth(0.6f)
.fillMaxHeight(0.5f)
.background(color = Color.Yellow)
)
}
對應的效果為:
· wrapContentSize:元件的控制元件寬高若是小與定義的最小寬高,會將元件進行排列的設定(看名字是不是想起了wrap_content)。
· sizeIn(minWidth: Dp ,minHeight: Dp ,maxWidth: Dp ,maxHeight: Dp):設定寬高的最小值和最大值,寬度在minWidth ~ maxWidth之間,高度在minHeight ~ maxHeight之間。
Column {
Box(
Modifier
.sizeIn(minWidth = 50.dp, minHeight = 50.dp)
.size(20.dp)
.background(Color.Black)
)
Box(
Modifier
.sizeIn(minWidth = 50.dp, minHeight = 50.dp)
.wrapContentSize(Alignment.TopCenter)
.size(20.dp)//設定的size小於最小寬高,最終渲染出來的就是20*20的,對齊方式為TopCenter
.background(Color.Red)
)
}
對應的效果為:
由程式碼可知,黑色的Box設定的size小於最小寬高,最終渲染出來的就是5050的長寬。紅色的Box設定了wrapContentSize,設定的size小於最小寬高,最終渲染出來的就是2020的長寬,同時對齊方式為TopCenter。
當然,也可以單獨設定寬高wrap:
//設定寬度
wrapContentWidth(
align: Alignment.Horizontal = Alignment.CenterHorizontally,
unbounded: Boolean = false
)
//設定高度
wrapContentHeight(
align: Alignment.Vertical = Alignment.CenterVertically,
unbounded: Boolean = false
)
我們修改上述程式碼中的兩個屬性:
Column {
Box(
Modifier
.sizeIn(minWidth = 50.dp, minHeight = 50.dp)
.wrapContentHeight(Alignment.CenterVertically)
.height(20.dp)//高20dp,寬50dp,垂直居中
.background(Color.Black)
)
Box(
Modifier
.sizeIn(minWidth = 50.dp, minHeight = 50.dp)
.wrapContentWidth(Alignment.CenterHorizontally)
.width(20.dp)//寬20dp,高50dp,水平居中
.background(Color.Red)
)
}
對應的效果展示為:
修飾符順序
修飾符函式的順序非常重要,每個函式都會對上一個函式返回的 Modifier 進行更改。
例如:
Column {
Box(
Modifier
.size(100.dp)
.background(Color.Red)
.padding(25.dp)
)
Box(
Modifier
.size(100.dp)
.padding(25.dp)
.background(Color.Yellow)
)
}
對應的效果為:
觀察程式碼,不難發現,如果先設定背景,然後設定padding值,那麼padding值是在其背景的基礎上進行的。如果是先設定padding值,那麼後設置的背景是針對padding之後的佈局進行設定的。原因很簡單,僅僅是因為每個函式都會對上一個函式返回的Modifier 進行更改。當然,點選事件也會受到影響,但也只是影響點選區域,這點不難理解,不做贅述了。
- 一文講完Jetpack常用修飾符
- JetpackCompose中的Dialog、AlertDialog
- Activity互動問題,你確定都知道?
- Kotlin中的內建函式-apply、let
- Compose自定義動畫API指南
- Android EditText關於imeOptions的設定和響應
- Jetpack 之Glance Compose實現一個小元件
- Compose高級別API動畫指南
- Android錄音功能的實現及踩坑記錄
- LayoutInflater原始碼解析及常見相關報錯分析
- UI自動重新整理大法:DataBinding資料繫結
- DataBinding簡易入門
- 還在用findViewById,不來了解下其它方式?