Android Jetpack Compose Modifier 介紹、常用方式示範 上篇(size, padding, border, clip)

在 Jetpack Compose 中幾乎所有元件都有 Modifier 屬性,透過 Modifier 來控制元件的外觀,例如長寬、邊界、顏色等等,而且順序也會有影響,不過一開始使用起來需要頻繁查詢資料,也因為幾乎每個函式都需要 import,很常 import 到錯誤的 package ,要使用好 Modifier 真的需要很多練習,趁這篇來摸索一下並記錄下來。

引用(導入) Modifier

    
import androidx.compose.ui.Modifier
    

基礎示範

Box 是一個容器元件,主要用於重疊內容的排列,這裡使用 Modifier 設定大小和背景顏色:
    
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.size
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp


Box(
    modifier = Modifier
        .size(100.dp)
        .background(Color.Yellow)
)
    


在測試時如果內容自動被拉伸佔滿全螢幕是因為專案預設使用了 Modifier.fillMaxSize()
    
class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            MyTestProjectTheme {
                // A surface container using the 'background' color from the theme
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colorScheme.background
                ) {
                    MyBox()
                }
            }
        }
    }
}

@Composable
fun MyBox() {
    Box(
        modifier = Modifier
            .size(100.dp)
            .background(Color.Yellow)
    )
}

@Preview(showBackground = true)
@Composable
fun MyBoxPreview() {
    MyTestProjectTheme {
        MyBox()
    }
}

    

移除上面第八行後就會看到正常大小的黃色小正方形:

kotlin 具名參數(Named arguments)

kotlin 支援具名參數(Named arguments),所以在呼叫時順序不變的情況下以下兩個語法是相同的:
	
Modifier.size(100.dp, 100.dp)
Modifier.size(width = 100.dp, height = 100.dp)
    

為了說明方便,在本篇文章中如果有多個參數時都會盡量以第二種方式做示範,在撰寫時可以自行省略。

常用設定尺寸、長寬

	
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.ui.unit.dp


Modifier.width(100.dp) // 只設定寬
Modifier.height(100.dp) // 只設定高
Modifier.size(size = 100.dp) // 同時設定寬高
Modifier.size(width = 100.dp, height = 100.dp) // 分別設定寬高

Modifier.fillMaxWidth() // 填滿寬度
Modifier.fillMaxHeight() // 填滿高度
Modifier.fillMaxSize() // 填滿高度
    

間距(padding)

	
import androidx.compose.foundation.layout.padding
import androidx.compose.ui.unit.dp


Modifier.padding(10.dp) // 四邊都加上 10dp 的間距

// 設定左側、上方、右側、下方的間距
Modifier.padding(start = 10.dp, top = 20.dp, end = 30.dp, bottom = 40.dp) 
    

註: 要先設定 padding 再設定 size ,不然會被覆蓋

邊框(border)

	
import androidx.compose.foundation.border
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.CutCornerShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp


// 設定邊框
Modifier.border(width = 5.dp, color = Color.Red) 

// 設定圓角邊框
Modifier.border(width = 5.dp, color = Color.Red, shape = RoundedCornerShape(20.dp))

// 設定切角邊框
Modifier.border(width = 5.dp, color = Color.Red, shape = CutCornerShape(20.dp))

// 設定圓形邊框
Modifier.border(width = 5.dp, color = Color.Red, shape = CircleShape)
    

Modifier 設定時是有順序,先設定間距(padding)再設定邊框(border)和兩個順序相反會有不同的效果:


上方內容分別是:
(左) 先 邊框(border) 再 間距(padding)
(中) 先 間距(padding) 再 邊框(border)
(右) 先 間距(padding) 再 邊框(border) 再加上等等要介紹的 裁切(clip)
	

