iT邦幫忙

2022 iThome 鐵人賽

DAY 16
0

在排版 UI 時,有時會想要把元件群組、彼此堆疊,或有時就只是需要一個可以動態撐開的空間。在 Compose 的世界裡,有些排版元件的功能就是協助我們更快的做出一些常見的排版小塊,方便我們做更彈性的組合。今天的耕讀筆記,就要來研究除了 ColumnRow 之外的其他排版元件。

Surface 元件

Surface 直譯就是一個「平面」,用來擺放許多元件在這個平面裡,透過對 Surface 設定 Modifier 來改變整個平台的形狀、邊框、顏色、陰影…等,如此就可以達成群組的效果。

Surface(
    modifier = Modifier.width(300.dp).height(100.dp),
    shape = RoundedCornerShape(8.dp),
    elevation = 7.dp,
) {
    Row {
        AsyncImage(
            load = { loadImageBitmap("https://picsum.photos/500") },
            painterFor = { remember { BitmapPainter(it) } },
            contentDescription = "Photo",
            contentScale = ContentScale.Crop,
            modifier = Modifier.size(100.dp)
                .padding(end = 12.dp),
        )
        Column(
            modifier = Modifier.fillMaxHeight(),
            verticalArrangement = Arrangement.Center
        ) {
            Text(
                text = "Lorem Ipsum",
                fontSize = 15.sp
            )
            Text(
                text = "Lorem ipsum dolor sit amet...",
                fontSize = 8.sp,
                modifier = Modifier.padding(vertical = 8.dp)
            )
        }
    }
}

在上例裡,我們用先 ColumnRow 做出了一個左邊放一張正方形圖片、右上一句標題、右下一段文字,再把這些元件放在一個 Surface 裡,接著就可以透過 Modifier 設定其寬(300 dp)、高(100 dp)、形狀(圓角矩形)、海拔(決定下落式陰影的深淺)。

Box 元件

Box 可以將包住的元件,依照程式碼從上而下的順序,依次將元件推疊在畫面上。若有 Web 前端經驗、寫過 CSS 的話,可以類比為寫在 Box 裡的每個元件,其 z 值一層一層加上去一樣。

Box(
    modifier = Modifier.fillMaxSize(),
) {
    Text(
        text = "This text is drawn first",
        modifier = Modifier.align(Alignment.TopCenter),
    )
    Box(
        modifier = Modifier.align(Alignment.TopCenter)
            .fillMaxHeight()
            .width(50.dp)
            .background(Color.Blue)
    )
    Text(
        text = "This text is drawn last",
        modifier = Modifier.align(Alignment.Center)
    )
}

在上面的例子裡,最外層的 Box 被設定為撐到整個畫面,其內的第一個 Text 元件會第一個被繪製在畫面的中間靠上。第二個 Box 元件的高度被撐到整個畫面,寬度只有 50 dp,背景色為藍色,所以畫面看起來有一個直長條在正中央。也因為是第二個被繪製的元件,所以會壓過第一個繪製的 Text 元件重疊的部份。第三個 Text 元件會最後才被繪製在畫面的正中央,因為是最後一個繪製,所以會壓過第二個繪製的 Box 元件。

透過這個範例,就可以了解 Box 內元件層層疊疊的效果。

Spacer 元件

還記得早期在做網頁切版時,有時為了精準的控制版面,會在頁面上放一個 1 x 1 像素的透明圖片,透過控制透明圖片的尺寸,來撐大或推擠畫面上的元素,以達成排版的效果,Spacer 的用途就像如此。使用它只需要用 Modifier 來控制它的寬高,就可以用這個「空間」來微調畫面上元件的位置:

var sliderPosition by remember { mutableStateOf(0f) }

Box(
    modifier = Modifier.fillMaxSize(),
    contentAlignment = Alignment.Center,
) {
    Column(
        modifier = Modifier.width(250.dp)
    ) {
        Row(
            modifier = Modifier.padding(end = 20.dp),
            horizontalArrangement = Arrangement.Center,
            verticalAlignment = Alignment.CenterVertically,
        ) {
            Icon(
                imageVector = Icons.Filled.Favorite,
                contentDescription = "Favorite Icon"
            )
            Spacer(
                modifier = Modifier.width(ceil(sliderPosition * 100).dp)
            )
            Icon(
                imageVector = Icons.Filled.Lock,
                contentDescription = "Lock Icon"
            )
        }
        Slider(
            value = sliderPosition,
            onValueChange = { sliderPosition = it },
        )
    }
}

在上面的例子裡,筆者試著將 Spacer 的寬度改變利用前面研究過的元件來做動態展示。首先將 Box 撐滿整個畫面,並將所有內容水平垂直置中,接著用 Column 切分上半部的 Row 及下半部的 Slider,在 Row 裡面放兩個 Icon,中間以 Spacer 隔開。最後,再透過 Slider 的操控,來調整 Spacermodifier 參數裡,width 的寬度值,如此就能以視覺化的方式,了解 Spacer 在版面控制上的效果了。

透過今天的三個例子,將前面研究過的元件組合起來一起使用,讀者是不是可以逐漸感受到 Compose 的好用之處呢?

參考資料


上一篇
第 15 天:排版元件之 Column、Row
下一篇
第 17 天:Desktop 特有元件之 Tooltip
系列文
傳教士的 Compose for Desktop 耕讀筆記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言