昨天講解了 Grid Layout 的基本用法,今天來講最後一個參數 content 的 LazyGridScope 是什麼。
Layout 佈局分為 Column 、Row 、Grid,這類排列的 Composable 最後一行的參數content 可以擺入要呈現的 composable。可以觀察到預設值都是 content: xxxScope.() -> Unit 的形式,不像其他 Compose 是content: () -> Unit 。
Scope 的名稱會對應 Composable 的名,例如 Column 的 Scope 就是ColumnScope ,LazyColumn 是LazyListScope ,而 LazyVerticalGrid 就是 LazyGridScope 。
在 Column 、Row 、Grid 前面加上 Lazy,效果就是以前的 RecyclerView 。Lazy 系列的 Scope 的特點在於,不能直接在 content ={ } 中使用 composable 而是要在DSL 定義的方法內部使用,像是 item() 、items() 等。
關鍵術語:
DSL是 domain-specific language 的縮寫,翻譯成特定領域的語言,也就是block範圍內能使用定義好的function、參數等等。
這裡先舉例 LazyColumn 的DSL function
@Preview(showBackground = true)
@Composable
fun LazyColumnDSL() {
val intList: List<Int> = listOf(1, 2, 3)
LazyColumn {
// 新增1列
item {
Text(text = "First item")
}
// 新增5列
items(5) { index ->
Text(text = "items 5: item =$index")
}
// 傳入 list 或 array
items(intList) { int ->
Text(text = "items list : item = $int")
}
// 傳入 list 或 array 並帶有 index 值
itemsIndexed(intList) { index, int ->
Text(text = "items index list : index= $index: item = $int")
}
}
}

Grid Layout 的 scope 和 column 一樣也可以用 item 、items(i)、items(List)、items(Array)、itemsIndexed(*List*) 、itemsIndexed(*Array*) 。
Grid Layout 可以很好的計算每一行有多少 items ,但有時候想另外插一行行跨多個欄位的 item 要怎麼做呢?
在 LazyGridScope 中 item() 參數 span 可以做到跨行效果。
fun item(
key: Any? = null,
span: (LazyGridItemSpanScope.() -> GridItemSpan)? = null,
contentType: Any? = null,
content: @Composable LazyGridItemScope.() -> Unit
)
span = {} 中使用 GridItemSpan(int) 可以單獨計算出該item要行跨多少欄位。
int : 1代表佔用1欄位,數字大於最大欄數效果等同最大欄數 maxLineSpan
this.maxLineSpan : 最大欄數this.maxCurrentLineSpan : 剩餘最大欄數GridItemSpan(3) |
GridItemSpan(this.maxLineSpan) |
GridItemSpan(this.maxCurrentLineSpan) |
|---|---|---|
![]() |
![]() |
![]() |
@Preview
@Composable
fun GridLayout() {
val list = (1..9).map { it.toString() }
LazyVerticalGrid(
//...
content = {
//單一個item
item() {
Card(
//...
) {
//...
}
}
// span item
item(span = { GridItemSpan(this.maxLineSpan) }) {
Card(
modifier = Modifier
.padding(4.dp)
.fillMaxWidth()
) {
Text(
text = "Span",
fontWeight = FontWeight.Bold,
fontSize = 30.sp,
textAlign = TextAlign.Center,
modifier = Modifier.padding(16.dp)
)
}
}
// list items
items(list.size) { index ->
//...
}
}
)
}
今天介紹了 content 如何使用 Scope,以及專有名詞DSL。
在 grid layout 橫跨多欄可以運用 Span 參數。
今日運動
休息