昨天講解了 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
參數。
今日運動
休息