티스토리 뷰
기존 xml 방식에서도 많이 사용되었던 ConstraintLayout 사용 방법입니다.
1) 라이브러리 설치
implementation "androidx.constraintlayout:constraintlayout-compose:1.0.1"
Constraintlayout | Android 개발자 | Android Developers
컬렉션을 사용해 정리하기 내 환경설정을 기준으로 콘텐츠를 저장하고 분류하세요. Constraintlayout 상대 위치에 따라 유연한 방식으로 위젯의 위치와 크기를 지정합니다. 이 표는 androidx.constraintlay
developer.android.com
최신 버전은 위의 링크를 확인해 주세요
2) 기본 사용 방법
ConstraintLayout(
modifier = Modifier.fillMaxSize()
) {
val button1 = createRef()
val (button2, text1) = createRefs()
Button(
onClick = {},
modifier = Modifier.constrainAs(button1) {
}
) {
Text(text = "button1")
}
Button(
onClick = {},
modifier = Modifier.constrainAs(button2) {
}
) {
Text(text = "button2")
}
Text(
text = "text1",
modifier = Modifier.constrainAs(text1) {
}
)
}
xml과 가장 큰 차이점은 3~4 라인의 코드입니다.
xml에서 사용했던 id들을 변수에다가 미리 정의를 하는 코드입니다.
한 개만 등록할 시에는 createRef()를, 여러 개 동시에 등록할 때에는 소괄호 안에 넣고 createRefs()를 해주면 됩니다.
단 변수 생성 시 ConstraintLayout 안에서 생성해 주어야 합니다.
제약조건을 넣을 때에는 Modier.constraintAs() 안에 위에서 만든 id를 넣어주면 됩니다.
Button(
onClick = {},
modifier = Modifier.constrainAs(button1) {
top.linkTo(parent.top)
start.linkTo(parent.start)
end.linkTo(parent.end)
}
) {
Text(text = "button1")
}
Button(
onClick = {},
modifier = Modifier.constrainAs(button2) {
top.linkTo(button1.bottom, 10.dp)
start.linkTo(parent.start, 20.dp)
}
) {
Text(text = "button2")
}
Text(
text = "text1",
modifier = Modifier.constrainAs(text1) {
}
)
제약조건을 추가할 때에는 다음의 조건에 따라 넣어주면 됩니다.
[해당 Composable의 지정하고 싶은 위치 ex) top].linkTo([제약 조건], [Margin], [GoneMargin])
ConstrintLayout을 사용해 본 경험이 있으시면 쉽게 파악이 가능할 겁니다.
3) 크기 지정
val line = createGuidelineFromStart(fraction = 0.5f)
Box(modifier = Modifier
.background(Color(0xFF1DE9B6))
.constrainAs(box) {
start.linkTo(line)
end.linkTo(parent.end)
top.linkTo(parent.top)
bottom.linkTo(parent.bottom)
height = Dimension.fillToConstraints
width = Dimension.fillToConstraints
}
)
Text(
text = "text1 Lorem Ipsum is simply dummy text of the printing and typesetting industry.",
color = Color.Red,
modifier = Modifier
.background(Color.Black)
.constrainAs(text1) {
top.linkTo(parent.top)
start.linkTo(line)
end.linkTo(parent.end)
width = Dimension.preferredWrapContent
}
)
Text(
text = "text2 Lorem Ipsum is simply dummy text of the printing and typesetting industry.",
color = Color.Blue,
modifier = Modifier
.background(Color.Black)
.constrainAs(text2) {
top.linkTo(text1.bottom, 10.dp)
start.linkTo(line)
end.linkTo(parent.end)
width = Dimension.wrapContent
}
)
Text(
text = "text3 Lorem Ipsum is simply dummy text of the printing and typesetting industry.",
color = Color.Green,
modifier = Modifier
.background(Color.Black)
.constrainAs(text3) {
top.linkTo(text2.bottom, 10.dp)
start.linkTo(line)
end.linkTo(parent.end)
width = Dimension.fillToConstraints
}
)
Text(
text = "text4 Lorem Ipsum is simply dummy text of the printing and typesetting industry.",
color = Color.White,
modifier = Modifier
.background(Color.Black)
.constrainAs(text4) {
top.linkTo(text3.bottom, 10.dp)
start.linkTo(line)
end.linkTo(parent.end)
width = Dimension.preferredValue(100.dp)
}
)
Text(
text = "text5 Lorem Ipsum is simply dummy text of the printing and typesetting industry.",
color = Color.Yellow,
modifier = Modifier
.background(Color.Black)
.constrainAs(text5) {
top.linkTo(text4.bottom, 10.dp)
start.linkTo(line)
end.linkTo(parent.end)
width = Dimension.value(100.dp)
}
)
우선 가이드라인입니다.
createGuidelineFrom***()로 생성이 가능하며 실제로 앱 화면에 보이지는 않기 때문에 디자인을 편리하게 하기 위해 사용할 수 있습니다.
Box는 눈으로 색상을 줘서 크기가 어느 정도인지 쉽게 보기 위한 것입니다.
ConstraintLayout을 사용하고 값을 아무것도 주지 않으면 with나 height가 Composable의 크기에 맞게만 설정이 됩니다.
그러나 상황에 따라 크기를 지정해 줄 필요가 있는데 그럴 경우 Dimension을 이용하면 됩니다.
순서대로 보면
Dimension.preferredWrapContent
는 제약조건의 크기를 최대값으로 갖고 그 안에서 wrapContent를 해주는 방식입니다.
만약 텍슽트가 짧으면 텍스트의 길이 만큼만 영역을 차지합니다.
Dimension.wrapContent
는 Composable의 자신의 크기에 맞게 설정을 합니다.
위의 예시에서는 텍스트가 디바이스의 넓이만큼 길이를 잡고 다음 줄로 넘어간 것을 확인할 수 있습니다.
그리고 가이드라인과 화면의 끝에 제약을 넣었으므로 가운데 위치하려고 하다 보니 영역을 벗어나게 표시가 됩니다.
Dimension.fillToConstraints
는 제약조건에서 준 영역만큼 자신의 영역을 가지게 설정합니다. 기존 xml에서 0dp 준 것과 동일하다고 보시면 됩니다.
Dimension.preferredValue(100.*dp*)
와 Dimension.value(100.*dp*)
는 제약조건과는 무관하게 크기를 지정할 수 있습니다. 대신 preferredValue는 제약조건의 크기를 최대 크기로 가지게 됩니다.
글로 써서 표현이 애매하긴한데 사용해보시면 쉽게 알 수 있습니다.
4) Chain
ConstraintLayout {
val (text1, text2, text3) = createRefs()
createHorizontalChain(text1, text2, text3, chainStyle = ChainStyle.Spread)
Text(
text = "text1",
modifier = Modifier.constrainAs(text1) {
top.linkTo(parent.top, 20.dp)
}
)
Text(
text = "text2",
modifier = Modifier.constrainAs(text2) {
top.linkTo(text1.top)
}
)
Text(
text = "text3",
modifier = Modifier.constrainAs(text3) {
top.linkTo(text1.top)
}
)
}
createHorizontalChain / createVerticalChin을 통해 Chain을 설정할 수 있습니다.
스타일의 종류는 xml과 동일합니다.
5) ConstraintSet
제약 조건을 Composable 안에서 직접 지정할 수도 있지만 따로 함수로 빼서 작업을 진행할 수도 있습니다.
@Composable
fun ConstraintTest2() {
ConstraintLayout(decoupledConstraints()) {
Box(
modifier = Modifier
.layoutId("box1")
.background(Color(0xFFFF8A80))
)
Box(
modifier = Modifier
.layoutId("box2")
.background(Color(0xFF80D8FF))
)
}
}
private fun decoupledConstraints(): ConstraintSet =
ConstraintSet {
val box1 = createRefFor("box1")
val box2 = createRefFor("box2")
constrain(box1) {
top.linkTo(parent.top)
bottom.linkTo(box2.top)
start.linkTo(parent.start)
end.linkTo(parent.end)
width = Dimension.fillToConstraints
height = Dimension.fillToConstraints
}
constrain(box2) {
top.linkTo(box1.bottom)
bottom.linkTo(parent.bottom)
start.linkTo(parent.start)
end.linkTo(parent.end)
width = Dimension.fillToConstraints
height = Dimension.fillToConstraints
}
}
ConstraintSet에서는 createRefFor를 통해 변수를 생성 할 수 있습니다.
여러 개 동시에 만드는 것은 지원하지 않고 있습니다.
변수 명은 ContraintSet에서 사용하기 위함이고 createRefFor는 ContraintLayout에서 사용할 id입니다.
그 이외에는 동일하게 제약조건을 넣어주면 됩니다.
ConstrintLayout에서는 생성 시 만들어둔 ConstraintSet을 넣어주면 되고,
각 Composable의 Modifier에서 LayoutId를 ConstraintSet에서 설정한 id와 동일하게 넣어주면 됩니다.
필수로 사용해야하는 요소는 아니므로 본인의 코딩 취향이나 상황에 따라 사용하면 될 것 같습니다.
'안드로이드 > 코드' 카테고리의 다른 글
Android Compose MotionLayout 2 (0) | 2022.11.03 |
---|---|
Compose MotionLayout (0) | 2022.11.02 |
Compose Naver Map (1) | 2022.10.29 |
Compose GoogleMap (0) | 2022.10.27 |
Compose LaunchedEffect (0) | 2022.10.27 |
- Total
- Today
- Yesterday
- WorkManager
- 웹뷰
- WebView
- LazyColumn
- Compose 네이버 지도
- Compose Naver Map
- Compose BottomSheetDialog
- Duplicate class found error
- Row
- 안드로이드
- Pokedex
- Retrofit
- Duplicate class fond 에러
- Android Compose
- Kotlin
- 안드로이드 구글 지도
- Compose ModalBottomSheetLayout
- compose
- Compose QRCode Scanner
- Worker
- Compose BottomSheet
- Compose ConstraintLayout
- Compose BottomSheetScaffold
- column
- Compose MotionLayout
- 포켓몬 도감
- Android
- Fast api
- Gradient
- Compose 네이버 지도 api
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |