boxshadowというか要素の重なりというか、下の画像のような装飾を実現したくいろいろ試した。これがベストには思えないが、一応それっぽいものができたのでメモっておく。
コード
構造だけ抜き出すと下のようになる。
・Box(Parent)
・Box(Back)
・Box(Front / Main )
・Content
Box(
Modifier
.fillMaxWidth()
.height(IntrinsicSize.Max)
) {
// このボックスが後ろ側
Box(
Modifier
.fillMaxSize()
.padding(top = 4.dp, start = 4.dp)
.border(
width = Border,
color = Color.Black,
)
.background(Color.White)
)
//でこっちが前側
Box(
modifier = Modifier
.fillMaxSize()
.padding(bottom = 10.dp, end = 10.dp)
.border(
width = Border,
color = Color.Black,
)
){
Column(
Modifier
.background(Color.White)
.fillMaxSize()) {
Text(text = "Main Contents")
Text(text = "Main Contents")
Text(text = "Main Contents")
}
}
}
詰まった点
子の高さを親いっぱいにする(子要素の中で一番高さのある要素Aに他の子の高さも合わせる)ので詰まった。
親に .height(IntrinsicSize.Max) を当てて子には.fillMaxHeight() (下のコードではfillMaxSizeを使っている)を指定することでうまくいった。
テンプレート化して再利用する
枠だけテンプレート化して使いまわし、内部は個々別々の内容にしたい。Slot機能があるのでそれを利用する。
テンプレート側のコード。
ほとんど同じだけど
@Composable
fun Template(
content: @Composable () -> Unit = {}
) {
Box(
Modifier
.fillMaxWidth()
.height(IntrinsicSize.Max)
) {
// このボックスが後ろ側のボーダーになる
Box(
Modifier
.fillMaxSize()
.padding(top = 10.dp, start = 6.dp)
.border(
width = Border,
color = Color.Black,
// shape = RoundedCornerShape(Shape)
)
.background(Color.White)
)
Box(
modifier = Modifier
// .align(Alignment.TopStart)
.fillMaxSize()
.padding(bottom = 10.dp, end = 10.dp)
.border(
width = Border,
color = Color.Black,
// shape = RoundedCornerShape(Shape)
)
) {
Column(
Modifier
.background(Color.White)
.fillMaxSize()
) {
// ここに渡されたcontentが収まる
content()
}
}
}
}
呼び出す際はこんな感じ
Template() {
Column() {
Text(text = "this is slotted text")
Text(text = "this is slotted text")
Text(text = "this is slotted text")
Text(text = "this is slotted text")
}
}
結果はこう。
参考
https://developer.android.com/jetpack/compose/layout
https://stackoverflow.com/questions/70984692/set-height-of-child-elements-equal-to-highest-other-element-that-are-contained-b
コメント