Jetpack Compose布局(一) - 布局基礎知識

在上篇《Jetpack Compose技術快速上手》一文中簡單介紹了Compose,那么這邊我們就來學習下Compose的布局。由于布局這塊涉及內容較多,會分開寫。
布局主要包括:布局基礎知識、Material組件和布局自定義布局Compose中使用ConstraintLayout

image.png

本文重點講解布局基礎知識
主要涉及:可組合函數、標準布局元素、基本組件、布局模型、修飾符、槽位布局。如下圖:

本文涉及主要知識點

可組合函數

可組合函數是 Compose 的基本構建塊,返回值是 Unit 的函數,用于描述界面中的某一部分,該函數可接收參數。
組合函數中可包含多個界面元素。
其基本格式為:

@Composable
fun xxx():Unit{
....
}

標準布局元素

在Compose中標準的布局元素有三個:BoxColumnRow

標準布局元素特性示意圖

Box
重疊布局,類似Android View系統(tǒng)中的FramLayout布局,元素會重疊顯示,其原型定義如下:

@Composable
inline fun Box(
    modifier: Modifier = Modifier,                   //修飾符
    contentAlignment: Alignment = Alignment.TopStart,//內容的位置
    propagateMinConstraints: Boolean = false,       //是否應將傳入的最小約束傳遞給內容
    content: @Composable BoxScope.() -> Unit    //內容,即界面元素
) {
    ......
}

例子

/**
 * 標準布局 - Box
 */
@Composable
fun BoxExample(){
    Box (
        modifier = Modifier.size(width = 230.dp,height = 100.dp),
        contentAlignment = Alignment.Center
    ){  //對應content參數 lambda表達上
        Text(text = "Text 1")
        Text(text = "Text 2")
    }
}
預覽結果

Column
垂直布局,在界面元素垂直方向依次排列。源碼中定義如下:

@Composable
inline fun Column(
    modifier: Modifier = Modifier,          //修飾符
    verticalArrangement: Arrangement.Vertical = Arrangement.Top,  //內容元素垂直方向分布方式
    horizontalAlignment: Alignment.Horizontal = Alignment.Start,    //內容元素水平方向分布方式
    content: @Composable ColumnScope.() -> Unit                      //內部元素
) {
    ......
}

實例

/**
 * 標準布局 - Column
 */
@Composable
fun ColumnExample(){
    Column (
        modifier = Modifier.size(width = 230.dp,height = 100.dp),
        verticalArrangement = Arrangement.Center,//垂直方向居中
        horizontalAlignment = Alignment.End      //水平方向靠右
    ){  //對應content參數 lambda表達上
        Text(text = "Text 111")
        Text(text = "Text 666666")
    }
}
Column示例預覽結果

Row
元素水平方向分布,源碼中定義:

@Composable
inline fun Row(
    modifier: Modifier = Modifier,          //修飾符
    horizontalArrangement: Arrangement.Horizontal = Arrangement.Start,//水平方向排列方式
    verticalAlignment: Alignment.Vertical = Alignment.Top,      //垂直方向元素排列方式
    content: @Composable RowScope.() -> Unit          //內部子元素
) {
    ......
}

示例

/**
 * 標準布局 - Row
 */
@Composable
fun RowExample(){
    Row (
        modifier = Modifier.size(width = 230.dp,height = 100.dp),
        horizontalArrangement = Arrangement.SpaceAround,
        verticalAlignment = Alignment.Bottom
    ){  //對應content參數 lambda表達上
        Text(text = "Text 111")
        Text(text = "Text 666666")
    }
}
Row示例預覽

基本組件

Jetpack Compose中組件庫包括:compose-ui和material。很多常用基本組件都是在material庫中,Compose-ui中組件很少:Image、BasicTextField(輸入框)。
示例:

//添加一個圖片
Image(
      //填充內容
      painter = painterResource(id = message.iconId),
      contentDescription = "logo",
      //尺寸及形狀
      modifier= Modifier
          .padding(top = 2.dp)
          .size(40.dp)             //圖像尺寸
          .clip(CircleShape)       //形狀
          .border(1.5.dp, MaterialTheme.colors.secondary, CircleShape)//邊框樣式
  )

