Compose については、前回の記事「Jetpack Compose テクノロジのクイック スタート」で簡単に紹介しましたので、ここでは Compose のレイアウトについて学びます。レイアウトにはさらに多くの内容が含まれるため、別で記述します。
レイアウトには主に、レイアウトの基本、マテリアル コンポーネントとレイアウト、カスタム レイアウト、Compose での ConstraintLayout の使用が含まれます。
カスタム レイアウトに関連する知識ポイント:
Compose レイアウトのプロセス
Compose では、インターフェイス要素はコンポーズ可能な関数によって表され、呼び出された後にインターフェイスの一部が出力され、インターフェイスのこの部分が画面上のインターフェイス ツリーに追加されて表示されます。すべてのインターフェイス要素には親要素があり、場合によっては複数の子要素があります。さらに、各要素には、(x, y) 位置として指定される親要素内の位置と、幅と高さとして指定されるサイズがあります。
親要素は、その子要素に対する制約を定義します。要素はこれらの制約内で寸法を定義する必要があります。制約は、要素の幅と高さの最小値と最大値を制限します。要素に子がある場合、そのサイズを決定するために各子を測定することがあります。要素が独自の寸法を決定して報告すると、要素自体に対して子をどのように配置するかを定義できるようになります。
インターフェイス ツリー内の各ノードを配置するプロセスは、次の 3 つのステップに分かれています。
1.测量所有子项
2.确定自己的尺寸
3.放置其子项
★注意:Compose 界面不允许多遍测量。这意味着,布局元素不能为了尝试不同的测量配置而多次测量任何子元素。
拡張レイアウト修飾子 レイアウトは修飾子
を使用して、要素の計測方法とレイアウト方法を変更します。layout
レイアウトはラムダであり、そのパラメーターには、測定できる要素 (測定可能として渡される) と、そのコンポーザブルの受信制約 (制約として渡される) が含まれます。カスタム レイアウト修飾子は次のようになります。
fun Modifier.customLayoutModifier(...) =
this.layout { measurable, constraints ->
...
})
先頭のパディングを例に挙げるとText
、このような要件がある場合は、次の図に示すように、テキストの最初の行のベースラインを参照してパディングを設定します。コードは次のとおりです
文字位置Y = 设置高度 - 文字高度
。
/**
* 1.自定义布局修饰符-修改文字基线距离顶部距离
*/
fun Modifier.firstBaselineToTop(firstBaselineToTop: Dp)=layout { measurable, constraints ->
//先测量
val placeable = measurable.measure(constraints)
check(placeable[FirstBaseline] != AlignmentLine.Unspecified)
val firstBaseLine = placeable[FirstBaseline]
//文字位置Y
val placeableY = firstBaselineToTop.roundToPx() - firstBaseLine
val height = placeable.height + placeableY
//重新布局
layout(placeable.width,height){
placeable.placeRelative(0,placeableY)
}
}
次の図に示すように、最終的なエフェクトがパディング エフェクトと比較されます。
カスタム レイアウトの作成 レイアウト
Android View システムでレイアウトをカスタマイズしたい場合は、ViewGroup を継承し、測定およびレイアウト関数を実装する必要がありますが、Compose でのレイアウトのカスタマイズははるかに簡単で、コンポーザブル アイテムを直接使用して実現できます。Layout
手動でのLayout
測定と子レイアウトを可能にします。から構築されていColumn
ます。ここではカスタム修飾子との違いに注意してください。例として垂直レイアウトをカスタマイズしてみましょう (同様)。コードは次のとおりです。Row
Layout
layout
Column
/**
* 2.自定义Layout实现组件垂直布局
*/
@Composable
fun MyBasicColumn(
modifier: Modifier = Modifier,
content:@Composable ()->Unit
){
//步骤一:
//其中measurables,constraints为Layout最后一个参数的lambda写法
Layout(content = content, modifier = modifier){ measurables,constraints ->
//步骤二:通过给点的约束条件constraints对组件进行测量
val placeables = measurables.map {
it.measure(constraints)
}
//获取所有元素的高度总和
val wrapHeight = placeables.sumOf {
it.height
}
//步骤三:布局,设置可允许的布局大小
layout(constraints.maxWidth,wrapHeight){
var yPosition = 0
//步骤四:设置每个组件的位置
placeables.forEach {placeable->
//设置组件的x,y坐标
placeable.placeRelative(x = 0,y=yPosition)
//计算下一个组件的y坐标
yPosition += placeable.height
}
}
}
}
注目に値します: modifierLayout
と似ていますが、最初の引数は測定する必要がある子のリストであり、constraints は親からの制約です。効果の例は次のとおりです。layout
measurables
また、滝の流れのレイアウトはここでカスタマイズされていますので、興味があればご覧ください。
レンダリング:
レイアウトの方向 レイアウト
の方向を変更する必要がある場合は、LocalLayoutDirection
実装を使用できます。変更されたレイアウト方向がサポートされています: Ltr(由左到右)
、Rtl(由右到左)
。
例えば:
/**
* 3.布局方向
*/
@Composable
fun ChangeColumnDirection(){
CompositionLocalProvider(LocalLayoutDirection provides LayoutDirection.Rtl ) {
Column(Modifier.fillMaxWidth()) {
Text("Title")
Text("Subtitle")
}
}
}
効果の例:
ここではカスタム レイアウトを紹介しますが、その内容は比較的少ないです。