detekt に指摘されながら、ドキュメントを読む。
【detekt / ktlint】元 Twitter 管理者 @mrmans0n らによって Jetpack Compose Rules フォークが進化している件 #プログラミング #kmmhttps://t.co/ToXFLbyXcR
— chanzmao (@maochanz) October 23, 2023
こんなコードがあったとして。
Column {
InnerContent()
}
@Composable
private fun InnerContent() {
Text(...)
Image(...)
Button(...)
}
以下、知らなかった流儀。
🧩 Composable 関数はレイアウトを一つだけ出力する
A composable function should emit either 0 or 1 pieces of layout, but no more. A composable function should be cohesive, and not rely on what function it is called from.
コンポーザブル関数は、レイアウトのピースを0個または1個だけ発行するべきで、それ以上は発行してはいけません。コンポーザブル関数は結束性を持ち、呼び出される関数に依存すべきではありません。
レイアウトのネストのコストはあまり気にしなくて良い、とのこと。
Nesting of layouts has a drastically lower cost vs the view system, so developers should not try to minimize UI layers at the cost of correctness.
レイアウトのネストには、ビューシステムに比べてはるかに低いコストがかかるため、UIの階層を正確性の犠牲にして最小化しようとしないべきです。
👉 Do not emit multiple pieces of content - Twitter Jetpack Compose Rules
ということで、一見不要に見える Column を追加する。
@Composable
private fun InnerContent() {
Column {
Text(...)
Image(...)
Button(...)
}
}
🧩 デフォルトを持つパラメータ modifier: Nodifier = Modifier は必須
They are especially important for your public components, as they allow callers to customize the component to their wishes.
特に、公開コンポーネントにとって Modifier は非常に重要であり、呼び出し元がコンポーネントを希望に合わせてカスタマイズできるようにします。
👉 When should I expose modifier parameters? - Jetpack Compose Rules
Composables that accept a Modifier as a parameter to be applied to the whole component represented by the composable function should name the parameter modifier and assign the parameter a default value of Modifier.
Composable 関数内でコンポーザブル関数を表すコンポーネント全体に適用するための修飾子をパラメータとして受け入れる場合、そのパラメータは "modifier" という名前を付け、パラメータに Modifier のデフォルト値を割り当てるべきです。
👉 Modifiers should have default parameters - Jetpack Compose Rules
ということで、親からの Modifier を受け入れるようにします。デフォルト値もつけておきます。
@Composable
private fun InnerContent(modifier: Modifier = Modifier) {
Column {
Text(...)
Image(...)
Button(...)
}
}
🧩 受け取った Modifier パラメータは最上位のレイアウトにのみ適用する
Modifiers should be applied once as a first modifier in the chain to the root-most layout in the component implementation. Since modifiers aim to modify the external behaviors and appearance of the component, they must be applied to the top-most layout and be the first modifiers in the hierarchy. It is allowed to chain other modifiers to the modifier passed as a param if needed.
Modifier は、コンポーネントの実装内でルートのレイアウトに最初の Modifier として一度適用すべきです。Modifier はコンポーネントの外部の動作や外観を変更することを目的としているため、最上位のレイアウトに適用し、階層内で最初の Modifier である必要があります。必要に応じて、パラメータとして渡された Modifier に他の Modifier を連鎖させることは許可されています。
👉 Modifiers should be used at the top-most layout of the component - Jetpack Compose Rules
ということで、最上位ルートの Column で適用します。
@Composable
private fun InnerContent(modifier: Modifier = Modifier) {
Column(modifier = modifier) {
Text(...)
Image(...)
Button(...)
}
}
🧩 まとめ
@Composable 内のレイアウトに関する Modifier は、親 (呼び出し元) から持ってきて、最上位のレイアウトで一度だけ適用する。
detekt を使うことで、なんとなく記述していた部分がスッキリしてきます。