布局模型

在對標準布局元素和組件有了一定了解后,我們來看下Compose的布局流程。
首先Compose布局是一個界面樹,從樹的根節(jié)點開始依次要求其子節(jié)點對自身進行測量,然后遞歸完成所有子節(jié)點的測量,并將約束條件沿著樹向下傳遞給子節(jié)點,并將測量的尺寸和放置指令依次向根節(jié)點傳遞。

以下面可組合函數為示例:

@Composable
fun SearchResult(...) {
  Row(...) {
    Image(...)
    Column(...) {
      Text(...)
      Text(..)
    }
  }
}

其布局過程如下圖示:


image.png

修飾符

在Compose布局中修飾符至關重要,您可以使用修飾符來修飾或擴充可組合項。常用的修飾符如下:

  • background 可組合元素的背景色;
  • clickable 使可組合項響應用戶點擊,并顯示波紋效果;
  • padding 設置元素周圍留出空間;
  • size 可組合元素的尺寸;
  • clip 可組合元素的形狀;
  • border 可組合元素的邊框及形狀;
  • fillMaxSize可組合元素尺寸按父布局的最大尺寸顯示;
  • fillMaxWidth 可組合元素寬度按父布局的最大寬度顯示;
  • fillMaxHeight 可組合元素高度按父布局的最大高度顯示;
    除以上外,還有widthheightwrapConentHeight等,用到的時候可以嘗試看看效果。
    下面展示一個圓形圖像的示例
/**
 * 修飾符使用示例
 */
@Composable
fun ModifierExample(){
    //添加一個圖片
    Image(
        //填充內容
        painter = painterResource(id = R.mipmap.ic_girl),
        contentDescription = "logo",
        //尺寸及形狀
        modifier= Modifier
            .padding(top = 2.dp)
            .background(Color.Blue)//設置藍色背景
            .size(40.dp)             //圖像尺寸
            .clip(CircleShape)       //圓形形狀
            .border(1.5.dp, MaterialTheme.colors.secondary, CircleShape)//邊框樣式
    )
}

效果如下:
修飾符示例

修飾符擴展
除了使用Compose提供的修飾符外,我們也可以擴展函數自定義修飾符,具體方式可以參考Jetpack Compose布局(三)一文中講的擴展布局修飾符

強調:修飾符的使用是有順序的
強調:修飾符的使用是有順序的
強調:修飾符的使用是有順序的
例如,將上例的background和padding順序調換下,就會如下圖效果,仔細看兩圖的頂部邊距,會發(fā)現區(qū)別

調換background和padding順序的效果圖

槽位布局

Compose中提供了固定槽位的可組合項,以簡化界面元素,這些主要在androidx.compose.material:material庫中,如:DrawerFloatingActionButtonTopAppBar等。
Material 組件大量使用槽位 API,這是 Compose 引入的一種模式,它在可組合項之上帶來一層自定義設置。這種方法使組件變得更加靈活,因為它們接受可以自行配置的子元素,而不必公開子元素的每個配置參數。槽位會在界面中留出空白區(qū)域,讓開發(fā)者按照自己的意愿來填充。如下圖TopAppBar的槽位。

TopAppBar的槽位

關于槽位內容會在Jetpack Compose布局(二)中做詳細講解,本篇就不進行深入討論了。

歡迎留言,一起學習,共同進步!

github - 示例源碼
gitee - 示例源碼

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,786評論 6 534
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現死者居然都...
    沈念sama閱讀 98,656評論 3 419
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,697評論 0 379
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,098評論 1 314
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,855評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,254評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,322評論 3 442
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,473評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發(fā)現了一具尸體,經...
    沈念sama閱讀 49,014評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,833評論 3 355
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,016評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,568評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,273評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,680評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,946評論 1 288
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,730評論 3 393
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,006評論 2 374

推薦閱讀更多精彩內容