Android(kotlin) - JetPack Compose - Box, BoxWithConstraints

하동혁 ·2023년 7월 13일
1

Android Jetpack Compose

목록 보기
6/30
post-thumbnail
post-custom-banner

Box

박스는 겹칠수 있습니다.
(기존 relative layout, constriant layout, framelayout 과 같이 뷰 겹치기가 가능합니다.)
아래로 내려갈수록 위에 뷰를 올리는 방식입니다.

  • alignment는 row, column 보다 다양하게 지원
  • Alignment.BottomCenter : 컨테이너의 중앙 아래
  • Alignment.BottomEnd : 컨테이너의 아래 오른쪽
  • Alignment.BottomStart : 컨테이너의 아래 왼쪽
  • Alignment.Center : 컨테이너의 정중앙
  • Alignment.CenterStart : 컨테이너의 중앙 왼쪽
  • Alignment.CenterEnd : 컨테이너의 중앙 오른쪽
  • Alignment.TopCenter : 컨테이너의 위 중앙
  • Alignment.TopEnd : 컨테이너의 위 오른쪽
  • Alignment.TopStart : 컨테이너의 위 왼쪽

Box 실습

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()
    }
}

  • Container의 속성으로 fillMaxSize()를 지정했기 때문에 이 컨테이너가 화면의 전체를 차지 합니다.



BoxWithConstraints

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()를 사용하여 해당 박스가 자신의 부모 박스를 꽉 차게 할 수 있다.

post-custom-banner

0개의 댓글