박스는 겹칠수 있습니다.
(기존 relative layout, constriant layout, framelayout 과 같이 뷰 겹치기가 가능합니다.)
아래로 내려갈수록 위에 뷰를 올리는 방식입니다.
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Surface
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.dong.study.ui.theme.MyComposeStudyTheme
import java.util.*
class BoxActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent {
MyComposeStudyTheme {
// A surface container using the 'background' color from the theme
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colors.background
) {
Container()
}
}
}
}
}
@Composable
fun Container(){
Box(
modifier = Modifier
.background(Color.White)
.fillMaxSize()
, contentAlignment = Alignment.CenterEnd
// , propagateMinConstraints = true // 가장 작은 box를 현재 Box()에 꽉 채움
) {
BoxContainer(modifier = Modifier.size(200.dp), color = Color.Blue)
BoxContainer(modifier = Modifier.size(150.dp), color = Color.Cyan)
BoxContainer(color = Color.Green)
}
}
@Composable
fun BoxContainer(modifier: Modifier = Modifier, color : Color? = null){
val random = Random()
val red = random.nextInt(256)
val green = random.nextInt(256)
val blue = random.nextInt(256)
// color가 값이 있으면 넣어주고 없으면 random color를 넣기
val randomColor = color?.let{ it } ?: Color(red, green, blue)
Box(modifier = modifier
.size(100.dp)
.background(randomColor))
}
@Preview(showBackground = true)
@Composable
fun BoxActivityPreview() {
MyComposeStudyTheme {
Container()
}
}
fillMaxSize()
를 지정했기 때문에 이 컨테이너가 화면의 전체를 차지 합니다.BoxWihtConstraints는 Box Layout의 SuperSet Layout으로 Box의 기능을 모두 포함하면서 Layout의 Constraint에 접근할 수 있도록 만들어진 Layout입니다.
총 5가지 변수에 접근할 수 있습니다.
이 변수들을 통해 해당 BoxWithConstraints의 Width와 Height에 접근할 수 있습니다.
이 변수들을 통해 BoxWithConstraints에 넓이, 높이에 min, max값을 지정하고, 내부 요소들의 크기에 따라 BoxWithConstraints의 크기가 min, max 범위 내에서 결정되도록 할 수 있습니다.
또는 요소들의 사이즈에 따라 어느 사이즈 이상일때 BoxWithConstriants에 넣거나 뺴도록 구현할 수 있습니다.
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.dong.study.ui.theme.MyComposeStudyTheme
import java.util.*
class BoxWithConstraintsActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContent{
MyComposeStudyTheme{
// A surface container using the 'background' color from the theme
Surface(
modifier = Modifier.fillMaxSize(),
color = MaterialTheme.colorScheme.background
){
BWCContainer()
}
}
}
}
}
@Composable
fun BWCContainer(){
BoxWithConstraints(
modifier = Modifier
.background(Color.White)
.fillMaxSize()
, contentAlignment = Alignment.Center
){
Column(){
BoxWithConstraintItem(modifier = Modifier
.size(200.dp)
.background(Color.Red)
)
BoxWithConstraintItem(modifier = Modifier
.size(300.dp)
.background(Color.Blue)
)
}
}
}
@Composable
fun BoxWithConstraintItem(modifier: Modifier = Modifier){
BoxWithConstraints(
modifier = modifier,
contentAlignment = Alignment.Center,
propagateMinConstraints = false
){
if (this.minWidth > 200.dp) {
Text(text = "Big Box")
} else {
Text(text = "Small Box")
}
}
}
@Preview(showBackground = true)
@Composable
fun BWCActivityPreview() {
MyComposeStudyTheme{
BWCContainer()
}
}
Box(modifier = Modifier.size(100.dp)) {
// text의 modifier는 BoxScope 안에서만 사용 가능
Text(text = "Hello World", modifier = Modifier.align(Alignment.BottomStart))
Text(text = "Hello World", modifier = Modifier.align(Alignment.CenterEnd))
Text(text = "Hello World", modifier = Modifier.align(Alignment.TopCenter))
}
Box(modifier = Modifier.size(100.dp)) {
Box(modifier = Modifier.fillMaxSize().background(Color.Green).align(Alignment.CenterStart))
Box(modifier = Modifier.size(50.dp).background(Color.Blue).align(Alignment.BottomStart))
}
주의!!
fillMaxSize()가 아닌 matchParentSize()를 사용하면 밖깥 Box가 Modifier.size(50.dp).background(Color.Blue).align(Alignment.BottomStart)) 이 Box를 기준으로 영역을 잡는다.
그러므로 fillMaxSize()를 사용하여 해당 박스가 자신의 부모 박스를 꽉 차게 할 수 있다.