티스토리 뷰
MotionLayout은 이전 포스팅에서 다루었던 ConstraintLayout을 추가하였다면 별도로 설치하실 필요는 없습니다.
1) 기본 사용 방법
@OptIn(ExperimentalMotionApi::class)
@Composable
fun MotionLayoutTest() {
var state by remember {
mutableStateOf(false)
}
val progress by animateFloatAsState(
targetValue = if (state) 1f else 0f,
animationSpec = tween(500)
)
MotionLayout(
start = startConstraintSet(),
end = endConstraintSet(),
progress = progress
) {
Box(
modifier = Modifier
.layoutId("box")
.size(50.dp)
.background(Color(0xFFFF9E80))
)
Button(
onClick = { state = !state },
modifier = Modifier.layoutId("button")
) {
Text(text = if (state) "초기화" else "시작")
}
}
}
private fun startConstraintSet(): ConstraintSet = ConstraintSet(
"""
{
box: {
top: ['parent', 'top', 30],
bottom: ['parent', 'bottom'],
start: ['parent' , 'start', 20],
},
button: {
width: "parent",
start: ['parent', 'start', 20],
end: ['parent', 'end', 20],
bottom: ['parent', 'bottom', 30]
}
}
"""
)
private fun endConstraintSet(): ConstraintSet = ConstraintSet(
"""
{
box: {
top: ['parent', 'top', 30],
bottom: ['parent', 'bottom'],
end: ['parent' , 'end', 20],
},
button: {
width: "parent",
start: ['parent', 'start', 20],
end: ['parent', 'end', 20],
bottom: ['parent', 'bottom', 30]
}
}
"""
)
MotionLayout()에 start와 end를 ConstraintSet을 통해 값을 지정하면 모션을 사용할 수 있습니다.
이전 ConstraintLayout 포스팅에서 사용했던 것 처럼 사용해도 작동은 하나 몇 속성을 제외하고는 적용하는 방법을 찾지 못했습니다.
ConstraintSet을 중괄호가 아닌 소괄호로 하면 JSON형식으로 넣을 수 있습니다.
box: {
top: ['parent', 'top', 30],
bottom: ['parent', 'bottom'],
start: ['parent' , 'start', 20],
}
이 코드로 예시를 들면
Modifier.layoutId가 box인 Composable의 top이 부모의 탑에서 30Dp만큼 떨어지게 만들어 줍니다. (bottom과 start 동일하게 속성에 맞게 적용)
var state by remember {
mutableStateOf(false)
}
val progress by animateFloatAsState(
targetValue = if (state) 1f else 0f,
animationSpec = tween(500)
)
MotionLayout(
start = startConstraintSet(),
end = endConstraintSet(),
progress = progress
)
MotionLayout은 시작과 끝을 따로 정의하여 progress의 진행에 따라 모션이 동작하게 됩니다.
progress는 0~1의 값의 사용이 기본입니다.
해당 예제에서는 버튼을 클릭하여 state의 값에 변화를 주어 모션을 동작하게 하였습니다.
2) MotionSence
MotionLayout(
motionScene = myMotionScene(),
progress = progress
)
@Composable
private fun myMotionScene() = MotionScene(
"""
{
ConstraintSets: {
start: {
box: {
top: ['parent', 'top', 30],
bottom: ['parent', 'bottom'],
start: ['parent' , 'start', 20],
custom: {
background: "#84FFFF"
}
},
button: {
width: "parent",
start: ['parent', 'start', 20],
end: ['parent', 'end', 20],
bottom: ['parent', 'bottom', 30]
}
},
end: {
box: {
top: ['parent', 'top', 30],
bottom: ['parent', 'bottom'],
end: ['parent' , 'end', 20],
custom: {
background: "#FF9E80"
}
},
button: {
width: "parent",
start: ['parent', 'start', 20],
end: ['parent', 'end', 20],
bottom: ['parent', 'bottom', 30]
}
}
}
}
"""
MotionScene는 위에서 사용한 start와 end가 결합된 형태입니다.
해당 부분의 코드가 “””에 감싸져 있고 들였기 등의 불편한 점이 있어서 파일로 따로 빼서 사용도 가능합니다.
raw에 my_motion이라는 json5파일을 생성해 줍니다.
그리고 위에 작성한 코드를 저장해 줍니다.
val context = LocalContext.current
val motionSceneContent = remember {
context.resources
.openRawResource(R.raw.my_motion)
.readBytes()
.decodeToString()
}
MotionLayout(
motionScene = MotionScene(motionSceneContent),
progress = progress
)
그 후 위의 방법을 이용해서 모션 적용을 하실 수 있습니다.
3) 색상 변경
색상의 변경의 경우 기본 속성에서는 제공하지 않습니다.
이러한 경우에는 custom을 이용하면 됩니다.
box: {
top: ['parent', 'top', 30],
bottom: ['parent', 'bottom'],
start: ['parent' , 'start', 20],
custom: {
background: "#84FFFF"
}
}
코드가 길어져서 일부만 가져왔습니다. start와 end의 색상은 다르게 설정하였습니다.
custom에 원하는 속성의 키값을 지정합니다.
그다음 레이아웃 영역에서는 다음과 같이 설정합니다.
val boxProperties = motionProperties(id = "box")
Box(
modifier = Modifier
.layoutId("box")
.size(50.dp)
.background(boxProperties.value.color("background"))
)
정의한 아이디에 해당하는 속성들을 motionProperties를 통해 가져올 수 있고 위에서 지정한 키값을 통해 원하는 값을 가져올 수 있습니다.
가져올 수 있는 단위로는 Color, Dp, int, float, String, textUnit이 있습니다.
4) Transitions
{
ConstraintSets: {
...
}
Transitions: {
default: {
from: 'start',
to: 'end',
KeyFrames: {
KeyAttributes: [
{
target: ['box'],
frames: [0, 50, 100],
translationY: [0, -200, 0]
}
]
}
}
},
}
Transitions은 위에서 만든 동작에서 전환 효과를 추가합니다.
위의 예시에서는 frames은 0~100 범위 안으로 프레임으로 나눈 뒤
start에서 end로 애니메이션이 진행될 때 중간에 설정한 프레임(50)에 설정한 동작(translationY>-200)의 전환 효과를 추가하는 작업입니다.
'안드로이드 > 코드' 카테고리의 다른 글
Compose QR코드 스캐너 (2) | 2022.11.04 |
---|---|
Android Compose MotionLayout 2 (0) | 2022.11.03 |
Compose ConstraintLayout (0) | 2022.11.02 |
Compose Naver Map (1) | 2022.10.29 |
Compose GoogleMap (0) | 2022.10.27 |
- Total
- Today
- Yesterday
- Kotlin
- Compose Naver Map
- Gradient
- Android
- Compose 네이버 지도
- WorkManager
- compose
- Pokedex
- Compose BottomSheet
- Row
- Compose QRCode Scanner
- Retrofit
- Duplicate class fond 에러
- 웹뷰
- LazyColumn
- WebView
- Duplicate class found error
- Compose BottomSheetScaffold
- column
- Compose ConstraintLayout
- 포켓몬 도감
- Compose 네이버 지도 api
- Compose BottomSheetDialog
- 안드로이드 구글 지도
- Compose ModalBottomSheetLayout
- Android Compose
- Worker
- 안드로이드
- Fast api
- Compose MotionLayout
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
29 | 30 | 31 |