Jetpack Compose - ConstraintLayout

樂翁龍發表於2020-12-22

Compose系列文章,請點原文閱讀。原文:是時候學習Compose了!

0、介紹

在xml的時代我們已經瞭解過了ConstraintLayout的強大功能,比例、相對位置、引導線、屏障、鏈條等讓我們開發頁面佈局可以大展身手。那麼在Compose的時代,ConstraintLayout是如何使用的呢?首先官方給它的介紹很簡單:

根據子項之間的約束,定位子項的佈局。

但是實際用法上有了很多的差異,接下來一起研究下吧。

1、屬性一覽

【目前基於alpha08版本的屬性】首先請看它的兩個函式:

@Composable fun ConstraintLayout(
    modifier: Modifier = Modifier, 
    content: ConstraintLayoutScope.() -> Unit
): Unit
@Composable fun ConstraintLayout(
    constraintSet: ConstraintSet, 
    modifier: Modifier = Modifier, 
    content: () -> Unit
): Unit

屬性引數含義:

引數含義
modifier: Modifier = Modifier應用於佈局的修飾符
【1】content: ConstraintLayoutScope.() -> Unit子級內容,可以很方便的建立 約束佈局參照物
【2】constraintSet: ConstraintSet,對於子級約束相關描述
【2】content: () -> Unit使用ConstraintSet引數而定義的子級內容

2、使用示例

我們先從一些基本概念說起:

2.0、ID

到目前為止我們並沒有見到過Compose類似xml中那種給控制元件命名id的形式,那既然Compose是約束佈局,必須要有個控制元件的編號或者ID,才能實現各種約束條件,那麼這個編號其實也就相當於ID。 目前在ConstraintLayout中有兩種方式來建立這種編號的方式:

  • Modifier.constrainAs()和createRef()、createRefs()
  • Modifier.layoutId()和createRefFor()

在Compose的ConstraintLayout中我們可以通過createRef()或者createRefs()來建立一個或者多個編號。然後某一個控制元件使用其修飾符的constrainAs來應用該編號。如下程式碼,我們使用解構的方法建立了兩個ID,分別為box1和box2,然後建立了一個Box佈局並應用了編號 box1,然後在box1的約束條件中我們規定了,box1的end需要連結到box2。

val (box1, box2) = createRefs()

//ID為box1的Box佈局
Box(
    modifier = Modifier.fillMaxSize()
        .background(color = Color.Yellow)
        .constrainAs(box1) {
            end.linkTo(box2)
        }
)

建立參照物(ID)的基本用法就是這樣,下面我們再針對具體場景進行講解。

2.1、Guideline

引導線,可以從特定的位置(某一方向上的偏移量或者某一方向上的比例)建立一條實際並不可見的參考線。總共有如下幾種方式:

  • createGuidelineFromStart(offset: Dp)
  • createGuidelineFromAbsoluteLeft(offset: Dp)
  • createGuidelineFromStart(fraction: Float)
  • createGuidelineFromAbsoluteLeft(fraction: Float)
  • createGuidelineFromEnd(offset: Dp)
  • createGuidelineFromAbsoluteRight(offset: Dp)
  • createGuidelineFromEnd(fraction: Float)
  • createGuidelineFromAbsoluteRight(fraction: Float)
  • createGuidelineFromTop(offset: Dp)
  • createGuidelineFromTop(fraction: Float)
  • createGuidelineFromBottom(offset: Dp)
  • createGuidelineFromBottom(fraction: Float)

別被這麼多方法嚇到,其實就是從上、下、左、右四個方向,分別支援某一偏移量,或者某一比例進行建立引導線。而帶有Absolute的表示絕對的左右方向,這裡其實就是國際化的問題。

如下程式碼:


@Composable
fun ConstraintLayoutDemo() {
    ConstraintLayout(
        modifier = Modifier.fillMaxSize()
    ) {

        val guideline = createGuidelineFromStart(0.2f)
        val (box1, box2) = createRefs()

        Box(
            modifier = Modifier.fillMaxSize()
                .background(color = Color.Yellow)
                .constrainAs(box1) {
                    end.linkTo(guideline)
                }
        )

        Box(
            modifier = Modifier.fillMaxSize()
                .background(color = Color.Red)
                .constrainAs(box2) {
                    start.linkTo(guideline)
                }
        )
}

首先ConstraintLayout是一個填充全螢幕的佈局,然後在該佈局中從開始(左側)的百分之20的位置,建立一條豎向引導線。
然後建立了兩個Box佈局,分別是結束部分連結到引導線,開始部分連結到引導線。所以部分效果如下所示:
在這裡插入圖片描述

2.2、Barrier

待續

2.3、Chain

待續

3、版本更新

待續

4、未解決問題

待續

相關文章