Column {

    // 無邊框
    Row() {
        Box(
            modifier = Modifier
                .padding(10.dp)
                .size(size = 100.dp)
                .background(Color.Yellow)
        )
    }

    // 方形
    Row() {
        Box(
            modifier = Modifier
                .border(width = 5.dp, color = Color.Red) // 設定邊框
                .padding(10.dp)
                .size(size = 100.dp)
                .background(Color.Yellow)
        )
        Box(
            modifier = Modifier
                .padding(10.dp)
                .border(width = 5.dp, color = Color.Red) // 設定邊框
                .size(size = 100.dp)
                .background(Color.Yellow)
        )
    }

    // 圓角
    Row() {
        Box(
            modifier = Modifier
                .border(width = 5.dp, color = Color.Red, shape = RoundedCornerShape(20.dp)) // 設定圓角邊框
                .padding(10.dp)
                .background(Color.Yellow)
                // 設定邊框
                .size(size = 100.dp)
        )
        Box(
            modifier = Modifier
                .padding(10.dp)
                .border(width = 5.dp, color = Color.Red, shape = RoundedCornerShape(20.dp)) // 設定圓角邊框
                .background(Color.Yellow)
                // 設定邊框
                .size(size = 100.dp)
        )
        Box(
            modifier = Modifier
                .padding(10.dp)
                .border(width = 5.dp, color = Color.Red, shape = RoundedCornerShape(20.dp)) // 設定圓角邊框
                .clip(RoundedCornerShape(20.dp)) // 裁切成圓角
                .background(Color.Yellow)
                // 設定邊框
                .size(size = 100.dp)
        )
    };
    // 切角
    Row() {
        Box(
            modifier = Modifier
                .border(width = 5.dp, color = Color.Red, shape = CutCornerShape(20.dp)) // 設定切角邊框
                .padding(10.dp)
                .background(Color.Yellow)
                // 設定邊框
                .size(size = 100.dp)
        )
        Box(
            modifier = Modifier
                .padding(10.dp)
                .border(width = 5.dp, color = Color.Red, shape = CutCornerShape(20.dp)) // 設定切角邊框
                .background(Color.Yellow)
                // 設定邊框
                .size(size = 100.dp)
        )
        Box(
            modifier = Modifier
                .padding(10.dp)
                .border(width = 5.dp, color = Color.Red, shape = CutCornerShape(20.dp)) // 設定切角邊框
                .clip(CutCornerShape(20.dp)) // 裁切成切角
                .background(Color.Yellow)
                // 設定邊框
                .size(size = 100.dp)
        )
    }

    // 圓形
    Row() {
        Box(
            modifier = Modifier
                .border(width = 5.dp, color = Color.Red, shape = CircleShape) // 設定圓形邊框
                .padding(10.dp)
                .background(Color.Yellow)
                // 設定邊框
                .size(size = 100.dp)
        )
        Box(
            modifier = Modifier
                .padding(10.dp)
                .border(width = 5.dp, color = Color.Red, shape = CircleShape) // 設定圓形邊框
                .background(Color.Yellow)
                // 設定邊框
                .size(size = 100.dp)
        )
        Box(
            modifier = Modifier
                .padding(10.dp)
                .border(width = 5.dp, color = Color.Red, shape = CircleShape) // 設定圓形邊框
                .clip(CircleShape) // 裁切成圓形
                .background(Color.Yellow)
                // 設定邊框
                .size(size = 100.dp)
        )
    }
}
    

裁切(clip)

效果可以看上面的圖片,這裡再列出一次常見的使用方式
	

import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.shape.CutCornerShape
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.unit.dp


Modifier.clip(shape = CircleShape) // 裁切成圓形
Modifier.clip(shape = RoundedCornerShape(20.dp)) // 裁切切角
Modifier.clip(shape = CutCornerShape(20.dp)) // 裁切圓角
    



參考資料:
Android developers - Compose 版面配置基本概念
Android developers - Compose 修飾符清單
Kotlin - Functions #Named arguments

留言